/* SoClass security declarations */
sInfo = [self soClassSecurityInfo];
/* require View permission to access the root (bound to authenticated ...) */
- [sInfo declareObjectProtected: SoPerm_View];
+// [sInfo declareObjectProtected: SoPerm_View];
/* to allow public access to all contained objects (subkeys) */
[sInfo setDefaultAccess: @"allow"];
- implemented cookie-based identification in the web interface;
- fixed a bug where a false positive happening whenever a wrong user login was
given during an indirect bind;
+- deleting a message no longer expunges its parent folder;
+- countless bugfixes;
0.9.0-20070824
--------------
02111-1307, USA.
*/
+#import <Foundation/NSCalendarDate.h>
+
#import <NGObjWeb/NSException+HTTP.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
}
/* "iCal multifolder saves" */
+- (BOOL) _aptIsStillRelevant: (iCalEvent *) appointment
+{
+ NSCalendarDate *now;
+
+ now = [NSCalendarDate calendarDate];
+
+ return ([[appointment endDate] earlierDate: now] == now);
+}
- (NSException *) saveContentString: (NSString *) _iCal
baseSequence: (int) _v
if (delError != nil) return delError;
/* email notifications */
- if ([self sendEMailNotifications])
+ if ([self sendEMailNotifications]
+ && [self _aptIsStillRelevant: newApt])
{
- attendees = [NSMutableArray arrayWithArray: [changes insertedAttendees]];
+ attendees
+ = [NSMutableArray arrayWithArray: [changes insertedAttendees]];
[attendees removePerson: organizer];
[self sendEMailUsingTemplateNamed: @"Invitation"
forOldObject: nil
toAttendees: attendees];
}
- attendees = [NSMutableArray arrayWithArray:[changes deletedAttendees]];
+ attendees
+ = [NSMutableArray arrayWithArray: [changes deletedAttendees]];
[attendees removePerson: organizer];
if ([attendees count])
{
- iCalEvent *canceledApt;
+ iCalEvent *cancelledApt;
- canceledApt = [newApt copy];
- [(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"];
+ cancelledApt = [newApt copy];
+ [(iCalCalendar *) [cancelledApt parent] setMethod: @"cancel"];
[self sendEMailUsingTemplateNamed: @"Removal"
forOldObject: nil
- andNewObject: canceledApt
+ andNewObject: cancelledApt
toAttendees: attendees];
- [canceledApt release];
+ [cancelledApt release];
}
}
attendees = [NSMutableArray arrayWithArray:[apt attendees]];
[attendees removePerson:[apt organizer]];
- /* flag appointment as being canceled */
+ /* flag appointment as being cancelled */
[(iCalCalendar *) [apt parent] setMethod: @"cancel"];
[apt increaseSequence];
-<#IsSubject>Appointment <#AptStartDate /> at <#AptStartTime /> has been canceled</#IsSubject>
+<#IsSubject>Appointment <#AptStartDate /> at <#AptStartTime /> has been cancelled</#IsSubject>
<#IsBody>
The appointment at <#AptStartDate /> <#AptStartTime /> has been cancelled by <#Organizer />.
</#IsBody>
\ No newline at end of file
// attendees = [NSMutableArray arrayWithArray:[changes deletedAttendees]];
// [attendees removePerson: organizer];
// if ([attendees count]) {
-// iCalToDo *canceledApt;
+// iCalToDo *cancelledApt;
-// canceledApt = [newApt copy];
-// [(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"];
+// cancelledApt = [newApt copy];
+// [(iCalCalendar *) [cancelledApt parent] setMethod: @"cancel"];
// [self sendEMailUsingTemplateNamed: @"Removal"
// forOldObject: nil
-// andNewObject: canceledApt
+// andNewObject: cancelledApt
// toAttendees: attendees];
-// [canceledApt release];
+// [cancelledApt release];
// }
// }
attendees = [NSMutableArray arrayWithArray:[task attendees]];
[attendees removePerson:[task organizer]];
- /* flag task as being canceled */
+ /* flag task as being cancelled */
[(iCalCalendar *) [task parent] setMethod: @"cancel"];
[task increaseSequence];
error = [[self imap4Connection] markURLDeleted: [self imap4URL]];
if (error != nil) return error;
- /* c) expunge */
-
- error = [[self imap4Connection] expungeAtURL:[[self container] imap4URL]];
- if (error != nil) return error; // TODO: unflag as deleted?
[self flushMailCaches];
return nil;
- (NSException *) moveToFolderNamed: (NSString *) folderName
inContext: (id)_ctx
{
- /*
- Trashing is three actions:
- a) copy to trash folder
- b) mark mail as deleted
- c) expunge folder
-
- In case b) or c) fails, we can't do anything because IMAP4 doesn't tell us
- the ID used in the trash folder.
- */
SOGoMailAccounts *destFolder;
NSEnumerator *folders;
NSString *currentFolderName, *reason;
error = [[self imap4Connection] markURLDeleted: [self imap4URL]];
if (error != nil) return error;
-
- /* c) expunge */
- error = [[self imap4Connection] expungeAtURL:[[self container] imap4URL]];
- if (error != nil) return error; // TODO: unflag as deleted?
[self flushMailCaches];
return nil;
int start, length;
NSRange workRange;
+// [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"];
+// [urlAfterEndingChars addCharactersInString: @"()[]{}&;<\t \r\n"];
+
if (!urlNonEndingChars)
{
urlNonEndingChars = [NSMutableCharacterSet new];
- [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"];
+ [urlNonEndingChars addCharactersInString: @">=,.:;\t \r\n"];
}
if (!urlAfterEndingChars)
{
urlAfterEndingChars = [NSMutableCharacterSet new];
- [urlAfterEndingChars addCharactersInString: @"()[]{}&;<\t \r\n"];
+ [urlAfterEndingChars addCharactersInString: @"\t \r\n"];
}
start = refRange.location;
#import <Foundation/NSString.h>
#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/SoClassSecurityInfo.h>
#import <NGExtensions/NSObject+Logs.h>
#import <Appointments/SOGoAppointmentFolder.h>
@implementation SOGoUserFolder
++ (void) initialize
+{
+ SoClassSecurityInfo *sInfo;
+ NSArray *basicRoles;
+
+ sInfo = [self soClassSecurityInfo];
+ [sInfo declareObjectProtected: SoPerm_View];
+
+ basicRoles = [NSArray arrayWithObject: SoRole_Authenticated];
+
+ /* require Authenticated role for View and WebDAV */
+ [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
+ [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
+}
+
/* accessors */
- (NSString *) login
*/
#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
+#import <NGObjWeb/SoDefaultRenderer.h>
#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOCookie.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGLdap/NGLdapConnection.h>
#import <UI/MainUI/SOGoRootPage.h>
return [SOGoUser userWithLogin: login roles: roles];
}
+- (WOResponse *) preprocessCredentialsInContext: (WOContext *) context
+{
+ /*
+ This is called by SoObjectRequestHandler prior doing any significant
+ processing to allow the authenticator to reject invalid requests.
+ */
+ WOResponse *response;
+ NSString *auth;
+
+ auth = [[context request]
+ cookieValueForKey: [self cookieNameInContext:context]];
+ if ([auth isEqualToString: @"discard"])
+ {
+ [context setObject: [NSArray arrayWithObject: SoRole_Anonymous]
+ forKey: @"SoAuthenticatedRoles"];
+ response = nil;
+ }
+ else
+ response = [super preprocessCredentialsInContext: context];
+
+ return response;
+}
+
- (void) setupAuthFailResponse: (WOResponse *) response
withReason: (NSString *) reason
inContext: (WOContext *) context
{
- id page;
+ WOComponent *page;
+ WOCookie *authCookie;
+ NSCalendarDate *date;
page = [[WOApplication application] pageWithName: @"SOGoRootPage"
forRequest: [context request]];
- [page appendToResponse: response inContext: context];
+ [[SoDefaultRenderer sharedRenderer] renderObject: page
+ inContext: context];
+ authCookie = [WOCookie cookieWithName: [self cookieNameInContext: context]
+ value: @"discard"];
+ [authCookie setPath: @"/"];
+ date = [NSCalendarDate calendarDate];
+ [authCookie setExpires: [date yesterday]];
+ [response addCookie: authCookie];
}
@end /* SOGoWebAuthenticator */
#import "UIxMailPartViewer.h"
@interface UIxMailPartHTMLViewer : UIxMailPartViewer
+{
+ id handler;
+}
- (NSString *) flatContentAsString;
- (void) dealloc
{
- if (crumb)
- [crumb release];
- if (result)
- [result release];
- if (css)
- [css release];
+ [crumb release];
+ [result release];
+ [css release];
[super dealloc];
}
- (NSString *) css
{
- return [[css copy] autorelease];
+ return css;
}
- (NSString *) result
{
- return [[result copy] autorelease];
+ return result;
}
/* SaxContentHandler */
{
showWhoWeAre();
- if (crumb)
- [crumb release];
- if (result)
- [result release];
- if (css)
- [css release];
+ [crumb release];
+ [css release];
+ [result release];
result = [NSMutableString new];
css = [NSMutableString new];
crumb = [NSMutableArray new];
+
inBody = NO;
inStyle = NO;
inScript = NO;
}
}
+- (void) _finishCSS
+{
+ [css replaceString: @".SOGoHTMLMail-CSS-Delimiter body"
+ withString: @".SOGoHTMLMail-CSS-Delimiter"];
+ [css replaceString: @";" withString: @" !important;"];
+ [css replaceString: @"<!--" withString: @""];
+ [css replaceString: @"-->" withString: @""];
+}
+
- (void) endElement: (NSString *) _localName
namespace: (NSString *) _ns
rawName: (NSString *) _rawName
else if (inBody)
{
if ([_localName caseInsensitiveCompare: @"body"] == NSOrderedSame)
- inBody = NO;
+ {
+ inBody = NO;
+ if (css)
+ [self _finishCSS];
+ }
else
[result appendFormat: @"</%@>", _localName];
}
{
if (inStyle)
[self _appendStyle: _chars length: _len];
- if (inBody)
+ else if (inBody)
{
tmpString = [NSString stringWithCharacters: _chars length: _len];
[result appendString: [tmpString stringByEscapingHTMLString]];
@implementation UIxMailPartHTMLViewer
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ handler = nil;
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [handler release];
+ [super dealloc];
+}
+
- (void) _convertReferencesForPart: (NSDictionary *) part
withCount: (unsigned int) count
andBaseURL: (NSString *) url
return attachmentIds;
}
-- (NSString *) flatContentAsString
+- (void) _parseContent
{
id <NSObject, SaxXMLReader> parser;
- _UIxHTMLMailContentHandler *handler;
- NSString *css;
- NSMutableString *content;
NSData *preparsedContent;
- content = [NSMutableString string];
-
preparsedContent = [super decodedFlatContent];
parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType: @"text/html"];
[handler setAttachmentIds: [self _attachmentIds]];
[parser setContentHandler: handler];
[parser parseFromSource: preparsedContent];
+}
+
+- (NSString *) cssContent
+{
+ NSString *cssContent, *css;
+
+ if (!handler)
+ [self _parseContent];
css = [handler css];
if ([css length])
- [content appendFormat: @"<style type=\"text/css\">%@</style>", css];
- [content appendString: [handler result]];
- [handler release];
+ cssContent = [NSString stringWithFormat: @"<style type=\"text/css\">%@</style>",
+ [handler css]];
+ else
+ cssContent = @"";
+
+ return cssContent;
+}
+
+- (NSString *) flatContentAsString
+{
+ if (!handler)
+ [self _parseContent];
- return content;
+ return [handler result];
}
@end
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/NSException+HTTP.h>
+
#import <SoObjects/Mailer/SOGoDraftObject.h>
#import <SoObjects/Mailer/SOGoDraftsFolder.h>
#import <SoObjects/Mailer/SOGoMailAccount.h>
@implementation UIxMailActions
-- (WOResponse *) editAction
+- (WOResponse *) replyToAll: (BOOL) toAll
{
SOGoMailAccount *account;
SOGoMailObject *co;
account = [co mailAccountFolder];
folder = [account draftsFolderInContext: context];
newMail = [folder newDraft];
- [newMail fetchMailForEditing: co];
- [newMail storeInfo];
+ [newMail fetchMailForReplying: co toAll: toAll];
newLocation = [NSString stringWithFormat: @"%@/edit",
[newMail baseURLInContext: context]];
return [self redirectToLocation: newLocation];
}
-- (WOResponse *) replyToAll: (BOOL) toAll
+- (WOResponse *) replyAction
+{
+ return [self replyToAll: NO];
+}
+
+- (WOResponse *) replyToAllAction
+{
+ return [self replyToAll: NO];
+}
+
+- (WOResponse *) forwardAction
{
SOGoMailAccount *account;
SOGoMailObject *co;
account = [co mailAccountFolder];
folder = [account draftsFolderInContext: context];
newMail = [folder newDraft];
- [newMail fetchMailForReplying: co toAll: toAll];
+ [newMail fetchMailForForwarding: co];
newLocation = [NSString stringWithFormat: @"%@/edit",
[newMail baseURLInContext: context]];
return [self redirectToLocation: newLocation];
}
-- (WOResponse *) replyAction
+- (id) trashAction
{
- return [self replyToAll: NO];
+ id response;
+
+ response = [[self clientObject] trashInContext: context];
+ if (!response)
+ {
+ response = [context response];
+ [response setStatus: 204];
+ }
+
+ return response;
}
-- (WOResponse *) replyToAllAction
+- (id) moveAction
{
- return [self replyToAll: NO];
+ NSString *destinationFolder;
+ id response;
+
+ destinationFolder = [[context request] formValueForKey: @"tofolder"];
+ if ([destinationFolder length] > 0)
+ {
+ response = [[self clientObject] moveToFolderNamed: destinationFolder
+ inContext: context];
+ if (!response)
+ {
+ response = [context response];
+ [response setStatus: 204];
+ }
+ }
+ else
+ response = [NSException exceptionWithHTTPStatus: 500 /* Server Error */
+ reason: @"No destination folder given"];
+
+ return response;
}
-- (WOResponse *) forwardAction
+/* SOGoDraftObject */
+- (WOResponse *) editAction
{
SOGoMailAccount *account;
SOGoMailObject *co;
account = [co mailAccountFolder];
folder = [account draftsFolderInContext: context];
newMail = [folder newDraft];
- [newMail fetchMailForForwarding: co];
+ [newMail fetchMailForEditing: co];
+ [newMail storeInfo];
newLocation = [NSString stringWithFormat: @"%@/edit",
[newMail baseURLInContext: context]];
return [self redirectToLocation: newLocation];
}
-/* SOGoDraftObject */
- (id) deleteAction
{
SOGoDraftObject *draft;
- (void) _setQualifierForCriteria: (NSString *) criteria
andValue: (NSString *) value
{
+ NSMutableString *newQString;
+
[qualifier release];
- if ([criteria isEqualToString: @"subject"])
- qualifier = [EOQualifier qualifierWithQualifierFormat:
- @"(subject doesContain: %@)",
- value];
- else if ([criteria isEqualToString: @"sender"])
- qualifier = [EOQualifier qualifierWithQualifierFormat:
- @"(from doesContain: %@)",
- value];
- else if ([criteria isEqualToString: @"subject_or_sender"])
- qualifier = [EOQualifier qualifierWithQualifierFormat:
- @"(subject doesContain: %@) OR "
- @"(from doesContain: %@)",
- value, value];
- else if ([criteria isEqualToString: @"to_or_cc"])
- qualifier = [EOQualifier qualifierWithQualifierFormat:
- @"(to doesContain: %@) OR "
- @"(cc doesContain: %@)",
- value, value];
- else if ([criteria isEqualToString: @"entire_message"])
- qualifier = [EOQualifier qualifierWithQualifierFormat:
- @"(message doesContain: %@)",
- value];
- else
- qualifier = nil;
+ newQString = [NSMutableString stringWithString: @"(NOT flags doesContain: deleted)"];
+ if ([value length] > 0)
+ {
+ if ([criteria isEqualToString: @"subject"])
+ [newQString appendFormat: @" AND (subject doesContain: %@)", value];
+ else if ([criteria isEqualToString: @"sender"])
+ [newQString appendFormat: @" AND (sender doesContain: %@)", value];
+ else if ([criteria isEqualToString: @"subject_or_sender"])
+ [newQString appendFormat: @" AND ((sender doesContain: %@)"
+ @" OR (from doesContain: %@))",
+ value, value];
+ else if ([criteria isEqualToString: @"to_or_cc"])
+ [newQString appendFormat: @" AND ((to doesContain: %@)"
+ @" OR (cc doesContain: %@))",
+ value, value];
+ else if ([criteria isEqualToString: @"entire_message"])
+ [newQString appendFormat: @" AND (message doesContain: %@)", value];
+ }
+ qualifier = [EOQualifier qualifierWithQualifierFormat: newQString];
[qualifier retain];
}
specificMessage = [request formValueForKey: @"pageforuid"];
searchCriteria = [request formValueForKey: @"search"];
searchValue = [request formValueForKey: @"value"];
- if ([searchCriteria length] > 0
- && [searchValue length] > 0)
- [self _setQualifierForCriteria: searchCriteria
- andValue: searchValue];
+ [self _setQualifierForCriteria: searchCriteria
+ andValue: searchValue];
firstMessageNumber
= ((specificMessage)
return [self redirectToLocation: url];
}
-- (id) deleteAction
-{
- NSException *ex;
-
- if (![self isDeletableClientObject]) {
- return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
- reason:@"method cannot be invoked on "
- @"the specified object"];
- }
-
- if ([self isInvokedBySafeMethod]) {
- // TODO: fix UI to use POST for unsafe actions
- [self logWithFormat:@"WARNING: method is invoked using safe HTTP method!"];
- }
-
- if ((ex = [[self clientObject] delete]) != nil) {
- id url;
-
- url = [[ex reason] stringByEscapingURL];
- url = [@"view?error=" stringByAppendingString:url];
- return [self redirectToLocation:url];
- //return ex;
- }
-
- if (![self isInlineViewer]) {
- // if everything is ok, close the window (send a JS closing the Window)
- id page;
-
- page = [self pageWithName:@"UIxMailWindowCloser"];
- [page takeValue:@"YES" forKey:@"refreshOpener"];
- return page;
- }
-
- return [self redirectToParentFolder];
-}
-
-- (id) trashAction
-{
- NSException *ex;
-
- if ([self isInvokedBySafeMethod]) {
- // TODO: fix UI to use POST for unsafe actions
- [self logWithFormat:@"WARNING: method is invoked using safe HTTP method!"];
- }
-
- if ((ex = [[self clientObject] trashInContext:context]) != nil) {
- id url;
-
- if ([[[context request] formValueForKey:@"jsonly"] boolValue])
- /* called using XMLHttpRequest */
- return ex;
-
- url = [[ex reason] stringByEscapingURL];
- url = [@"view?error=" stringByAppendingString:url];
- return [self redirectToLocation:url];
- }
-
- if ([[[context request] formValueForKey:@"jsonly"] boolValue]) {
- /* called using XMLHttpRequest */
- [[context response] setStatus:200 /* OK */];
- return [context response];
- }
-
- if (![self isInlineViewer]) {
- // if everything is ok, close the window (send a JS closing the Window)
- id page;
-
- page = [self pageWithName:@"UIxMailWindowCloser"];
- [page takeValue:@"YES" forKey:@"refreshOpener"];
- return page;
- }
-
- return [self redirectToParentFolder];
-}
-
-- (id <WOActionResults>) moveAction
-{
- id <WOActionResults> result;
- NSString *destinationFolder;
- id url;
-
- if ([self isInvokedBySafeMethod]) {
- // TODO: fix UI to use POST for unsafe actions
- [self logWithFormat:@"WARNING: method is invoked using safe HTTP method!"];
- }
-
- destinationFolder = [self queryParameterForKey: @"tofolder"];
- if ([destinationFolder length] > 0)
- {
- result = [[self clientObject] moveToFolderNamed: destinationFolder
- inContext: context];
- if (result)
- {
- if (![[[context request] formValueForKey:@"jsonly"] boolValue])
- {
- url = [NSString stringWithFormat: @"view?error=%@",
- [[result reason] stringByEscapingURL]];
- result = [self redirectToLocation: url];
- }
- }
- else
- {
- result = [context response];
- [result setStatus: 200];
- }
- }
- else
- result = [NSException exceptionWithHTTPStatus:500 /* Server Error */
- reason: @"No destination folder given"];
-
- return result;
-}
-
/* generating response */
- (void) appendToResponse: (WOResponse *) _response
-{ /* -*-javascript-*- */
-requires = ( MAIN, MainUI, CommonUI, Mailer, MailPartViewers ); /* , Sieve */
+{ /* -*-java-*- */
+ requires = ( MAIN, MainUI, CommonUI, Mailer, MailPartViewers ); /* , Sieve */
- publicResources = (
- "uix.css",
- "mailer.css",
- "mailer.js",
- "generic.js",
- "searchfield.js",
- "UIxAppointmentEditor.js",
- "UIxContactEditor.js",
- "UIxMailToSelection.js",
+ publicResources = ("uix.css",
+ "mailer.css",
+ "mailer.js",
+ "generic.js",
+ "searchfield.js",
+ "UIxAppointmentEditor.js",
+ "UIxContactEditor.js",
+ "UIxMailToSelection.js",
- "lori_32x32.png",
+ "lori_32x32.png",
- "tbtv_account_17x17.gif",
- "tbtv_drafts_17x17.gif",
- "tbtv_inbox_17x17.gif",
- "tbtv_junction2_17x17.gif",
- "tbtv_junction_17x17.gif",
- "tbtv_leaf_corner_17x17.gif",
- "tbtv_line_17x17.gif",
- "tbtv_minus_17x17.gif",
- "tbtv_plus_17x17.gif",
- "tbtv_corner_17x17.gif",
- "tbtv_corner_minus_17x17.gif",
- "tbtv_corner_plus_17x17.gif",
- "tbtv_sent_17x17.gif",
- "tbtv_trash_17x17.gif",
+ "tbtv_account_17x17.gif",
+ "tbtv_drafts_17x17.gif",
+ "tbtv_inbox_17x17.gif",
+ "tbtv_junction2_17x17.gif",
+ "tbtv_junction_17x17.gif",
+ "tbtv_leaf_corner_17x17.gif",
+ "tbtv_line_17x17.gif",
+ "tbtv_minus_17x17.gif",
+ "tbtv_plus_17x17.gif",
+ "tbtv_corner_17x17.gif",
+ "tbtv_corner_minus_17x17.gif",
+ "tbtv_corner_plus_17x17.gif",
+ "tbtv_sent_17x17.gif",
+ "tbtv_trash_17x17.gif",
- "tbtb_addressbook.png",
- "tbtb_compose.png",
- "tbtb_delete.png",
- "tbtb_deletedoc.png",
- "tbtb_filetofolder.png",
- "tbtb_forward.png",
- "tbtb_getmail.png",
- "tbtb_next.png",
- "tbtb_previous.png",
- "tbtb_print.png",
- "tbtb_reply.png",
- "tbtb_replyall.png",
- "tbtb_search.png",
- "tbtb_trash.png",
+ "tbtb_addressbook.png",
+ "tbtb_compose.png",
+ "tbtb_delete.png",
+ "tbtb_deletedoc.png",
+ "tbtb_filetofolder.png",
+ "tbtb_forward.png",
+ "tbtb_getmail.png",
+ "tbtb_next.png",
+ "tbtb_previous.png",
+ "tbtb_print.png",
+ "tbtb_reply.png",
+ "tbtb_replyall.png",
+ "tbtb_search.png",
+ "tbtb_trash.png",
- "tbtb_compose_addressbook_30x30.png",
- "tbtb_compose_attach_30x30.png",
- "tbtb_compose_clip_30x30.png",
- "tbtb_compose_cut_30x30.png",
- "tbtb_compose_dup_30x30.png",
- "tbtb_compose_file_30x30.png",
- "tbtb_compose_lock_30x30.png",
- "tbtb_compose_quote_30x30.png",
- "tbtb_compose_send_30x30.png",
- "tbtb_compose_spell_30x30.png",
+ "tbtb_compose_addressbook_30x30.png",
+ "tbtb_compose_attach_30x30.png",
+ "tbtb_compose_clip_30x30.png",
+ "tbtb_compose_cut_30x30.png",
+ "tbtb_compose_dup_30x30.png",
+ "tbtb_compose_file_30x30.png",
+ "tbtb_compose_lock_30x30.png",
+ "tbtb_compose_quote_30x30.png",
+ "tbtb_compose_send_30x30.png",
+ "tbtb_compose_spell_30x30.png",
- "message-mail.png",
- "message-mail-read.png",
+ "message-mail.png",
+ "message-mail-read.png",
- "icon_mark_flagged.gif",
- "icon_mark_read.gif",
- "icon_mark_unflagged.gif",
- "icon_mark_unread.gif",
- "icon_read.gif",
- "icon_unread.gif",
+ "icon_mark_flagged.gif",
+ "icon_mark_read.gif",
+ "icon_mark_unflagged.gif",
+ "icon_mark_unread.gif",
+ "icon_read.gif",
+ "icon_unread.gif",
- "title_attachment_14x14.png",
- "title_config.png",
- "title_junk.png",
- "title_read_14x14.png",
- "title_thread.png",
- "title_sortdown_12x12.png",
- "title_sortup_12x12.png",
- );
+ "title_attachment_14x14.png",
+ "title_config.png",
+ "title_junk.png",
+ "title_read_14x14.png",
+ "title_thread.png",
+ "title_sortdown_12x12.png",
+ "title_sortup_12x12.png",
+ );
-factories = {
-};
+ factories = {
+ };
-categories = {
- SOGoMailFolder = {
+ categories = {
+ SOGoMailFolder = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoMailObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoMailObject.toolbar";
+ };
};
methods = {
- subscribe = {
- protectedBy = "<public>";
- actionClass = "UIxMailFolderActions";
- actionName = "subscribe";
- };
- unsubscribe = {
- protectedBy = "<public>";
- actionClass = "UIxMailFolderActions";
- actionName = "unsubscribe";
- };
- quotas = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "quotas";
- };
- view = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- };
- ajax = {
- protectedBy = "View";
- pageName = "UIxMailAjaxRequest";
- };
- index = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- };
- GET = { /* hack to make it work as the default method */
- protectedBy = "View";
- pageName = "UIxMailListView";
- };
- markMessageUnread = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- actionName = "markMessageUnread";
- };
- markMessageRead = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- actionName = "markMessageRead";
- };
- getMail = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- actionName = "getMail";
- };
- expunge = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "emptyTrash";
- };
- createFolder = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "createFolder";
- };
- renameFolder = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "renameFolder";
- };
- deleteFolder = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "deleteFolder";
- };
- userRights = {
- protectedBy = "ReadAcls";
- pageName = "UIxMailUserRightsEditor";
- };
- saveUserRights = {
- protectedBy = "SaveAcls";
- pageName = "UIxMailUserRightsEditor";
- actionName = "saveUserRights";
- };
+ subscribe = {
+ protectedBy = "<public>";
+ actionClass = "UIxMailFolderActions";
+ actionName = "subscribe";
+ };
+ unsubscribe = {
+ protectedBy = "<public>";
+ actionClass = "UIxMailFolderActions";
+ actionName = "unsubscribe";
+ };
+ quotas = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "quotas";
+ };
+ view = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ };
+ ajax = {
+ protectedBy = "View";
+ pageName = "UIxMailAjaxRequest";
+ };
+ index = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ };
+ GET = { /* hack to make it work as the default method */
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ };
+ markMessageUnread = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ actionName = "markMessageUnread";
+ };
+ markMessageRead = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ actionName = "markMessageRead";
+ };
+ getMail = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ actionName = "getMail";
+ };
+ expunge = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "emptyTrash";
+ };
+ createFolder = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "createFolder";
+ };
+ renameFolder = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "renameFolder";
+ };
+ deleteFolder = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "deleteFolder";
+ };
+ userRights = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxMailUserRightsEditor";
+ };
+ saveUserRights = {
+ protectedBy = "SaveAcls";
+ pageName = "UIxMailUserRightsEditor";
+ actionName = "saveUserRights";
+ };
};
- };
+ };
- SOGoTrashFolder = {
+ SOGoTrashFolder = {
/* just a new toolbar, other things come from SOGoMailFolder */
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoMailObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoMailObject.toolbar";
+ };
};
methods = {
- emptyTrash = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "emptyTrash";
- };
+ emptyTrash = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "emptyTrash";
+ };
};
- };
+ };
- SOGoMailObject = {
+ SOGoMailObject = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoMailObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoMailObject.toolbar";
+ };
};
methods = {
- view = {
- protectedBy = "View";
- pageName = "UIxMailView";
- };
- viewsource = {
- protectedBy = "View";
- actionClass = "UIxMailSourceView";
- actionName = "viewSource";
- };
- popupview = {
- protectedBy = "View";
- pageName = "UIxMailPopupView";
- };
- move = {
- protectedBy = "View";
- pageName = "UIxMailView";
- actionName = "move";
- };
- delete = {
- protectedBy = "View";
- pageName = "UIxMailView";
- actionName = "delete";
- };
- trash = {
- protectedBy = "View";
- pageName = "UIxMailView";
- actionName = "trash";
- };
- junk = {
- protectedBy = "View";
- pageName = "UIxMailView";
- actionName = "junk";
- };
- edit = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "edit";
- };
- reply = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "reply";
- };
- replyall = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "replyToAll";
- };
- forward = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "forward";
- };
+ view = {
+ protectedBy = "View";
+ pageName = "UIxMailView";
+ };
+ viewsource = {
+ protectedBy = "View";
+ actionClass = "UIxMailSourceView";
+ actionName = "viewSource";
+ };
+ popupview = {
+ protectedBy = "View";
+ pageName = "UIxMailPopupView";
+ };
+ move = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "move";
+ };
+ trash = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "trash";
+ };
+ junk = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "junk";
+ };
+ edit = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "edit";
+ };
+ reply = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "reply";
+ };
+ replyall = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "replyToAll";
+ };
+ forward = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "forward";
+ };
};
- };
+ };
- SOGoMailAccounts = {
+ SOGoMailAccounts = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoMailObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoMailObject.toolbar";
+ };
};
methods = {
- view = {
- protectedBy = "View";
- pageName = "UIxMailMainFrame";
- };
- compose = {
- protectedBy = "View";
- pageName = "UIxMailMainFrame";
- actionName = "compose";
- };
+ view = {
+ protectedBy = "View";
+ pageName = "UIxMailMainFrame";
+ };
+ compose = {
+ protectedBy = "View";
+ pageName = "UIxMailMainFrame";
+ actionName = "compose";
+ };
};
- };
+ };
- SOGoMailAccount = {
+ SOGoMailAccount = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoMailObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoMailObject.toolbar";
+ };
};
methods = {
- compose = {
- protectedBy = "View";
- actionClass = "UIxMailAccountActions";
- actionName = "compose";
- };
- mailboxes = {
- protectedBy = "View";
- actionClass = "UIxMailAccountActions";
- actionName = "listMailboxes";
- };
- createFolder = {
- protectedBy = "View";
- actionClass = "UIxMailFolderActions";
- actionName = "createFolder";
- };
+ compose = {
+ protectedBy = "View";
+ actionClass = "UIxMailAccountActions";
+ actionName = "compose";
+ };
+ mailboxes = {
+ protectedBy = "View";
+ actionClass = "UIxMailAccountActions";
+ actionName = "listMailboxes";
+ };
+ createFolder = {
+ protectedBy = "View";
+ actionClass = "UIxMailFolderActions";
+ actionName = "createFolder";
+ };
};
- };
+ };
- SOGoDraftsFolder = {
+ SOGoDraftsFolder = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = ( /* the toolbar groups */
- ( /* first group */
- { link = "getMail";
- image = "tb-mail-getmail-flat-24x24.png";
- cssClass = "tbicon_getmail"; label = "Get Mail"; },
- {
- link = "#"; // "compose"; // target = "_blank";
- isSafe = NO;
- onclick = "return openMessageWindow(null, 'compose');";
- image = "tb-mail-write-flat-24x24.png";
- cssClass = "tbicon_compose"; label = "Write"; },
- )
- );
- };
+ toolbar = {
+ protectedBy = "View";
+ value = ( /* the toolbar groups */
+ ( /* first group */
+ { link = "getMail";
+ image = "tb-mail-getmail-flat-24x24.png";
+ cssClass = "tbicon_getmail"; label = "Get Mail"; },
+ {
+ link = "#"; // "compose"; // target = "_blank";
+ isSafe = NO;
+ onclick = "return openMessageWindow(null, 'compose');";
+ image = "tb-mail-write-flat-24x24.png";
+ cssClass = "tbicon_compose"; label = "Write"; },
+ )
+ );
+ };
};
methods = {
- view = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- };
- getMail = {
- protectedBy = "View";
- pageName = "UIxMailListView";
- };
+ view = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ };
+ getMail = {
+ protectedBy = "View";
+ pageName = "UIxMailListView";
+ };
};
- };
+ };
- SOGoDraftObject = {
+ SOGoDraftObject = {
slots = {
- toolbar = {
- protectedBy = "View";
- value = "SOGoDraftObject.toolbar";
- };
+ toolbar = {
+ protectedBy = "View";
+ value = "SOGoDraftObject.toolbar";
+ };
};
methods = {
- edit = {
- protectedBy = "View";
- pageName = "UIxMailEditor";
- };
- save = {
- protectedBy = "View";
- pageName = "UIxMailEditor";
- actionName = "save";
- };
- send = {
- protectedBy = "View";
- pageName = "UIxMailEditor";
- actionName = "send";
- };
- delete = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "delete";
- };
- deleteAttachment = {
- protectedBy = "View";
- actionClass = "UIxMailActions";
- actionName = "deleteAttachment";
- };
+ edit = {
+ protectedBy = "View";
+ pageName = "UIxMailEditor";
+ };
+ save = {
+ protectedBy = "View";
+ pageName = "UIxMailEditor";
+ actionName = "save";
+ };
+ send = {
+ protectedBy = "View";
+ pageName = "UIxMailEditor";
+ actionName = "send";
+ };
+ delete = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "delete";
+ };
+ deleteAttachment = {
+ protectedBy = "View";
+ actionClass = "UIxMailActions";
+ actionName = "deleteAttachment";
+ };
};
- };
+ };
- /* Sieve */
+ /* Sieve */
- /* SOGoSieveScriptsFolder = {
- slots = {
- toolbar = {
- protectedBy = "View";
- value = (
- (
- {
- link = "getMail";
- image = "tb-mail-getmail-flat-24x24.png";
- cssClass = "tbicon_getmail"; label = "Get Mail";
- },
- {
- link = "#"; // "compose"; // target = "_blank";
- onclick = "clickedNewFilter(this); return false";
- image = "tb-mail-write-flat-24x24.png";
- cssClass = "tbicon_compose"; label = "New Filter";
- },
- ),
- (
- { link = "#";
- cssClass = "tbicon_delete"; label = "Delete"; },
- ),
- );
- };
- };
- methods = {
- view = {
- protectedBy = "View";
- pageName = "UIxFilterList";
- };
- create = {
- protectedBy = "View";
- pageName = "UIxFilterList";
- actionName = "create";
- };
- };
- };
+// SOGoSieveScriptsFolder = {
+// slots = {
+// toolbar = {
+// protectedBy = "View";
+// value = (
+// (
+// {
+// link = "getMail";
+// image = "tb-mail-getmail-flat-24x24.png";
+// cssClass = "tbicon_getmail"; label = "Get Mail";
+// },
+// {
+// link = "#"; // "compose"; // target = "_blank";
+// onclick = "clickedNewFilter(this); return false";
+// image = "tb-mail-write-flat-24x24.png";
+// cssClass = "tbicon_compose"; label = "New Filter";
+// },
+// ),
+// (
+// { link = "#";
+// cssClass = "tbicon_delete"; label = "Delete"; },
+// ),
+// );
+// };
+// };
+// methods = {
+// view = {
+// protectedBy = "View";
+// pageName = "UIxFilterList";
+// };
+// create = {
+// protectedBy = "View";
+// pageName = "UIxFilterList";
+// actionName = "create";
+// };
+// };
+// };
- SOGoSieveScriptObject = {
- slots = {
- toolbar = {
- protectedBy = "View";
- value = (
- ( { link = "#";
- onclick = "clickedEditorSave(this);return false;";
- image = "tb-mail-file-flat-24x24.png";
- cssClass = "tbicon_save"; label = "Save"; },
- { link = "#";
- onclick = "clickedEditorDelete(this);return false;";
- image = "tb-mail-delete-flat-24x24.png";
- cssClass = "tbicon_delete"; label = "Delete"; },
- )
- );
- };
- };
- methods = {
- edit = {
- protectedBy = "View";
- pageName = "UIxSieveEditor";
- actionName = "edit";
- };
- save = {
- protectedBy = "View";
- pageName = "UIxSieveEditor";
- actionName = "save";
- };
- delete = {
- protectedBy = "View";
- pageName = "UIxSieveEditor";
- actionName = "delete";
- };
- };
- }; */
-};
+// SOGoSieveScriptObject = {
+// slots = {
+// toolbar = {
+// protectedBy = "View";
+// value = (
+// ( { link = "#";
+// onclick = "clickedEditorSave(this);return false;";
+// image = "tb-mail-file-flat-24x24.png";
+// cssClass = "tbicon_save"; label = "Save"; },
+// { link = "#";
+// onclick = "clickedEditorDelete(this);return false;";
+// image = "tb-mail-delete-flat-24x24.png";
+// cssClass = "tbicon_delete"; label = "Delete"; },
+// )
+// );
+// };
+// };
+// methods = {
+// edit = {
+// protectedBy = "View";
+// pageName = "UIxSieveEditor";
+// actionName = "edit";
+// };
+// save = {
+// protectedBy = "View";
+// pageName = "UIxSieveEditor";
+// actionName = "save";
+// };
+// delete = {
+// protectedBy = "View";
+// pageName = "UIxSieveEditor";
+// actionName = "delete";
+// };
+// }
+ };
}
+
/* this file is in UTF-8 format! */
-"Homepage" = "Homepage";
+"title" = "SOGo";
"Login:" = "Login:";
"Password:" = "Password:";
+
+"Connect" = "Connect";
/* this file is in UTF-8 format! */
-"Homepage" = "Accueil";
+"title" = "SOGo";
"Login:" = "Nom d'utilisateur :";
"Password:" = "Mot de passe :";
+
+"Connect" = "Connexion";
/* this file is in UTF-8 format! */
-"Homepage" = "Startseite";
+"title" = "SOGo";
-"Login:" = "Login:";
-"Password:" = "Password:";
+"Login:" = "Benutzername:";
+"Password:" = "Passwort:";
+
+"Connect" = "Verbinden";
#ifndef SOGOROOTPAGE_H
#define SOGOROOTPAGE_H
-#import <UI/Common/UIxPageFrame.h>
+#import <UI/SOGoUI/UIxComponent.h>
-@interface SOGoRootPage : UIxPageFrame
+@interface SOGoRootPage : UIxComponent
{
NSString *userName;
}
#import <NGObjWeb/WOCookie.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
+#import <NGExtensions/NGBase64Coding.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSObject+Logs.h>
return userName;
}
-/* actions */
+- (NSString *) connectURL
+{
+ return [NSString stringWithFormat: @"%@connect", [self applicationPath]];
+}
-- (id <WOActionResults>) defaultAction
+/* actions */
+- (id <WOActionResults>) connectAction
{
- WOResponse *r;
- NSString *login, *rhk;
+ WOResponse *response;
+ WOCookie *authCookie;
SOGoWebAuthenticator *auth;
- SOGoUser *user;
- SOGoUserFolder *home;
- WOApplication *base;
-
- /*
- Note: ctx.activeUser is NOT set here. Don't know why, so we retrieve
- the user from the authenticator.
- */
+ NSString *cookieValue, *cookieString;
+
+ auth = [[WOApplication application]
+ authenticatorInContext: context];
+ response = [context response];
+ cookieString = [NSString stringWithFormat: @"%@:%@",
+ [self queryParameterForKey: @"userName"],
+ [self queryParameterForKey: @"password"]];
+ cookieValue = [NSString stringWithFormat: @"basic%@",
+ [cookieString stringByEncodingBase64]];
+ authCookie = [WOCookie cookieWithName: [auth cookieNameInContext: context]
+ value: cookieValue];
+ [authCookie setPath: @"/"];
+ [response setStatus: 204];
+ [response addCookie: authCookie];
+
+ return response;
+}
+
+// - (id <WOActionResults>) defaultAction
+// {
+// WOResponse *r;
+// NSString *login, *rhk;
+// SOGoWebAuthenticator *auth;
+// SOGoUser *user;
+// SOGoUserFolder *home;
+// WOApplication *base;
+
+// /*
+// Note: ctx.activeUser is NOT set here. Don't know why, so we retrieve
+// the user from the authenticator.
+// */
- auth = [[self clientObject] authenticatorInContext: context];
- user = [auth userInContext: context];
- login = [user login];
+// auth = [[self clientObject] authenticatorInContext: context];
+// user = [auth userInContext: context];
+// login = [user login];
- if ([login isEqualToString:@"anonymous"]) {
- /* use root page for unauthenticated users */
- return self;
- }
+// if ([login isEqualToString:@"anonymous"]) {
+// /* use root page for unauthenticated users */
+// return self;
+// }
- /* check base */
+// /* check base */
- base = [self application];
- rhk = [[context request] requestHandlerKey];
- if (([rhk length] == 0) || ([base requestHandlerForKey:rhk] == nil)) {
- base = [base lookupName: @"so" inContext: context acquire: NO];
+// base = [self application];
+// rhk = [[context request] requestHandlerKey];
+// if (([rhk length] == 0) || ([base requestHandlerForKey:rhk] == nil)) {
+// base = [base lookupName: @"so" inContext: context acquire: NO];
- if (![base isNotNull] || [base isKindOfClass:[NSException class]]) {
- /* use root page if home could not be found */
- [self errorWithFormat:@"Did not find 'so' request handler!"];
- return self;
- }
- }
+// if (![base isNotNull] || [base isKindOfClass:[NSException class]]) {
+// /* use root page if home could not be found */
+// [self errorWithFormat:@"Did not find 'so' request handler!"];
+// return self;
+// }
+// }
- /* lookup home-page */
+// /* lookup home-page */
- home = [base lookupName: login inContext: context acquire: NO];
- if (![home isNotNull] || [home isKindOfClass:[NSException class]]) {
- /* use root page if home could not be found */
- return self;
- }
+// home = [base lookupName: login inContext: context acquire: NO];
+// if (![home isNotNull] || [home isKindOfClass:[NSException class]]) {
+// /* use root page if home could not be found */
+// return self;
+// }
- /* redirect to home-page */
+// /* redirect to home-page */
- r = [context response];
- [r setStatus: 302 /* moved */];
- [r setHeader: [home baseURLInContext: context]
- forKey: @"location"];
+// r = [context response];
+// [r setStatus: 302 /* moved */];
+// [r setHeader: [home baseURLInContext: context]
+// forKey: @"location"];
- return r;
-}
+// return r;
+// }
/* response generation */
-- (void) appendToResponse: (WOResponse *) response
- inContext: (WOContext *) ctx
-{
- NSString *rhk;
+// - (void) appendToResponse: (WOResponse *) response
+// inContext: (WOContext *) ctx
+// {
+// NSString *rhk;
- // TODO: we might also want to look into the HTTP basic-auth to redirect to
- // the login URL!
+// // TODO: we might also want to look into the HTTP basic-auth to redirect to
+// // the login URL!
- rhk = [[ctx request] requestHandlerKey];
- if ([rhk length] == 0
- || [[self application] requestHandlerForKey: rhk] == nil)
- {
- /* a small hack to redirect to a valid URL */
- NSString *url;
+// rhk = [[ctx request] requestHandlerKey];
+// if ([rhk length] == 0
+// || [[self application] requestHandlerForKey: rhk] == nil)
+// {
+// /* a small hack to redirect to a valid URL */
+// NSString *url;
- url = [ctx urlWithRequestHandlerKey: @"so" path: @"/" queryString: nil];
- [response setStatus: 302 /* moved */];
- [response setHeader: url forKey: @"location"];
- [self logWithFormat: @"URL: %@", url];
- return;
- }
-
- [response setHeader: @"text/html" forKey: @"content-type"];
- [super appendToResponse: response inContext: ctx];
+// url = [ctx urlWithRequestHandlerKey: @"so" path: @"/" queryString: nil];
+// [response setStatus: 302 /* moved */];
+// [response setHeader: url forKey: @"location"];
+// [self logWithFormat: @"URL: %@", url];
+// return;
+// }
+
+// [response setHeader: @"text/html" forKey: @"content-type"];
+// [super appendToResponse: response inContext: ctx];
+// }
+
+- (BOOL) isPublicInContext: (WOContext *) localContext
+{
+ return YES;
}
@end /* SOGoRootPage */
- (id <WOActionResults>) logoffAction
{
WOResponse *response;
- NSEnumerator *cookies;
WOCookie *cookie;
SOGoWebAuthenticator *auth;
id container;
+ NSCalendarDate *date;
container = [[self clientObject] container];
[response setStatus: 302];
[response setHeader: [container baseURLInContext: context]
forKey: @"location"];
- cookies = [[response cookies] objectEnumerator];
auth = [[self clientObject] authenticatorInContext: context];
cookie = [WOCookie cookieWithName: [auth cookieNameInContext: context]
- value: @"logoff"];
+ value: @"discard"];
[cookie setPath: @"/"];
+ date = [NSCalendarDate calendarDate];
+ [cookie setExpires: [date yesterday]];
[response addCookie: cookie];
return response;
classes = {
SOGoRootPage = {
superclass = "SoComponent";
- protectedBy = "View";
+ protectedBy = "<public>";
defaultRoles = {
"View" = ( "Authenticated" );
};
SOGo = { // TODO: move decls to class
methods = {
view = {
- protectedBy = "View";
+ protectedBy = "<public>";
pageName = "SOGoRootPage";
};
connect = {
- protectedBy = "View";
- pageName = "SOGoRootPage";
+ protectedBy = "<public>";
+ pageName = "SOGoRootPage";
actionName = "connect";
};
GET = { // more or less a hack, see README of dbd
- protectedBy = "View";
+ protectedBy = "<public>";
pageName = "SOGoRootPage";
};
};
SOGoObject *currentClient, *parent;
BOOL found;
Class objectClass, groupFolderClass, userFolderClass;
- WOContext *ctx;
-
- groupFolderClass = [SOGoCustomGroupFolder class];
- userFolderClass = [SOGoUserFolder class];
currentClient = [self clientObject];
- objectClass = [currentClient class];
- found = (objectClass == groupFolderClass || objectClass == userFolderClass);
- while (!found && currentClient)
+ if (currentClient
+ && [currentClient isKindOfClass: [SOGoObject class]])
{
- parent = [currentClient container];
- objectClass = [parent class];
- if (objectClass == groupFolderClass
- || objectClass == userFolderClass)
- found = YES;
- else
- currentClient = parent;
+ groupFolderClass = [SOGoCustomGroupFolder class];
+ userFolderClass = [SOGoUserFolder class];
+
+ objectClass = [currentClient class];
+ found = (objectClass == groupFolderClass || objectClass == userFolderClass);
+ while (!found && currentClient)
+ {
+ parent = [currentClient container];
+ objectClass = [parent class];
+ if (objectClass == groupFolderClass
+ || objectClass == userFolderClass)
+ found = YES;
+ else
+ currentClient = parent;
+ }
}
+ else
+ currentClient = [WOApplication application];
- ctx = context;
-
- return [[currentClient baseURLInContext:ctx] hostlessURL];
+ return [[currentClient baseURLInContext: context] hostlessURL];
}
- (NSString *) resourcesPath
currentAttendee = [attendees nextObject];
while (currentAttendee)
{
- NSLog (@"currentCN: %@", [currentAttendee cn]);
[names appendFormat: @"%@,", [currentAttendee cn]];
[emails appendFormat: @"%@,", [currentAttendee rfc822Email]];
currentAttendee = [attendees nextObject];
</label>
</td>
</tr>
+ <tr>
+ <td>
+ <label><var:string label:value="Screen Name:"
+ />
+ <input type="text" class="textField" name="screenName"
+ id="screenName" var:value="snapshot.screenName" />
+ </label>
+ </td>
+ </tr>
<tr>
<td id="htmlMailFormat">
<label><var:string
</label>
</td>
</tr>
- <tr>
- <td>
- <label><var:string label:value="Screen Name:"
- />
- <input type="text" class="textField" name="screenName"
- id="screenName" var:value="snapshot.screenName" />
- </label>
- </td>
- </tr>
- </table>
+ </table>
<span class="caption"><var:string label:value="Phones" /></span>
<table>
<tr>
<?xml version="1.0" standalone="yes"?>
-<div
+<!DOCTYPE container>
+<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
- xmlns:label="OGo:label"
- class="mailer_htmlcontent SOGoHTMLMail-CSS-Delimiter"
-><var:string value="flatContentAsString" const:escapeHTML="NO" /></div>
+ xmlns:label="OGo:label">
+ <var:string value="cssContent" const:escapeHTML="NO" />
+ <div class="SOGoHTMLMail-CSS-Delimiter mailer_htmlcontent"
+ ><var:string value="flatContentAsString" const:escapeHTML="NO" /></div>
+</container>
<?xml version="1.0" standalone="yes"?>
-<!DOCTYPE container>
-<container
+<!DOCTYPE var:component>
+<var:component
+ className="UIxPageFrame"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label"
><var:string var:value="doctype" const:escapeHTML="NO" />
- <html>
- <head>
- <title>
- <var:string value="title"/>
- </title>
- <meta name="hideFrame" var:content="hideFrame" />
- <meta name="description" content="SOGo Web Interface" />
- <meta name="author" content="SKYRIX Software AG/Inverse groupe conseil" />
- <meta name="robots" content="stop" />
- <meta name="build" var:content="buildDate" />
- <link href="mailto:support@inverse.ca" rev="made" />
- <link rel="shortcut icon" rsrc:href="lori_16x16.ico" type="image/x-icon" />
- <link type="text/css" rel="stylesheet" rsrc:href="generic.css" />
- <link type="text/css" rel="stylesheet" rsrc:href="dtree.css" />
- <var:if-ie
- ><link type="text/css" rel="stylesheet" rsrc:href="iefixes.css"
- /></var:if-ie>
- <link type="text/css" rel="stylesheet" rsrc:href="SOGoRootPage.css" />
- </head>
-
- <body class="loginPage">
- <script type="text/javascript">
- var ResourcesURL = '/SOGo.woa/WebServerResources';
- var ApplicationBaseURL = '<var:string value="applicationPath" />';
- </script>
-
- <script type="text/javascript" rsrc:src="_IEtoW3C.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="events.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="prototype.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="JavascriptAPIExtensions.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="HTMLElement.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="HTMLInputElement.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="HTMLTableElement.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="HTMLUListElement.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="generic.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="SOGoDragAndDrop.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="SOGoDragHandles.js"><!-- space required --></script>
- <script type="text/javascript" rsrc:src="SOGoRootPage.js"><!-- space required --></script>
- <!-- var:js-stringtable
- var:framework="productFrameworkName"
- const:identifier="labels" -->
- <!-- var:js-stringtable
- const:identifier="clabels" -->
- <div class="pageContent">
- <form href="view">
- <div id="loginScreen">
- <img rsrc:src="lori-login.jpg"/><br/><br/>
- <label><var:string label:value="Login:"/><br/>
- <input class="textField" id="userName" name="userName"
- type="text" var:value="userName" /></label><br/>
- <label><var:string label:value="Password:"/><br/>
- <input class="textField" id="password"
- name="password" type="password" var:value="password" /><br/></label>
- <div id="loginButton">
- <input class="button" id="submit" name="submit" type="submit" label:value="Connect" />
- </div>
- </div>
- </form>
+ <form id="connectForm" var:href="connectURL">
+ <div id="loginScreen">
+ <img rsrc:src="lori-login.jpg"/><br/><br/>
+ <label><var:string label:value="Login:"/><br/>
+ <input class="textField" id="userName" name="userName"
+ type="text" var:value="userName" /></label><br/>
+ <label><var:string label:value="Password:"/><br/>
+ <input class="textField" id="password"
+ name="password" type="password" var:value="password" /><br/></label>
+ <div id="loginButton">
+ <input class="button" id="submit" name="submit" type="submit" label:value="Connect" />
</div>
- <noscript>
- <div class="javascriptPopupBackground">
- </div>
- <div class="javascriptMessagePseudoWindow noJavascriptErrorMessage">
- <var:string label:value="noJavascriptError"
- /><br /><br
- /><a class="button" var:href="page.context.uri"
- ><var:string label:value="noJavascriptRetry"
- /></a>
- </div>
- </noscript>
- </body>
- </html>
-</container>
+ </div>
+ </form>
+ <img id="preparedAnimation" rsrc:src="busy.gif"/>
+</var:component>
<body var:class="bodyClasses">
<script type="text/javascript">
- var UserFolderURL = '<var:string value="userFolderPath" />';
var ApplicationBaseURL = '<var:string value="applicationPath" />';
var ResourcesURL = '/SOGo.woa/WebServerResources';
- var UserLogin = '<var:string value="shortUserNameForDisplay" />';
+ <var:if condition="shortUserNameForDisplay" const:value="anonymous"
+ const:negate="YES"
+ >var UserFolderURL = '<var:string value="userFolderPath" />';
+ var UserLogin = '<var:string value="shortUserNameForDisplay" />';</var:if>
</script>
-
- <script type="text/javascript" rsrc:src="_IEtoW3C.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="events.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="prototype.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="JavascriptAPIExtensions.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="generic.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="SOGoDragAndDrop.js"><!-- space required --></script>
<script type="text/javascript" rsrc:src="SOGoDragHandles.js"><!-- space required --></script>
- <var:if condition="hasProductSpecificJavaScript"
- ><script type="text/javascript" var:src="productJavaScriptURL"><!-- space required --></script
- ></var:if>
- <var:if condition="hasPageSpecificJavaScript"
- ><script type="text/javascript" var:src="pageJavaScriptURL"> <!-- space required --></script
- ></var:if>
+ <var:if condition="hasProductSpecificJavaScript"><script type="text/javascript"
+ var:src="productJavaScriptURL"><!-- space required --></script></var:if>
+ <var:if condition="hasPageSpecificJavaScript"><script type="text/javascript"
+ var:src="pageJavaScriptURL"><!-- space required --></script></var:if>
<var:js-stringtable
var:framework="productFrameworkName"
const:identifier="labels" />
<var:js-stringtable
const:identifier="clabels" />
- <var:if condition="isPopup" const:negate="YES"
- ><var:if condition="context.isUIxDebugEnabled"
- ><div id="logConsole"><!-- space --></div></var:if>
-
- <div id="linkBanner" class="linkbanner">
- <a id="logoff" var:href="logoffPath"
- ><var:string label:value="Logoff" /></a>
- <a var:href="relativeCalendarPath"
- ><var:string label:value="Calendar" /></a> |
- <a 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:string label:value="Preferences" /></a>
- <var:if condition="context.isUIxDebugEnabled"
- >| <a href="#"><var:string
- label:value="Log Console (dev.)" /></a
- ></var:if>
- </div>
- </var:if
-
- ><var:component className="UIxToolbar" var:toolbar="toolbar"
- />
-
+ <var:if condition="shortUserNameForDisplay" const:value="anonymous"
+ const:negate="YES"
+ ><var:if condition="isPopup" const:negate="YES"
+ ><var:if condition="context.isUIxDebugEnabled"
+ ><div id="logConsole"><!-- space --></div></var:if>
+ <div id="linkBanner" class="linkbanner">
+ <a id="logoff" var:href="logoffPath"
+ ><var:string label:value="Logoff" /></a>
+ <a var:href="relativeCalendarPath"
+ ><var:string label:value="Calendar" /></a> |
+ <a 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:string label:value="Preferences" /></a>
+ <var:if condition="context.isUIxDebugEnabled"
+ >| <a href="#"><var:string
+ label:value="Log Console (dev.)" /></a
+ ></var:if>
+ </div>
+ </var:if
+ ><var:component className="UIxToolbar" var:toolbar="toolbar"
+ />
+ </var:if>
+
<div class="pageContent"
><var:component-content
/></div>
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
- var input = this._base64_utf8_encode();
+ var input = this.utf8encode();
while (i < input.length) {
chr1 = input.charCodeAt(i++);
}
}
- return output._base64_utf8_decode();
+ return output.utf8decode();
};
-String.prototype._base64_utf8_encode = function() {
+String.prototype.utf8encode = function() {
var string = this.replace(/\r\n/g,"\n");
var utftext = "";
return utftext;
};
-String.prototype._base64_utf8_decode = function() {
+String.prototype.utf8decode = function() {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
if (http) {
// TODO: add parameter to signal that we are only interested in OK
- http.open("POST", url + "&jsonly=1", false /* not async */);
+ http.open("POST", url, false /* not async */);
http.send("");
if (http.status != 200) {
// TODO: refresh page?
/* send AJAX request (synchronously) */
var messageId = currentMailbox + "/" + rowId;
- url = ApplicationBaseURL + messageId + "/trash?jsonly=1";
+ url = ApplicationBaseURL + messageId + "/trash";
http = createHTTPClient();
http.open("POST", url, false /* not async */);
http.send("");
- if (http.status != 200) { /* request failed */
+ if (!isHttpStatus204(http.status)) { /* request failed */
failCount++;
http = null;
continue;
var messageId = currentMailbox + "/" + rowIds[i];
url = (ApplicationBaseURL + messageId
- + "/move?jsonly=1&tofolder=" + folder);
+ + "/move?tofolder=" + folder);
http = createHTTPClient();
http.open("GET", url, false /* not async */);
http.send("");
mailboxTree.add(0, -1, '');
mailboxTree.pendingRequests = mailAccounts.length;
+ activeAjaxRequests += mailAccounts.length;
for (var i = 0; i < mailAccounts.length; i++) {
var url = ApplicationBaseURL + "/" + mailAccounts[i] + "/mailboxes";
triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
function onLoadMailboxesCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
+ checkAjaxRequestsState();
var newAccount = buildMailboxes(http.callbackData,
http.responseText);
accounts[http.callbackData] = newAccount;
mailboxTree.addMailAccount(newAccount);
mailboxTree.pendingRequests--;
+ activeAjaxRequests--;
if (!mailboxTree.pendingRequests) {
updateMailboxTreeInPage();
updateMailboxMenus();
+ checkAjaxRequestsState();
}
}
function onMenuEmptyTrash(event) {
var folderID = document.menuTarget.getAttribute("dataname");
var urlstr = URLForFolderID(folderID) + "/emptyTrash";
-
triggerAjaxRequest(urlstr, folderRefreshCallback, folderID);
+
+ if (folderID == currentMailbox) {
+ var div = $('messageContent');
+ for (var i = div.childNodes.length - 1; i > -1; i--)
+ div.removeChild(div.childNodes[i]);
+ }
+ var msgID = currentMessages[folderID];
+ if (msgID)
+ deleteCachedMessage(folderID + "/" + msgID);
}
function folderOperationCallback(http) {
BODY
{ background-color: #999; }
+IMG#preparedAnimation
+{
+ width: 0px;
+ height: 0px;
+}
+
DIV#loginScreen
{
background-color: #d4d0c8;
margin-top: 5em;
padding: 10px;
border: 2px solid transparent;
- width: 158px;
- height: 250px;
+ width: 197px;
+ height: 300px;
-moz-border-top-colors: #efebe7 #fff;
-moz-border-left-colors: #efebe7 #fff;
-moz-border-right-colors: #000 #9c9a94 transparent;
}
DIV#loginScreen IMG
-{ border: 1px solid #999; }
+{ border: 0px;
+ margin: 0px;
+ padding: 0px;
+ height: 192px;
+ width: 192px; }
-DIV#loginScreen INPUT
-{ width: 100%; }
+DIV#loginScreen INPUT.textField
+{ width: 187px; }
DIV#loginButton
{ text-align: right; }
DIV#loginButton IMG#progressIndicator
{ float: left;
+ width: 16px;
+ height: 16px;
border: 0px none;
margin-top: 5px;
margin-left: 5px; }
function initLogin() {
+ var date = new Date();
+ date.setTime(date.getTime() - 86400000);
+ document.cookie = ("0xHIGHFLYxSOGo-0.9=discard; path=/"
+ + "; expires=" + date.toGMTString());
var submit = $("submit");
+ Event.observe(submit, "click", onLoginClick);
+
var userName = $("userName");
userName.focus();
- Event.observe(submit, "click", onLoginClick);
+
+ var image = $("preparedAnimation");
+ image.parentNode.removeChild(image);
}
function onLoginClick(event) {
startAnimation($("loginButton"), $("submit"));
- var loginString = $("userName").value + ":" + $("password").value;
- document.cookie = ("0xHIGHFLYxSOGo-0.9 = basic" + loginString.base64encode()
- + "; path=/");
+ var userName = $("userName").value;
+ var password = $("password").value;
+
+ if (userName.length > 0) {
+ var url = ($("connectForm").getAttribute("action")
+ + "?userName=" + userName
+ + "&password=" + password);
+ document.cookie = "";
+ triggerAjaxRequest(url, onLoginCallback);
+ }
+
+ preventDefault(event);
+}
+
+function onLoginCallback(http) {
+ if (http.readyState == 4) {
+ if (http.status == 204) {
+ window.location.href = ApplicationBaseURL + $("userName").value;
+ }
+ }
}
addEvent(window, 'load', initLogin);
}
function onLoadHandler(event) {
- if (!document.body.hasClassName("loginPage")) {
- loadPreferences();
- }
- queryParameters = parseQueryParameters('' + window.location);
- if (!$(document.body).hasClassName("popup")) {
- initLogConsole();
- }
- initCriteria();
- configureSearchField();
- initMenus();
- initTabs();
- configureDragHandles();
- configureSortableTableHeaders();
- configureLinkBanner();
- var progressImage = $("progressIndicator");
- if (progressImage)
- progressImage.parentNode.removeChild(progressImage);
- Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
+ if (typeof UserLogin != "undefined")
+ loadPreferences();
+ queryParameters = parseQueryParameters('' + window.location);
+ if (!$(document.body).hasClassName("popup")) {
+ initLogConsole();
+ }
+ initCriteria();
+ configureSearchField();
+ initMenus();
+ initTabs();
+ configureDragHandles();
+ configureSortableTableHeaders();
+ configureLinkBanner();
+ var progressImage = $("progressIndicator");
+ if (progressImage)
+ progressImage.parentNode.removeChild(progressImage);
+ Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
}
function onBodyClickContextMenu(event) {