Monotone-Parent: 27aea167b22f4039327617a920f320773435357a

Monotone-Revision: 47696beae1f727f105c84083c575020ef044e2b6

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-11-26T20:41:59
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2007-11-26 20:41:59 +00:00
parent 1bf613706d
commit 04e82c1971
12 changed files with 252 additions and 77 deletions

View File

@ -1,5 +1,30 @@
2007-11-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/PreferencesUI/UIxPreferences.m ([UIxPreferences -userHasCalendarAccess])
([UIxPreferences -userHasMailAccess]): same as below, for
displaying preference tabs.
* UI/Common/UIxPageFrame.m ([UIxPageFrame
-userHasCalendarAccess]): new accessor for the link banner.
([UIxPageFrame -userHasMailAccess]): same as above.
* SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
-toManyRelationshipKeys]): do not report the path to modules to
which the user has no access. No longer cache this information
statically, the array will be generated at each call.
([SOGoUserFolder -lookupName:_keyinContext:_ctxacquire:_flag]):
ignore the path to modules to which the user has no access.
* SoObjects/SOGo/SOGoUser.m ([SOGoUser -canAccessModule:module]):
new method that returns whether the user has access to the
specified module.
* SoObjects/SOGo/LDAPSource.m ([LDAPSource
-initFromUDSource:udSource]): take a new parameter named
'ModulesContraints' that defines a set of constraints for
accessing specified named modules. This is an optout, meaning the
modules will be present unless a constraint is specified.
* SoObjects/Appointments/SOGoAppointmentFolder.m
([SOGoAppointmentFolder
-roleForComponentsWithAccessClass:accessClassforUser:uid]): cache

View File

@ -44,6 +44,8 @@
NSArray *mailFields;
NSString *bindFields;
NSDictionary *modulesConstraints;
NGLdapConnection *ldapConnection;
NSMutableArray *searchAttributes;
}

View File

@ -170,6 +170,7 @@ static int sizeLimit;
[bindFields release];
[ldapConnection release];
[sourceID release];
[modulesConstraints release];
[super dealloc];
}
@ -189,6 +190,7 @@ static int sizeLimit;
UIDField: [udSource objectForKey: @"UIDFieldName"]
mailFields: [udSource objectForKey: @"MailFieldNames"]
andBindFields: [udSource objectForKey: @"bindFields"]];
ASSIGN (modulesConstraints, [udSource objectForKey: @"ModulesConstraints"]);
return self;
}
@ -351,6 +353,20 @@ static int sizeLimit;
return [EOQualifier qualifierWithQualifierFormat: qs];
}
- (NSArray *) _contraintsFields
{
NSMutableArray *fields;
NSEnumerator *values;
NSDictionary *currentConstraint;
fields = [NSMutableArray array];
values = [[modulesConstraints allValues] objectEnumerator];
while ((currentConstraint = [values nextObject]))
[fields addObjectsFromArray: [currentConstraint allKeys]];
return fields;
}
- (NSArray *) _searchAttributes
{
if (!searchAttributes)
@ -361,6 +377,7 @@ static int sizeLimit;
if (UIDField)
[searchAttributes addObject: UIDField];
[searchAttributes addObjectsFromArray: mailFields];
[searchAttributes addObjectsFromArray: [self _contraintsFields]];
[searchAttributes addObjectsFromArray: commonSearchFields];
}
@ -408,7 +425,8 @@ static int sizeLimit;
emailFields = [mailFields objectEnumerator];
while ((currentFieldName = [emailFields nextObject]))
{
value = [[ldapEntry attributeWithName: currentFieldName] stringValueAtIndex: 0];
value = [[ldapEntry attributeWithName: currentFieldName]
stringValueAtIndex: 0];
if (value)
[emails addObject: value];
}
@ -416,6 +434,38 @@ static int sizeLimit;
[contactEntry setObject: emails forKey: @"c_emails"];
}
- (void) _fillConstraints: (NGLdapEntry *) ldapEntry
forModule: (NSString *) module
intoContactEntry: (NSMutableDictionary *) contactEntry
{
NSDictionary *constraints;
NSEnumerator *matches;
NSString *currentMatch, *currentValue, *ldapValue;
BOOL result;
result = YES;
constraints = [modulesConstraints objectForKey: module];
if (constraints)
{
matches = [[constraints allKeys] objectEnumerator];
currentMatch = [matches nextObject];
while (result && currentMatch)
{
ldapValue = [[ldapEntry attributeWithName: currentMatch]
stringValueAtIndex: 0];
currentValue = [constraints objectForKey: currentMatch];
if ([ldapValue isEqualToString: currentValue])
currentMatch = [matches nextObject];
else
result = NO;
}
}
[contactEntry setObject: [NSNumber numberWithBool: result]
forKey: [NSString stringWithFormat: @"%@Access", module]];
}
- (NSDictionary *) _convertLDAPEntryToContact: (NGLdapEntry *) ldapEntry
{
NSMutableDictionary *contactEntry;
@ -446,6 +496,10 @@ static int sizeLimit;
value = @"";
[contactEntry setObject: value forKey: @"c_cn"];
[self _fillEmailsOfEntry: ldapEntry intoContactEntry: contactEntry];
[self _fillConstraints: ldapEntry forModule: @"Calendar"
intoContactEntry: (NSMutableDictionary *) contactEntry];
[self _fillConstraints: ldapEntry forModule: @"Mail"
intoContactEntry: (NSMutableDictionary *) contactEntry];
return contactEntry;
}

View File

@ -303,11 +303,17 @@ static NSString *defaultMailDomain = nil;
LDAPSource *currentSource;
NSString *cn, *c_uid;
NSArray *c_emails;
BOOL access;
emails = [NSMutableArray array];
cn = nil;
c_uid = nil;
[currentUser setObject: [NSNumber numberWithBool: YES]
forKey: @"CalendarAccess"];
[currentUser setObject: [NSNumber numberWithBool: YES]
forKey: @"MailAccess"];
ldapSources = [sources objectEnumerator];
currentSource = [ldapSources nextObject];
while (currentSource)
@ -322,6 +328,14 @@ static NSString *defaultMailDomain = nil;
c_emails = [userEntry objectForKey: @"c_emails"];
if ([c_emails count])
[emails addObjectsFromArray: c_emails];
access = [[userEntry objectForKey: @"CalendarAccess"] boolValue];
if (!access)
[currentUser setObject: [NSNumber numberWithBool: NO]
forKey: @"CalendarAccess"];
access = [[userEntry objectForKey: @"MailAccess"] boolValue];
if (!access)
[currentUser setObject: [NSNumber numberWithBool: NO]
forKey: @"MailAccess"];
}
currentSource = [ldapSources nextObject];
}

View File

@ -124,6 +124,9 @@ extern NSString *SOGoWeekStartFirstFullWeek;
- (BOOL) isSuperUser;
/* module access */
- (BOOL) canAccessModule: (NSString *) module;
/* folders */
- (SOGoUserFolder *) homeFolderInContext: (id) context;

View File

@ -622,4 +622,15 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
return [superUsernames containsObject: login];
}
/* module access */
- (BOOL) canAccessModule: (NSString *) module
{
NSString *accessValue;
accessValue = [self _fetchFieldForUser:
[NSString stringWithFormat: @"%@Access", module]];
return [accessValue boolValue];
}
@end /* SOGoUser */

View File

@ -24,6 +24,8 @@
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoClassSecurityInfo.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSObject+Logs.h>
#import <Appointments/SOGoAppointmentFolders.h>
@ -64,12 +66,18 @@
- (NSArray *) toManyRelationshipKeys
{
static NSArray *children = nil;
NSMutableArray *children;
SOGoUser *currentUser;
if (!children)
children = [[NSArray alloc] initWithObjects:
@"Calendar", @"Contacts", @"Mail",
@"Preferences", nil];
children = [NSMutableArray arrayWithCapacity: 4];
currentUser = [context activeUser];
if ([currentUser canAccessModule: @"Calendar"])
[children addObject: @"Calendar"];
[children addObject: @"Contacts"];
if ([currentUser canAccessModule: @"Mail"])
[children addObject: @"Mail"];
[children addObject: @"Preferences"];
return children;
}
@ -149,12 +157,15 @@
acquire: (BOOL) _flag
{
id obj;
SOGoUser *currentUser;
/* first check attributes directly bound to the application */
obj = [super lookupName: _key inContext: _ctx acquire: NO];
if (!obj)
{
if ([_key isEqualToString: @"Calendar"])
currentUser = [_ctx activeUser];
if ([_key isEqualToString: @"Calendar"]
&& [currentUser canAccessModule: _key])
obj = [self privateCalendars: @"Calendar" inContext: _ctx];
// if (![_key isEqualToString: @"Calendar"])
// obj = [obj lookupName: [_key pathExtension]
@ -163,7 +174,8 @@
obj = [self privateContacts: _key inContext: _ctx];
// else if ([_key isEqualToString: @"Groups"])
// obj = [self groupsFolder: _key inContext: _ctx];
else if ([_key isEqualToString: @"Mail"])
else if ([_key isEqualToString: @"Mail"]
&& [currentUser canAccessModule: _key])
obj = [self mailAccountsFolder: _key inContext: _ctx];
else if ([_key isEqualToString: @"Preferences"])
obj = [$(@"SOGoPreferencesFolder") objectWithName: _key

View File

@ -345,6 +345,24 @@
&& [user isSuperUser]);
}
- (BOOL) userHasCalendarAccess
{
SOGoUser *user;
user = [context activeUser];
return [user canAccessModule: @"Calendar"];
}
- (BOOL) userHasMailAccess
{
SOGoUser *user;
user = [context activeUser];
return [user canAccessModule: @"Mail"];
}
/* browser/os identification */
- (BOOL) isCompatibleBrowser

View File

@ -483,7 +483,7 @@ static BOOL shouldDisplayPasswordChange = NO;
- (NSString *) itemIdentityText
{
return [item keysWithFormat: @"%{fullName} <%{email}>"];
return [(NSDictionary *) item keysWithFormat: @"%{fullName} <%{email}>"];
}
- (NSMutableDictionary *) defaultIdentity
@ -538,6 +538,16 @@ static BOOL shouldDisplayPasswordChange = NO;
return [[request method] isEqualToString: @"POST"];
}
- (BOOL) userHasCalendarAccess
{
return [user canAccessModule: @"Calendar"];
}
- (BOOL) userHasMailAccess
{
return [user canAccessModule: @"Mail"];
}
- (BOOL) shouldDisplayPasswordChange
{
return shouldDisplayPasswordChange;

View File

@ -15,12 +15,16 @@
<ul>
<li target="generalView"><var:string
label:value="General"/></li>
<li target="calendarOptionsView"><var:string
label:value="Calendar Options"/></li>
<li target="mailOptionsView"><var:string
label:value="Mail Options"/></li>
<li target="identitiesView"><var:string
label:value="Identities"/></li>
<var:if condition="userHasCalendarAccess">
<li target="calendarOptionsView"><var:string
label:value="Calendar Options"/></li>
</var:if>
<var:if condition="userHasMailAccess">
<li target="mailOptionsView"><var:string
label:value="Mail Options"/></li>
<li target="identitiesView"><var:string
label:value="Identities"/></li>
</var:if>
<var:if condition="shouldDisplayPasswordChange">
<li target="passwordView"><var:string label:value="Password"/></li>
</var:if>
@ -45,43 +49,46 @@
/></label>
</div>
</div>
<div id="calendarOptionsView" class="tab">
<label><var:string label:value="Week begins on :"/>
<var:popup list="daysList" item="item"
string="itemWeekStartDay" selection="userWeekStartDay"
/></label><br/>
<label><var:string label:value="Day start time :"/>
<var:popup list="hoursList" item="item"
string="item" selection="userDayStartTime"
/></label>
<label><var:string label:value="Day end time :"/>
<var:popup list="hoursList" item="item"
string="item" selection="userDayEndTime"
/></label><br/>
<label><var:string label:value="First week of year :"/>
<var:popup list="firstWeekList" item="item"
string="itemFirstWeekText" selection="userFirstWeek"
/></label><br/>
<br/>
<label><input class="checkBox"
type="checkbox" var:selection="reminderEnabled"
var:checked="reminderEnabled"/><var:string
label:value="Enable reminders for Calendar items"/></label><br/>
<label><input class="checkBox"
type="checkbox" var:selection="remindWithASound"
var:checked="remindWithASound"/><var:string
label:value="Play a sound when a reminder comes due"/></label><br/>
<label><var:string label:value="Default reminder :"/>
<var:popup list="reminderTimesList" item="item"
string="itemReminderTimeText" selection="userReminderTime"/></label>
</div>
<div id="mailOptionsView" class="tab">
<label><var:string label:value="Check for new mail:"/>
<var:popup list="messageCheckList" item="item"
string="itemMessageCheckText" selection="userMessageCheck"/></label><br/>
<label><var:string label:value="Forward messages:"/>
<var:popup list="messageForwardingList" item="item"
string="itemMessageForwardingText" selection="userMessageForwarding"/></label><br/>
<var:if condition="userHasCalendarAccess">
<div id="calendarOptionsView" class="tab">
<label><var:string label:value="Week begins on :"/>
<var:popup list="daysList" item="item"
string="itemWeekStartDay" selection="userWeekStartDay"
/></label><br/>
<label><var:string label:value="Day start time :"/>
<var:popup list="hoursList" item="item"
string="item" selection="userDayStartTime"
/></label>
<label><var:string label:value="Day end time :"/>
<var:popup list="hoursList" item="item"
string="item" selection="userDayEndTime"
/></label><br/>
<label><var:string label:value="First week of year :"/>
<var:popup list="firstWeekList" item="item"
string="itemFirstWeekText" selection="userFirstWeek"
/></label><br/>
<br/>
<label><input class="checkBox"
type="checkbox" var:selection="reminderEnabled"
var:checked="reminderEnabled"/><var:string
label:value="Enable reminders for Calendar items"/></label><br/>
<label><input class="checkBox"
type="checkbox" var:selection="remindWithASound"
var:checked="remindWithASound"/><var:string
label:value="Play a sound when a reminder comes due"/></label><br/>
<label><var:string label:value="Default reminder :"/>
<var:popup list="reminderTimesList" item="item"
string="itemReminderTimeText" selection="userReminderTime"/></label>
</div>
</var:if>
<var:if condition="userHasMailAccess">
<div id="mailOptionsView" class="tab">
<label><var:string label:value="Check for new mail:"/>
<var:popup list="messageCheckList" item="item"
string="itemMessageCheckText" selection="userMessageCheck"/></label><br/>
<label><var:string label:value="Forward messages:"/>
<var:popup list="messageForwardingList" item="item"
string="itemMessageForwardingText" selection="userMessageForwarding"/></label><br/>
<!-- <label><input
const:name="inTheOffice" type="radio" const:value="YES"
var:selection="inTheOffice"/>
@ -95,16 +102,17 @@
<label><var:string label:value="AutoReply only once to each sender with the following text :"/><br/>
<textarea const:name="autoReplyText" var:value="autoReplyText"/>
</label> -->
</div>
<div id="identitiesView" class="tab">
<!--<var:multiselection const:id="identitiesList" item="item"
</div>
<div id="identitiesView" class="tab">
<!--<var:multiselection const:id="identitiesList" item="item"
list="identitiesList" displayString="itemIdentityText">
</var:multiselection>
<br/>-->
<var:string label:value="Signature:"/><br/>
<textarea const:id="signature" const:name="signature"
var:value="signature"/>
</div>
<br/>-->
<var:string label:value="Signature:"/><br/>
<textarea const:id="signature" const:name="signature"
var:value="signature"/>
</div>
</var:if>
<var:if condition="shouldDisplayPasswordChange">
<div id="passwordView" class="tab">
<label><var:string label:value="New password:"

View File

@ -42,7 +42,8 @@
>
<var:if condition="shortUserNameForDisplay" const:value="anonymous"
const:negate="YES"
><var:if condition="shortUserNameForDisplay" const:value="wrongusernamepassword"
><var:if condition="shortUserNameForDisplay"
const:value="wrongusernamepassword"
const:negate="YES"
><var:if condition="isPopup" const:negate="YES"
><var:if condition="context.isUIxDebugEnabled"
@ -50,16 +51,24 @@
<div id="linkBanner" class="linkbanner">
<a id="logoff" var:href="logoffPath"
><var:string label:value="Disconnect" /></a>
<a var:href="relativeCalendarPath"
><var:string label:value="Calendar" /></a> |
<a var:href="relativeContactsPath"
<var:if condition="userHasCalendarAccess">
<a id="calendarBannerLink"
var:href="relativeCalendarPath"
><var:string label:value="Calendar" /></a> |
</var:if>
<a id="contactsBannerLink"
var:href="relativeContactsPath"
><var:string label:value="Address Book" /></a> |
<a var:href="relativeMailPath"
><var:string label:value="Mail" /></a> |
<a var:href="relativePreferencesPath"
<var:if condition="userHasMailAccess">
<a id="mailBannerLink" var:href="relativeMailPath"
><var:string label:value="Mail" /></a> |
</var:if>
<a id="preferencesBannerLink"
var:href="relativePreferencesPath"
><var:string label:value="Preferences" /></a>
<var:if condition="context.isUIxDebugEnabled"
>| <a href="#"><var:string
>| <a id="consoleBannerLink"
href="#"><var:string
label:value="Log Console (dev.)" /></a
></var:if>
</div>

View File

@ -1365,15 +1365,24 @@ function onPreferencesClick(event) {
function configureLinkBanner() {
var linkBanner = $("linkBanner");
if (linkBanner) {
var anchors = linkBanner.childNodesWithTag("a");
for (var i = 1; i < 3; i++) {
$(anchors[i]).observe("mousedown", listRowMouseDownHandler);
$(anchors[i]).observe("click", onLinkBannerClick);
var moduleLinks = [ "calendar", "contacts", "mail" ];
for (var i = 0; i < moduleLinks.length; i++) {
var link = $(moduleLinks[i] + "BannerLink");
if (link) {
link.observe("mousedown", listRowMouseDownHandler);
link.observe("click", onLinkBannerClick);
}
}
link = $("preferencesBannerLink");
if (link) {
link.observe("mousedown", listRowMouseDownHandler);
link.observe("click", onPreferencesClick);
}
link = $("consoleBannerLink");
if (link) {
link.observe("mousedown", listRowMouseDownHandler);
link.observe("click", toggleLogConsole);
}
$(anchors[4]).observe("mousedown", listRowMouseDownHandler);
$(anchors[4]).observe("click", onPreferencesClick);
if (anchors.length > 5)
$(anchors[5]).observe("click", toggleLogConsole);
}
}