/* Copyright (C) 2002-2005 SKYRIX Software AG This file is part of SOPE. SOPE is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SOPE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "SoClassSecurityInfo.h" #include "SoClass.h" #include "common.h" @implementation SoClassSecurityInfo - (id)initWithSoClass:(SoClass *)_class { if ((self = [self init])) { self->className = [[_class className] copy]; } return self; } - (void)dealloc { [self->defaultAccess release]; [self->publicNames release]; [self->privateNames release]; [self->nameToPerm release]; [self->defRoles release]; [self->objectPermission release]; [self->className release]; [super dealloc]; } /* attribute security */ - (void)_logPermAlreadySetForName:(NSString *)_name { [self warnWithFormat: @"tried to declare permission for attribute '%@' twice!", _name]; } - (void)setDefaultAccess:(NSString *)_access { if (self->defaultAccess) [self _logPermAlreadySetForName:@""]; else { self->defaultAccess = [_access isNotNull] ? [_access copy] : nil; [self debugWithFormat:@"set default access: '%@'", self->defaultAccess]; } } - (NSString *)defaultAccess { return self->defaultAccess; } - (BOOL)hasDefaultAccessDeclaration { return [self->defaultAccess length] > 0 ? YES : NO; } - (void)declarePublic:(NSString *)_firstName, ... { va_list va; NSString *aname; if (self->publicNames == nil) self->publicNames = [[NSMutableSet alloc] init]; va_start(va, _firstName); for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { if ([self->publicNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->privateNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->nameToPerm objectForKey:aname]) [self _logPermAlreadySetForName:aname]; else { [self->publicNames addObject:aname]; [self debugWithFormat:@"set key public: '%@'", aname]; } } va_end(va); } - (void)declarePrivate:(NSString *)_firstName, ... { va_list va; NSString *aname; if (self->privateNames == nil) self->privateNames = [[NSMutableSet alloc] init]; va_start(va, _firstName); for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { if ([self->publicNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->privateNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->nameToPerm objectForKey:aname]) [self _logPermAlreadySetForName:aname]; else { [self->privateNames addObject:aname]; [self debugWithFormat:@"set key private: '%@'", aname]; } } va_end(va); } - (void)declareProtected:(NSString *)_perm:(NSString *)_firstName, ... { va_list va; NSString *aname; _perm = [_perm lowercaseString]; if (self->nameToPerm == nil) self->nameToPerm = [[NSMutableDictionary alloc] initWithCapacity:16]; va_start(va, _firstName); for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { if ([self->publicNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->privateNames containsObject:aname]) [self _logPermAlreadySetForName:aname]; else if ([self->nameToPerm objectForKey:aname]) [self _logPermAlreadySetForName:aname]; else { [self->nameToPerm setObject:_perm forKey:aname]; [self debugWithFormat:@"protect key by '%@': '%@'", _perm, aname]; } } va_end(va); } - (BOOL)hasProtectionsForKey:(NSString *)_key { if (_key == nil) return NO; if ([self->publicNames containsObject:_key]) return YES; if ([self->privateNames containsObject:_key]) return YES; if ([self->nameToPerm objectForKey:_key]) return YES; return NO; } - (BOOL)isKeyPrivate:(NSString *)_key { return [self->privateNames containsObject:_key]; } - (BOOL)isKeyPublic:(NSString *)_key { return [self->publicNames containsObject:_key]; } - (NSString *)permissionRequiredForKey:(NSString *)_key { return [self->nameToPerm objectForKey:_key]; } /* object security */ - (void)_logObjPermAlreadySet { [self warnWithFormat:@"tried to declare object permission twice! " @"(perm=%@,private=%s,public=%s)", self->objectPermission, self->isObjectPrivate?"yes":"no", self->isObjectPublic?"yes":"no"]; } - (BOOL)hasObjectProtections { if (self->objectPermission) return YES; if (self->isObjectPrivate) return YES; if (self->isObjectPublic) return YES; return NO; } - (BOOL)isObjectPublic { return self->isObjectPublic; } - (BOOL)isObjectPrivate { return self->isObjectPrivate; } - (NSString *)permissionRequiredForObject { return self->objectPermission; } - (void)declareObjectPublic { if ([self->objectPermission isNotNull] || self->isObjectPrivate) [self _logObjPermAlreadySet]; else { [self debugWithFormat:@"declared object public"]; self->isObjectPublic = YES; } } - (void)declareObjectPrivate { if ([self->objectPermission isNotNull] || self->isObjectPublic) [self _logObjPermAlreadySet]; else { [self debugWithFormat:@"declared object private"]; self->isObjectPrivate = YES; } } - (void)declareObjectProtected:(NSString *)_perm { _perm = [_perm isNotNull] ? [_perm lowercaseString] : (NSString *)nil; if ([_perm length] == 0) { [self logWithFormat:@"tried to declare empty permission !", _perm]; return; } if (self->isObjectPrivate || self->isObjectPublic || (self->objectPermission != nil)) { [self _logObjPermAlreadySet]; } else { [self debugWithFormat:@"declared object protected by: %@", _perm]; self->objectPermission = [_perm copy]; } } /* default role mappings */ - (BOOL)hasDefaultRoleForPermission:(NSString *)_p { if (_p == nil) return NO; _p = [_p lowercaseString]; return [self->defRoles objectForKey:_p] == nil ? NO : YES; } - (void)declareRole:(NSString *)_role asDefaultForPermission:(NSString *)_per{ id tmp; _per = [_per isNotNull] ? [_per lowercaseString] : (NSString *)nil; if (self->defRoles == nil) self->defRoles = [[NSMutableDictionary alloc] initWithCapacity:8]; if ((tmp = [self->defRoles objectForKey:_per])) { [self warnWithFormat:@"tried to set default role of '%@' twice!" @" (set to %@)", _per, tmp]; return; } tmp = [_role isNotNull] ? [NSArray arrayWithObject:_role] : [NSArray array]; [self->defRoles setObject:tmp forKey:_per]; } - (void)declareRole:(NSString *)_role asDefaultForPermissions:(NSString *)_p,... { va_list va; NSString *aperm; va_start(va, _p); for (aperm = _p; aperm != nil; aperm = va_arg(va, id)) { [self declareRole:_role asDefaultForPermission:aperm]; } va_end(va); } - (void)declareRoles:(NSArray *)_roles asDefaultForPermission:(NSString *)_p { id tmp; _p = [_p isNotNull] ? [_p lowercaseString] : (NSString *)nil; if (self->defRoles == nil) self->defRoles = [[NSMutableDictionary alloc] initWithCapacity:8]; if ((tmp = [self->defRoles objectForKey:_p])) { [self warnWithFormat:@"tried to set default role of '%@' twice!" @" (set to %@)", _p, tmp]; return; } tmp = [_roles isNotNull] ? _roles : (NSArray *)[NSArray array]; [self->defRoles setObject:tmp forKey:_p]; } - (NSArray *)defaultViewRoles { static NSArray *defViewRoles = nil; if (defViewRoles == nil) { defViewRoles = [[NSArray alloc] initWithObjects: @"Anonymous", @"Manager", nil]; } return defViewRoles; } - (NSArray *)defaultContentsRoles { static NSArray *defContentRoles = nil; if (defContentRoles == nil) { defContentRoles = [[NSArray alloc] initWithObjects: @"Anonymous", @"Manager", nil]; } return defContentRoles; } - (NSArray *)defaultRoles { static NSArray *defRolesA = nil; if (defRolesA == nil) defRolesA = [[NSArray alloc] initWithObjects:@"Manager", nil]; return defRolesA; } - (NSArray *)defaultRolesForPermission:(NSString *)_p { NSArray *roles; _p = [_p lowercaseString]; if ((roles = [self->defRoles objectForKey:_p])) ; else if ([_p isEqualToString:@"view"]) roles = [self defaultViewRoles]; else if ([_p isEqualToString:@"access contents information"]) roles = [self defaultContentsRoles]; else roles = [self defaultRoles]; return roles; } @end /* SoClassSecurityInfo */ @implementation SoClassSecurityInfo(Logging) - (NSString *)loggingPrefix { return [self->className length] > 0 ? [NSString stringWithFormat:@"[so-secinfo %@]", self->className] : [NSString stringWithFormat:@"[so-secinfo 0x%p]", self]; } - (BOOL)isDebuggingEnabled { static int debugOn = -1; if (debugOn == -1) { debugOn = [[NSUserDefaults standardUserDefaults] boolForKey:@"SoLogSecurityDeclarations"] ? 1 : 0; } return debugOn ? YES : NO; } @end /* SoClassSecurityInfo(Logging) */