/usr/GNUstep/System/Library/SOGo-0.9/WebServerResources/
Alias /SOGO.woa/WebServerResources/ \
/usr/GNUstep/System/Library/SOGo-0.9/WebServerResources/
+
+<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*jpg">
+ SetHandler default-handler
+</LocationMatch>
+
+<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*png">
+ SetHandler default-handler
+</LocationMatch>
+
+<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*gif">
+ SetHandler default-handler
+</LocationMatch>
+
+<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*css">
+ SetHandler default-handler
+</LocationMatch>
+
+<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*js">
+ SetHandler default-handler
+</LocationMatch>
+
AliasMatch /SOGo/so/ControlPanel/Products/(.*)/Resources/(.*) \
/usr/GNUstep/System/Library/SOGo-0.9/$1.SOGo/Resources/$2
+2007-07-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder -davNamespaces]): added new overriden
+ method that declares the DAV namespace related to CardDAV.
+ ([SOGoContactGCSFolder -davComplianceClassesInContext:]): new
+ method that declares the "access-control" and "addressbook-access"
+ classes to the list.
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([-lookupActionForCalDAVMethod:]): removed method.
+ ([SOGoAppointmentFolder -davNamespaces]): added new overriden
+ method that declares the DAV namespace related to CalDAV.
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -davNamespaces]): new
+ optional method for subclasses which handle specific extensions to
+ the DAV protocol: CardDAV or CalDAV.
+ ([SOGoFolder
+ -lookupName:lookupNameinContext:localContextacquire:acquire]):
+ new overriden method that handles dav invocations for extensions
+ to DAV by returning an appropriate SoSelectorInvocation.
+
+ * SoObjects/SOGo/NSString+Utilities.m ([NSString
+ -asDavInvocation]): new method returning a dictionary with a "ns"
+ key representing the dav namespace and a "method" key representing
+ the dav method name of the request.
+
+ * UI/PreferencesUI/UIxPreferences.m ([UIxPreferences
+ +initialize]): scan the value of SOGoUIxUserCanChangePassword.
+ Default is "no".
+ ([UIxPreferences -shouldDisplayPasswordChange]): new template
+ method that returns the value of SOGoUIxUserCanChangePassword.
+
+ * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage +initialize]):
+ scan the value of SOGoUIxDefaultModule. If not set, the default
+ module defaults to "Calendar".
+ ([SOGoUserHomePage -defaultAction]): redirect the user to the
+ value of "SOGoUIxDefaultModule".
+
2007-07-20 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/Contacts/UIxContactsListView.m ([UIxContactsListView
0.9.0-20070xxx
--------------
+- added the ability to choose the default module from the
+ application settings: "Calendars", "Contacts" or "Mail";
+- added the ability to show or hide the password change dialog from the
+ application settings;
- put a work-around in the LDAP directory code to avoid fetching all the
- entries whenever a specific one is being requested.
+ entries whenever a specific one is being requested;
0.9.0-20070713
--------------
+++ /dev/null
-# SOGo config
-
-AliasMatch /SOGo/so/ControlPanel/Products/(.*)/Resources/(.*) \
- /Users/helge/GNUstep/Library/SOGo/$1.SOGo/Contents/Resources/$2
-
-<LocationMatch "^/SOGo*">
-SetHandler ngobjweb-adaptor
-SetAppPort 25000
-</LocationMatch>
-
-<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*png">
-SetHandler default-handler
-</LocationMatch>
-
-<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*gif">
-SetHandler default-handler
-</LocationMatch>
-
-<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*css">
-SetHandler default-handler
-</LocationMatch>
-
-<LocationMatch "^/SOGo/so/ControlPanel/Products/.*UI/Resources/.*js">
-SetHandler default-handler
-</LocationMatch>
-
@implementation NSMutableArray (iCalPersonConvenience)
-- (void)removePerson: (iCalPerson *)_person {
+- (void) removePerson: (iCalPerson *) _person
+{
int i;
-
- for (i = [self count] - 1; i >= 0; i--) {
- iCalPerson *p;
+ iCalPerson *p;
- p = [self objectAtIndex:i];
- if ([p hasSameEmailAddress:_person])
- [self removeObjectAtIndex:i];
- }
+ for (i = [self count] - 1; i >= 0; i--)
+ {
+ p = [self objectAtIndex: i];
+ if ([p hasSameEmailAddress: _person])
+ [self removeObjectAtIndex: i];
+ }
}
@end
#import <GDLContentStore/GCSFolder.h>
#import <NGCards/NGCards.h>
-#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOMessage.h>
#import <NGExtensions/NGCalendarDateRange.h>
#import <SOGo/SOGoCustomGroupFolder.h>
#import <SOGo/LDAPUserManager.h>
#import <SOGo/SOGoPermissions.h>
-#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h>
#import "common.h"
return ([_key length] != 0);
}
-- (id) lookupActionForCalDAVMethod: (NSString *)_key
-{
- SoSelectorInvocation *invocation;
- NSString *name;
-
- name = [NSString stringWithFormat: @"%@:", [_key davMethodToObjC]];
-
- invocation = [[SoSelectorInvocation alloc]
- initWithSelectorNamed: name
- addContextParameter: YES];
- [invocation autorelease];
-
- return invocation;
-}
-
- (void) appendObject: (NSDictionary *) object
withBaseURL: (NSString *) baseURL
toREPORTResponse: (WOResponse *) r
}
}
+- (NSArray *) davNamespaces
+{
+ return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:caldav"];
+}
+
- (id) davCalendarQuery: (id) queryContext
{
WOResponse *r;
obj = [super lookupName:_key inContext:_ctx acquire:NO];
if (!obj)
{
- if ([_key hasPrefix: @"{urn:ietf:params:xml:ns:caldav}"])
- obj
- = [self lookupActionForCalDAVMethod: [_key substringFromIndex: 31]];
- else if ([self isValidAppointmentName:_key])
+ if ([self isValidAppointmentName:_key])
{
url = [[[_ctx request] uri] urlWithoutParameters];
if ([url hasSuffix: @"AsTask"])
02111-1307, USA.
*/
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGExtensions/NSObject+Logs.h>
+#import <EOControl/EOQualifier.h>
+#import <EOControl/EOSortOrdering.h>
#import <GDLContentStore/GCSFolder.h>
-#import "common.h"
-
#import "SOGoContactGCSEntry.h"
#import "SOGoContactGCSFolder.h"
return records;
}
+- (NSArray *) davNamespaces
+{
+ return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"];
+}
+
+- (NSArray *) davComplianceClassesInContext: (id)_ctx
+{
+ NSMutableArray *classes;
+ NSArray *primaryClasses;
+
+ classes = [NSMutableArray new];
+ [classes autorelease];
+
+ primaryClasses = [super davComplianceClassesInContext: _ctx];
+ if (primaryClasses)
+ [classes addObjectsFromArray: primaryClasses];
+ [classes addObject: @"access-control"];
+ [classes addObject: @"addressbook-access"];
+
+ return classes;
+}
+
- (NSString *) groupDavResourceType
{
return @"vcard-collection";
- (NSString *) urlWithoutParameters;
- (NSString *) davMethodToObjC;
+- (NSDictionary *) asDavInvocation;
- (NSString *) stringByDetectingURLs;
return newName;
}
+- (NSDictionary *) asDavInvocation
+{
+ NSMutableDictionary *davInvocation;
+ NSRange nsEnclosing, methodEnclosing;
+ unsigned int length;
+
+ davInvocation = nil;
+ if ([self hasPrefix: @"{"])
+ {
+ nsEnclosing = [self rangeOfString: @"}"];
+ length = [self length];
+ if (nsEnclosing.length > 0
+ && nsEnclosing.location < (length - 1))
+ {
+ methodEnclosing = NSMakeRange(nsEnclosing.location + 1,
+ length - nsEnclosing.location - 1);
+ nsEnclosing.length = nsEnclosing.location - 1;
+ nsEnclosing.location = 1;
+ davInvocation = [NSMutableDictionary dictionaryWithCapacity: 2];
+ [davInvocation setObject: [self substringWithRange: nsEnclosing]
+ forKey: @"ns"];
+ [davInvocation setObject: [self substringWithRange: methodEnclosing]
+ forKey: @"method"];
+ }
+ }
+
+ return davInvocation;
+}
+
- (NSRange) _rangeOfURLInRange: (NSRange) refRange
{
int start, length;
- (BOOL) create;
- (NSException *) delete;
+/* dav */
+- (NSArray *) davNamespaces;
+
/* acls as a container */
- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
- (NSArray *) aclsForUser: (NSString *) uid
#import <Foundation/NSURL.h>
#import <NGObjWeb/SoObject.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGObjWeb/SoSelectorInvocation.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <GDLContentStore/GCSFolderType.h>
#import <SaxObjC/XMLNamespaces.h>
+#import "NSString+Utilities.h"
+
#import "SOGoPermissions.h"
#import "SOGoUser.h"
return [[self davURL] absoluteString];
}
+- (id) lookupName: (NSString *) lookupName
+ inContext: (id) localContext
+ acquire: (BOOL) acquire
+{
+ id obj;
+ NSArray *davNamespaces;
+ NSDictionary *davInvocation;
+ NSString *objcMethod;
+
+ obj = [super lookupName: lookupName inContext: localContext
+ acquire: acquire];
+ if (!obj)
+ {
+ davNamespaces = [self davNamespaces];
+ if ([davNamespaces count] > 0)
+ {
+ davInvocation = [lookupName asDavInvocation];
+ if (davInvocation
+ && [davNamespaces
+ containsObject: [davInvocation objectForKey: @"ns"]])
+ {
+ objcMethod = [[davInvocation objectForKey: @"method"]
+ davMethodToObjC];
+ obj = [[SoSelectorInvocation alloc]
+ initWithSelectorNamed:
+ [NSString stringWithFormat: @"%@:", objcMethod]
+ addContextParameter: YES];
+ [obj autorelease];
+ }
+ }
+ }
+
+ return obj;
+}
+
/* WebDAV */
+- (NSArray *) davNamespaces
+{
+ return nil;
+}
+
- (BOOL) davIsCollection
{
return [self isFolderish];
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
+#import <Foundation/NSURL.h>
+#import <Foundation/NSUserDefaults.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <NGExtensions/NSCalendarDate+misc.h>
+#import <NGExtensions/NSObject+Logs.h>
#import <Appointments/SOGoFreeBusyObject.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGoUI/UIxComponent.h>
+static NSString *defaultModule;
+
@interface SOGoUserHomePage : UIxComponent
@end
@implementation SOGoUserHomePage
++ (void) initialize
+{
+ NSUserDefaults *ud;
+
+ ud = [NSUserDefaults standardUserDefaults];
+ defaultModule = [ud stringForKey: @"SOGoUIxDefaultModule"];
+ if (defaultModule)
+ {
+ if (defaultModule)
+ {
+ if (!([defaultModule isEqualToString: @"Calendar"]
+ || [defaultModule isEqualToString: @"Contacts"]
+ || [defaultModule isEqualToString: @"Mail"]))
+ {
+ [self logWithFormat: @"default module '%@' not accepted (must be"
+ @"'Calendar', 'Contacts' or Mail)", defaultModule];
+ defaultModule = @"Calendar";
+ }
+ }
+ else
+ defaultModule = @"Calendar";
+
+ [self logWithFormat: @"default module set to '%@'", defaultModule];
+ [defaultModule retain];
+ }
+}
+
- (id <WOActionResults>) defaultAction
{
- NSString *baseURL, *url;
+ SOGoUserFolder *co;
+ NSURL *moduleURL;
- baseURL = [[context request] uri];
- url = [baseURL stringByAppendingString:@"/../Calendar"];
+ co = [self clientObject];
+ moduleURL = [NSURL URLWithString: defaultModule
+ relativeToURL: [co soURL]];
- return [self redirectToLocation: url];
+ return [self redirectToLocation: [moduleURL absoluteString]];
}
- (void) _fillFreeBusyItems: (NSMutableArray *) items
workweek = from -> to
identities */
+static BOOL shouldDisplayPasswordChange = NO;
+
@implementation UIxPreferences
++ (void) initialize
+{
+ NSUserDefaults *ud;
+
+ ud = [NSUserDefaults standardUserDefaults];
+ shouldDisplayPasswordChange
+ = [ud boolForKey: @"SOGoUIxUserCanChangePassword"];
+}
+
- (id) init
{
NSDictionary *locale;
return [[request method] isEqualToString: @"POST"];
}
+- (BOOL) shouldDisplayPasswordChange
+{
+ return shouldDisplayPasswordChange;
+}
+
@end
label:value="Date and Time"/></li>
<li target="calendarOptionsView"><var:string
label:value="Calendar Options"/></li>
- <li target="passwordView"><var:string label:value="Password"/></li>
+ <var:if condition="shouldDisplayPasswordChange">
+ <li target="passwordView"><var:string label:value="Password"/></li>
+ </var:if>
</ul>
<div id="outOfOfficeView" class="tab">
<label><input
<var:popup list="reminderTimesList" item="item"
string="itemReminderTimeText" selection="userReminderTime"/></label>
</div>
- <div id="passwordView" class="tab">
- <label><var:string label:value="New password:"
- /><input type="text" class="textField"
- const:enabled="disabled"
- var:value="newPassword"/></label><br/>
- <label><var:string label:value="Confirmation:"
- /><input type="text" class="textField"
- const:enabled="disabled"
- var:value="newPasswordConfirmation"/></label><br/>
- <input type="button" class="button"
- id="changePasswordBtn" label:value="Change"/>
- </div>
+ <var:if condition="shouldDisplayPasswordChange">
+ <div id="passwordView" class="tab">
+ <label><var:string label:value="New password:"
+ /><input type="text" class="textField"
+ const:enabled="disabled"
+ var:value="newPassword"/></label><br/>
+ <label><var:string label:value="Confirmation:"
+ /><input type="text" class="textField"
+ const:enabled="disabled"
+ var:value="newPasswordConfirmation"/></label><br/>
+ <input type="button" class="button"
+ id="changePasswordBtn" label:value="Change"/>
+ </div>
+ </var:if>
</div>
</form>
</var:component>