Session.m


max21 Unternehmensgruppe
#import "Aprica.h"
//	Aprica2
//	copyright Pirmin Braun 1997-2007 - pirmin@pirmin.de
//	all Rights reserved;
@implementation Session
ACCESSClassm(ueo, setUeo, PBEO)
ACCESSm(userName,setUserName)
ACCESSm(lastContextID,setLastContextID);
ACCESSClassm(modulToClose, setModulToClose, PBWOEditor)
ACCESSClassm(nextModul, setNextModul, PBWOEditor)
ACCESSm(confirmString,setConfirmString)
ACCESSm(confirmBack,setConfirmBack)
ACCESSm(confirmContinue,setConfirmContinue)
ACCESSm(cs_v,setCs_v);
ACCESSClassm(cs_a, setCs_a, NSArray)
ACCESSClassm(cs_datasource, setCs_datasource, PBWOEditor)
ACCESSClassm(cs_p_parmDict, setCs_p_parmDict, NSMutableDictionary)
ACCESSClassm(cs_stack, setCs_stack, NSMutableArray)
ACCESSClassm(cs_varDictStack, setCs_varDictStack, NSMutableArray)
ACCESSClassm(cs_foreachStack, setCs_foreachStack, NSMutableArray)
ACCESSClassm(cs_varDict, setCs_varDict, NSMutableDictionary)
ACCESSClassm(cs_localVarDict, setCs_localVarDict, NSMutableDictionary)
ACCESSm(cs_lookupName,setCs_lookupName);
ACCESSm(_rv,set_rv)
ACCESSm(lastLogin,setLastLogin)
ACCESSm(use_lif_from,setUse_lif_from)
- (BOOL)dialogMode;{return dialogMode;}
- (void)setDialogMode:(BOOL)yn;{dialogMode = yn;}
- (BOOL)dialogSubMode0; {return (dialogSubMode==0);}
- (BOOL)dialogSubMode1; {return (dialogSubMode==1);}
- (BOOL)mayConfig;{ return (!use_lif_from);}
- (int)dialogSubMode; {return dialogSubMode;}
- (void)setDialogSubMode:(int)i; { dialogSubMode=i;}
- (int)cs_i; {return cs_i;}
- (void)setCs_i:(int)i;{cs_i = i;}
- (int)cs_j; {return cs_j;}
- (void)setCs_j:(int)i;{cs_j = i;}
- (int)cs_stc; {return cs_stc;}
- (void)setCs_stc:(int)i;{cs_stc = i;}
- (BOOL)cs_debug;{return cs_debug;}
- (void)setCs_debug:(BOOL)yn;{cs_debug = yn;}
- init;
{
    int to;
    if(!(self = [super init]))return nil;
#warning configurierbar machen
//    [self setStoresIDsInCookies:YES];
    [self setUserName:nil];
    [self setUeo:nil];
    scriptStackDepth = 0;
    to = [[[_APP configDict]ofk:@"sessiontimeout"]intValue];
    if(!to)to=600; // 10 min default
    [self setTimeOut:to];
    MD(instanceDict);
    MD(dead);
    MA(launchedModuls);
    MD(bundlesByName);
    MD(bundlesByKuerzel);
    MD(parmDict);
    MD(moduleSoseq);
    MA(errors);
    oldContextRequested = NO;
    [self setLastContextID:nil];
    dialogMode = NO;
    dialogSubMode = 0;
    LOGS((@"new session created..."));
//    PRINTCURRENTSTACK;
    return self;
}
- (void)loadSoseq;
{
// den Inhalt aus ueo.soseq ins moduleSoseq Dictionary
    NSArray *a = [[ueo vfk:@"soseq"]componentsSeparatedByString:@"\n"];
    int i,j;
    [moduleSoseq removeAllObjects];
    for(i=0,j=[a count];i<j;i++){
        NSArray *a1 = [[a oai:i]componentsSeparatedByString:@"="];
	if([a1 count]==2){
            [moduleSoseq setObject:[a1 oai:1] forKey:[a1 oai:0]];
        }
    }
}
- (void)saveSoseq;
{
// den Inhalt aus moduleSoseq Dictionary ins ueo.soseq und dieses updaten
    LMA;
    NSArray *a1 = [moduleSoseq allKeys];
    NSArray *a2 = [moduleSoseq allObjects];
    int i,j;
    for(i=0,j=[a1 count];i<j;i++){
        [lma addObject:[NSSWF @"%@=%@",[a1 oai:i],[a2 oai:i]]];
    }
    [ueo tvfk([lma componentsJoinedByString:@"\n"],@"soseq")];
    UPDAT(ueo);
}
- initWithUserEO:(PBEO *)u;
{
    int to;
    if(!u)return nil;
    [self setUeo:u];
    [self setUserName:[ueo primaryKey]];
//steuert, ob gui oder dbName angezeigt wird; normalerweise guiname; f. Reports designen aber auch dbName interessant;
    isRoot = [[ueo vfk:@"sonderberechtigung"] iE:@"root"];
    isGruppe0 = [[ueo vfk:@"gruppe0"] iE:@"J"];
    isGruppe1 = [[ueo vfk:@"gruppe1"] iE:@"J"];
    isGruppe2 = [[ueo vfk:@"gruppe2"] iE:@"J"];
    isGruppe3 = [[ueo vfk:@"gruppe3"] iE:@"J"];
    isGruppe4 = [[ueo vfk:@"gruppe4"] iE:@"J"];
    isGruppe5 = [[ueo vfk:@"gruppe5"] iE:@"J"];
    isGruppe6 = [[ueo vfk:@"gruppe6"] iE:@"J"];
    isGruppe7 = [[ueo vfk:@"gruppe7"] iE:@"J"];
    isGruppe8 = [[ueo vfk:@"gruppe8"] iE:@"J"];
    isGruppe9 = [[ueo vfk:@"gruppe9"] iE:@"J"];
    [self setUse_lif_from:[ueo vfk:@"use_lif_from"]];
    if(!FILLED(use_lif_from))[self setUse_lif_from:nil];
    readOnly = [[ueo vfk:@"sonderberechtigung"] iE:@"gdpdu"] || [[ueo vfk:@"sonderberechtigung"] iE:@"rop"];
    lang = [[ueo vfk:@"lang"] intValue]; //lang haengt am usereo
    lang_script = lang;
    to = [[ueo vfk:@"sessiontimeout"] intValue];
    if (to){
        if(to < 600)to=600;
        [self setTimeOut: to];
    }
    [self registerUserBundles]; //User-Berechtigungen muessen bekannt sein dafuer
    [self loadSoseq];
    [parmDict setObject:[_APP browserTitle] forKey:@"browserTitle"]; // kann dann ueberschrieben werden von didLogin
    [_APP executeScriptNamed:@"_Application/didLogin"  datasource:(PBWOEditor *)self parmDict:parmDict];
    return self;
}
- (NSMutableDictionary *)parmDict;
{
    return parmDict;
}
- (NSMutableDictionary *)moduleSoseq;
{
    return moduleSoseq;
}
- (NSDictionary *)gatherBerechtForUser:(PBEO *)u;
{
    int i,ii,jj;
    LMD;
    NSString *gs;
    if((gs = [[u values]ofk:@"gruppenstring"])){
// neues verfahren
        NSArray *bs = [_APP availableBundles];
        PBWOBundle *b;
        BOOL gx[10];
// fuer nix berechtigt
        if([gs iE:@"----------"])return lmd;
        for(i=0;i<ANZ_GRUPPEN;i++){
            gx[i]=[[[gs charAt:i]lowercaseString]iE:@"x"];
        }
        for(ii=0,jj=[bs count];ii<jj;ii++){
            b = [bs oai:ii];
            gs = [b gruppenstring];
            if([gs iE:@"----------"])continue;
            for(i=0;i<ANZ_GRUPPEN;i++){
                if(gx[i] && [[[gs charAt:i]lowercaseString]iE:@"x"]){
                    [lmd setSecureObject:@"x" forKey:[b name]];
                    break;
                }
            }
        }
    }
    return lmd;
}
- (Application *)application;
{
    return _APP;
}
- (BOOL)isRoot;
{
    return isRoot || isTemporaryRoot;
}
- (BOOL)isTemporaryRoot;
{
    return isTemporaryRoot;
}
- (void)setIsTemporaryRoot:(BOOL)yn;
{
    isTemporaryRoot = yn;
}
- (BOOL)readOnly;
{
    return readOnly;
}
- (int)scriptStackDepth;{return scriptStackDepth;}
- (void)inc_scriptStackDepth;{scriptStackDepth++;}
- (void)dec_scriptStackDepth;{if(scriptStackDepth > 0)scriptStackDepth--;}
- (WOElement *)invokeActionForRequest:(WORequest *)aRequest inContext:(WOContext *)aContext;
{
    if(oldContextRequested)return nil;
    return [super invokeActionForRequest:aRequest inContext:aContext];
}
/*f. debugging
- retain;
{
    PRINTCURRENTSTACK;
    return [super retain];
}
*/
- (void)dealloc;
{
    //wird autom. aufgerufen, wenn timeout
    [_APP executeScriptNamed:@"_Application/didLogout"  datasource:(PBWOEditor *)self parmDict:parmDict];
    [_APP sessionEnded:[self sessionID]];
    if ([_APP currentSession] == self) [_APP setCurrentSession: nil];
    [modulToClose release];
    [nextModul release];
    [bundlesByName release];
    [bundlesByKuerzel release];
    [use_lif_from release];
    [dead release];
    [errors release];
    [instanceDict release];
    [lastContextID release];
    [lastLogin release];
    [launchedModuls release];
    [ueo release];
    [userName release];
    [parmDict release];
    [moduleSoseq release];
    [_rv release];
    [confirmString release];
    [confirmBack release];
    [confirmContinue release];
    [cs_v release];
    [cs_a release];
    [cs_datasource release];
    [cs_p_parmDict release];
    [cs_stack release];
    [cs_varDictStack release];
    [cs_foreachStack release];
    [cs_varDict release];
    [cs_localVarDict release];
    [cs_lookupName release];
    [super dealloc];
}
- (void)awake
{
//    LOGS(([NSSWF @"%@ awake",[self sessionID]]));
    [_APP setCurrentSession:self];
}
- (void)sleep;
{
    [errors removeAllObjects];
    [self setConfirmString:nil];
    [self setModulToClose:nil]; // released das dann
    [_APP setCurrentSession:nil];
    [super sleep];
}
- instanceForBundle:(PBWOBundle *)aBundle
{
    if(!aBundle){
        LOGS(@"kein bundle uebergeben");
        // PRINTCURRENTSTACK;
        return nil;
    }
    return [self instanceForBundleNamed:[aBundle name]];
}
- instanceForBundleNamed:(NSString *)bundleName;
{
// neuer Standard: Module heissen so wie die Tabelle, die sie verwalten
    id e = [self instanceForBundleNamed:bundleName fromApp:NO];
    if(e)return e;
// alte Namenskonvention
    e = [self instanceForBundleNamed:[bundleName capitalizedString] fromApp:NO];
    if(e)return e;
    return [self instanceForBundleNamed:[[bundleName capitalizedString]stringByAppendingString:@"E"] fromApp:NO];
}
- instanceForAppBundleNamed:(NSString *)bundleName;
{
    return [self instanceForBundleNamed:bundleName fromApp:YES];
}
- instanceForBundleNamed:(NSString *)bundleName fromApp:(BOOL)fromApp;
{
    return [self instanceForBundleNamed:bundleName fromApp:fromApp additional:NO];
}
- instanceForBundleNamed:(NSString *)bundleName fromApp:(BOOL)fromApp additional:(BOOL)additional;
{
    PBWOBundle *b;
    PBWOEditor *anInstance = nil;
    BOOL rc = YES;
    if(!bundleName){
        LOGS(@"kein bundleName uebergeben");
        // PRINTCURRENTSTACK;
        return nil;
    }
    if([dead ofk:bundleName]){
        LOGS(@"bundle schonmal gestorben");
        return nil; // schonmal fehlgeschlagen
    }
    if(additional || !(anInstance = [instanceDict ofk:bundleName])){
        // nur wenn user berechtigt f. bundle:
        if(fromApp){
            b=[_APP bundleWithName:bundleName];
        }else{
            b=[self bundleWithName:bundleName];
        }
        if(b){
            if([_APP logActions]){
                LOGS(([NSSWF @"%@ %@ %@",bundleName,[b principalClassName],CURRENTUSER]));
            }
            NS_DURING;
            anInstance = (PBWOEditor *)[_APP pageWithName:[b principalClassName] inContext:[self context]];
            if(anInstance){
                if([_APP logActions])LOGS(@"got Instance");
                [anInstance setUpWithBundle:b];
                [instanceDict setSecureObject:anInstance forKey:bundleName];
                if(![b hiddenModul]){
                    [launchedModuls addObject:anInstance];
                }
            }else{
                LOGS(([NSSWF @"pageWithName:%@ failed",bundleName]));
                // PRINTCURRENTSTACK;
                rc = NO;
            }
            NS_HANDLER;
            LOGS_Ex(EON);
            rc=NO;
            NS_ENDHANDLER;
            if(!rc){
                LOGI(([NSSWF TRANSLATION(@"konnte Modul %@ nicht laden. html, wod?"),bundleName]));
                [instanceDict removeObjectForKey:bundleName];
                [dead setSecureObject:bundleName forKey:bundleName];
                return nil;
            }
        }else{
            return nil;
        }
    }
        [anInstance ensureAwakeInContext:[self context]];
        [anInstance callingModul];
        return anInstance;
}
- (NSDictionary *)instanceDict;
{
    return instanceDict;
}
- (NSArray *)launchedModuls;
{
    return (NSArray *)launchedModuls;
}
- (void)appendToResponse:(WOResponse *)aResponse inContext:(WOContext *)aContext;
{
    NSString *si;
    [self setLastContextID:[aContext contextID]];
    [super appendToResponse:aResponse inContext:aContext];
    if((si=[self sessionID])){
        WORequest *aRequest = [aContext request];
        NSString *time = [[NSCalendarDate date] descriptionWithCalendarFormat:@"%H:%M:%S (%d.%m.%Y)"];
        NSString *s1;
        s1 = [NSSWF@"%@ %@ %@ %@",time,[aRequest headerForKey:@"x-webobjects-remote-host"],[aRequest headerForKey:@"x-webobjects-remote-addr"],si];
// hier kann jeder zugriff ueberwacht werden        LOGS(s1);
    }
}
- (NSString *)userLoginName
{
    return userName;
}
- (void)registerUserBundles;
{
// bundlesByName und bundlesByKuerzel  fuellen gemaess den festgestellten Berechtigungen
    NSArray *bs = [_APP availableBundles];
    PBWOBundle *b;
    int i,j;
    NSDictionary *d = [self gatherBerechtForUser:ueo]; // holt berechtigte modulnamen
    [bundlesByName removeAllObjects];
    [bundlesByKuerzel removeAllObjects];
    for(i=0,j=[bs count];i<j;i++){
        NSString *kuerzel;
        b = [bs oai:i];
        //editierberechtigung schliesst sichtbar-berechtigung natuerlich mit ein
	//gruppenberechtigung und Userberechtigung; nur wenn gar nichts, wird modul ausgeblendet
        if([self isRoot])goto takeIt;
        if([d ofk:[b name]])goto takeIt; //namen aller berechtigten
        if([b publicModul])goto takeIt; //public
        continue;
takeIt:
        [bundlesByName sofk(b,[b name])];
        kuerzel = [b kuerzel];
        if(FILLED(kuerzel)){
            [bundlesByKuerzel sofk(b,kuerzel)];
        }
    }
}
- (PBWOEditor *)instanceForKuerzel:(NSString *)kuerzel;
{
    PBWOBundle *b;
    if(!kuerzel)return nil;
    b = [bundlesByKuerzel ofk:kuerzel];
    if(!b)return nil;
    return [self instanceForBundle:b];
}
- (NSArray *)availableBundles;
{
    return [bundlesByName allValues];
}
- (PBWOBundle *)bundleWithName:(NSString *)name
{
    return [bundlesByName ofk:name];
}
- (NSArray *)bundlesForSuchString:(NSString *)s;
{
    NSArray *a = [self availableBundles];
    int i,j=[a count];
    LMA;
    PBWOBundle *b;
    NSString *ss=[s simplyfiedString],*mc;
    if(!FILLED(ss))return (NSArray *)lma;
    for(i=0;i<j;i++){
        b = [a oai:i];
        mc = [b matchCode];
        if(!FILLED(mc))continue;
        if(!([mc rangeOfString:ss].length))continue;
        if([b hiddenModul])continue;
        [lma addObject:b];
        if([lma count]>20)return lma; //max menge;
    }
    return (NSArray *)lma;
}
- (int)preferredLangForISOLanguages:(NSArray *)a;
{
    static NSDictionary *langmap = nil;
    NSString *s = nil;
    unsigned i,j;
    if (!langmap) langmap = [[@"{ de = 0; en = 1; pl = 2; zh = 3; ru = 4; it = 5; fr = 6; cs = 7; es = 8; hu = 9; }" propertyList] retain];
    for (i=0,j=[a count];i<j;i++) {
        if ((s=[langmap ofk: [[[a oai:i] secureSubstringToIndex:2] lowercaseString]])) break;
    }
    return [s intValue];
}
- (int)lang;{return lang;}
- (void)setLang:(int)i;
{
    lang = i;
}
- (int)lang_script;{return lang_script;}
- (void)setLang_script:(int)i;
{
    lang_script = i;
}
- (NSString *)transFor:(NSString *)s;
{
//liefert translation f. sprache des users
    if(lang == 0)return s;
    return [self transFor:s lang:lang];
}
- (NSString *)transScriptFor:(NSString *)s;
{
//liefert translation f. sprache des script
    if(lang_script == 0)return s;
    return [self transFor:s lang:lang_script];
}
- (NSString *)transFor:(NSString *)ps lang:(int)lng;
{
//liefert translation f. sprache lng
// neue fehlende in translationsm speichern;
    NSString *s,*s1;
    PBEO *eo;
    if(lng == 0)return ps;
    s = [ps stringWithoutLeadingWhiteSpace];
    s = [s stringWithoutTrailingWhiteSpace]; // Bug in MySQL:Trailing white space geht beim speichern verloren
    if(!FILLED(s)) return ps;
    s1 = [[_APP transDict] ofk:s];
    if(!s1){
        NSString *sql,*result;
        [[_APP transDict] setObject:EON forKey:s]; //gleich aufnehmen
        sql = [NSSWF @"select text0 from translationsm where text0 = BINARY '%@'",s];
        result = singleValueSQL(sql);
        if(!FILLED(result)){
//           LOGS(([NSSWF @">%@<  >%@<  >%@<",ps,s,result]));
            eo = NEW_EO(@"translationsm");
            [eo tvfk(s,@"text0")];
            INSRT(eo);
        }
        return ps;
    }
    if(FILLED(s1))return s1;
    return ps;
}
- (void)takeValuesFromRequest:(WORequest *)aRequest inContext:(WOContext *)aContext;
{
    if(oldContextRequested)return; //wg. F5-Feldloeschungen und vor/zurueck
    [super takeValuesFromRequest:aRequest inContext:aContext]; 
}
- (WOComponent *)restorePageForContextID:(NSString *)contextID;
{
    // LOGS(([NSSWF @"contextID:%@ lastContextID:%@ ",contextID,lastContextID]));
    // return nil; //erzeugt handlePageRestorationErrorInContext
    // LOGS([[self valueForKey:@"_contextRecords"]description]);
    if(lastContextID && ![lastContextID iE:contextID]){
        oldContextRequested = YES; // take values und invokeAction abgeschaltet
    }else{
        oldContextRequested = NO;
    }
    return [super restorePageForContextID:lastContextID]; //immer die zuletzt gesendete Seite; F5 und backtracking verhindern
}
//aus pbwobrowser:
- (void)clearErrors;
{
    [errors removeAllObjects];
}
- (NSString *)ip_adresse;
{
    if([_APP isBatch]) return @"127.0.0.1";
#ifdef GNUSTEP
    return [[[self context] request] headerForKey:@"x-gsweb-remote-addr"];
#else
    return [[[self context] request] headerForKey:@"x-webobjects-remote-addr"];
#endif
}
- (NSString *)serverName;
{
    NSString *ip_adresse = [self ip_adresse];
    NSString *subn = [[_APP configDict]ofk:@"internsubnet"];
//    LOGS(([NSSWF @"ipadr:%@ subnet:%@",ip_adresse,subn]));
    if([ip_adresse iE:@"127.0.0.1"] || [ip_adresse hasSecurePrefix:subn]){ //nicht ganz korrekt; bit-mask waere besser
        NSString *sn = [[_APP configDict]ofk:@"servername"];
        if(FILLED(sn))return sn; //in configDict festlegen, anstatt httpd.conf zu editieren
    }else{
        NSString *snx = [[_APP configDict]ofk:@"servernamex"]; //kommt von extern
        if(FILLED(snx))return snx; //in configDict festlegen, anstatt httpd.conf zu editieren
    }
    return [[[self context] request]headerForKey:@"x-webobjects-server-name"]; //aus dem apache httpd.conf
}
- (NSMutableArray *)errors;
{
    return errors;
}
- (void)addMsg:(NSString *)s;
{
    if(!s)return;
    LOGS(s); // in ereignisanzeige
    if([errors count]>10)return;
    if([errors count]==10){
        [errors addObject:TRANSLATION(@"... (weitere Meldungen unterdrueckt)")];
        return;
    }
    if(NSNotFound == [errors indexOfObject:s]) [errors addObject:s];
}
- (void)removeFromPersonal:(PBWOEditor *)pbv;
{
    LMA;
    if(!pbv)return;
    [lma addObjectsFromArray:[[ueo vfk:@"prestartingmod"]componentsSeparatedByString:@","]];
    [lma removeObject:[pbv name]];
    [ueo tvfk([lma componentsJoinedByString:@","],@"prestartingmod")];
    UPDAT(ueo);
}
- (void)addToPersonal:(PBWOEditor *)pbv;
{
    LMA;
    if(!pbv)return;
    if([[pbv bundle] hiddenModul])return;
    [lma addObjectsFromArray:[[ueo vfk:@"prestartingmod"]componentsSeparatedByString:@","]];
    if([lma count]>MAXHISTENTRIES)[lma secureRemoveLastObject];
    [lma insertObject:[pbv name] atIndex:0];
    [ueo tvfk([lma componentsJoinedByString:@","],@"prestartingmod")];
    UPDAT(ueo);
}
- (Session *)session;
{
// fuer scripting %session
    return self;
}
- (NSStringEncoding)preferredEncoding;
{
    //TODO: Encoding sollte wahrscheinlich entweder in der APP oder beim USER
    //      definiert werden.  Zunaechst unterscheiden wir nur UTF8/ISOLatin1
    return ([_APP utf8])?NSUTF8StringEncoding:NSWindowsCP1252StringEncoding;
}
@end
Foto