2006-06-15 21:34:10 +02:00
|
|
|
/*
|
2016-05-11 14:55:05 +02:00
|
|
|
Copyright (C) 2007-2016 Inverse inc.
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2011-04-25 12:31:08 +02:00
|
|
|
This file is part of SOGo
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2011-04-25 12:31:08 +02:00
|
|
|
SOGo is free software; you can redistribute it and/or modify it under
|
2006-06-15 21:34:10 +02:00
|
|
|
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.
|
|
|
|
|
2011-04-25 12:31:08 +02:00
|
|
|
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
2006-06-15 21:34:10 +02:00
|
|
|
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 OGo; see the file COPYING. If not, write to the
|
|
|
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2007-04-11 21:08:58 +02:00
|
|
|
#import <Foundation/NSKeyValueCoding.h>
|
2012-09-22 03:48:39 +02:00
|
|
|
#import <Foundation/NSUserDefaults.h> /* for locale strings */
|
2016-02-25 03:30:33 +01:00
|
|
|
#import <Foundation/NSValue.h>
|
2007-11-06 22:24:22 +01:00
|
|
|
|
2007-04-11 21:08:58 +02:00
|
|
|
#import <NGObjWeb/SoObjects.h>
|
2007-11-06 22:24:22 +01:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
2007-04-11 21:08:58 +02:00
|
|
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
#import <NGExtensions/NSString+misc.h>
|
|
|
|
#import <NGExtensions/NSURL+misc.h>
|
2007-11-06 22:24:22 +01:00
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/NSCalendarDate+SOGo.h>
|
2015-03-26 13:52:48 +01:00
|
|
|
#import <SOGo/NSDictionary+Utilities.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/NSObject+Utilities.h>
|
2016-04-26 17:06:44 +02:00
|
|
|
#import <SOGo/NSString+Crypto.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/NSString+Utilities.h>
|
2010-02-18 23:08:48 +01:00
|
|
|
#import <SOGo/SOGoBuild.h>
|
2016-04-26 17:06:44 +02:00
|
|
|
#import <SOGo/SOGoSession.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/SOGoSystemDefaults.h>
|
|
|
|
#import <SOGo/SOGoUser.h>
|
2012-10-22 16:09:13 +02:00
|
|
|
#import <SOGo/SOGoUserFolder.h>
|
2016-04-26 17:06:44 +02:00
|
|
|
#import <SOGo/SOGoWebAuthenticator.h>
|
2014-08-06 22:01:05 +02:00
|
|
|
#import <SOGo/WOContext+SOGo.h>
|
2012-10-22 16:09:13 +02:00
|
|
|
#import <SOGo/WOResourceManager+SOGo.h>
|
2006-10-12 18:44:40 +02:00
|
|
|
|
2007-04-11 21:08:58 +02:00
|
|
|
#import "UIxJSClose.h"
|
2006-10-03 18:16:22 +02:00
|
|
|
|
2007-11-06 22:24:22 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@interface UIxComponent (PrivateAPI)
|
|
|
|
- (void)_parseQueryString:(NSString *)_s;
|
|
|
|
- (NSMutableDictionary *)_queryParameters;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation UIxComponent
|
|
|
|
|
2016-02-02 02:54:37 +01:00
|
|
|
static NSMutableArray *amPmLabelKeys = nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
static NSMutableArray *dayLabelKeys = nil;
|
|
|
|
static NSMutableArray *abbrDayLabelKeys = nil;
|
|
|
|
static NSMutableArray *monthLabelKeys = nil;
|
|
|
|
static NSMutableArray *abbrMonthLabelKeys = nil;
|
2012-09-22 03:48:39 +02:00
|
|
|
static SoProduct *commonProduct = nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
+ (void)initialize {
|
|
|
|
if (dayLabelKeys == nil) {
|
2016-02-02 02:54:37 +01:00
|
|
|
amPmLabelKeys = [[NSMutableArray alloc] initWithCapacity:2];
|
|
|
|
[amPmLabelKeys addObject:@"AM"];
|
|
|
|
[amPmLabelKeys addObject:@"PM"];
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
dayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
|
|
|
|
[dayLabelKeys addObject:@"Sunday"];
|
|
|
|
[dayLabelKeys addObject:@"Monday"];
|
|
|
|
[dayLabelKeys addObject:@"Tuesday"];
|
|
|
|
[dayLabelKeys addObject:@"Wednesday"];
|
|
|
|
[dayLabelKeys addObject:@"Thursday"];
|
|
|
|
[dayLabelKeys addObject:@"Friday"];
|
|
|
|
[dayLabelKeys addObject:@"Saturday"];
|
|
|
|
|
|
|
|
abbrDayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Sunday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Monday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Tuesday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Wednesday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Thursday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Friday"];
|
|
|
|
[abbrDayLabelKeys addObject:@"a2_Saturday"];
|
|
|
|
|
|
|
|
monthLabelKeys = [[NSMutableArray alloc] initWithCapacity:12];
|
|
|
|
[monthLabelKeys addObject:@"January"];
|
|
|
|
[monthLabelKeys addObject:@"February"];
|
|
|
|
[monthLabelKeys addObject:@"March"];
|
|
|
|
[monthLabelKeys addObject:@"April"];
|
|
|
|
[monthLabelKeys addObject:@"May"];
|
|
|
|
[monthLabelKeys addObject:@"June"];
|
|
|
|
[monthLabelKeys addObject:@"July"];
|
|
|
|
[monthLabelKeys addObject:@"August"];
|
|
|
|
[monthLabelKeys addObject:@"September"];
|
|
|
|
[monthLabelKeys addObject:@"October"];
|
|
|
|
[monthLabelKeys addObject:@"November"];
|
|
|
|
[monthLabelKeys addObject:@"December"];
|
|
|
|
|
|
|
|
abbrMonthLabelKeys = [[NSMutableArray alloc] initWithCapacity:12];
|
2012-09-22 03:48:39 +02:00
|
|
|
[abbrMonthLabelKeys addObject:@"Jan"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Feb"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Mar"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Apr"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"May"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Jun"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Jul"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Aug"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Sep"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Oct"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Nov"];
|
|
|
|
[abbrMonthLabelKeys addObject:@"Dec"];
|
|
|
|
|
|
|
|
// @see commonLabelForKey:
|
|
|
|
commonProduct = [[SoProduct alloc] initWithBundle:
|
|
|
|
[NSBundle bundleForClass: NSClassFromString(@"CommonUIProduct")]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 02:54:37 +01:00
|
|
|
+ (NSArray *) amPmLabelKeys
|
|
|
|
{
|
|
|
|
return (NSArray *) amPmLabelKeys;
|
|
|
|
}
|
|
|
|
|
2012-09-22 03:48:39 +02:00
|
|
|
+ (NSArray *) abbrDayLabelKeys
|
|
|
|
{
|
|
|
|
return (NSArray *) abbrDayLabelKeys;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) monthLabelKeys
|
|
|
|
{
|
|
|
|
return (NSArray *) monthLabelKeys;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *) abbrMonthLabelKeys
|
|
|
|
{
|
|
|
|
return (NSArray *) abbrMonthLabelKeys;
|
|
|
|
}
|
|
|
|
|
2006-09-05 16:53:38 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
NSString *language;
|
|
|
|
|
2006-09-05 16:53:38 +02:00
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
2006-09-05 22:13:16 +02:00
|
|
|
_selectedDate = nil;
|
2008-09-02 04:53:34 +02:00
|
|
|
queryParameters = nil;
|
2012-09-22 03:48:39 +02:00
|
|
|
ASSIGN (userDefaults, [[context activeUser] userDefaults]);
|
2012-11-01 15:27:27 +01:00
|
|
|
if (!userDefaults)
|
|
|
|
ASSIGN (userDefaults, [SOGoSystemDefaults sharedSystemDefaults]);
|
2012-09-22 03:48:39 +02:00
|
|
|
language = [userDefaults language];
|
2014-08-06 22:01:05 +02:00
|
|
|
ASSIGN (languages, [context resourceLookupLanguages]);
|
2012-10-22 16:09:13 +02:00
|
|
|
ASSIGN (locale,
|
|
|
|
[[self resourceManager] localeForLanguageNamed: language]);
|
2006-09-05 16:53:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
2007-06-27 23:25:40 +02:00
|
|
|
[queryParameters release];
|
|
|
|
[_selectedDate release];
|
2012-09-22 03:48:39 +02:00
|
|
|
[locale release];
|
|
|
|
[userDefaults release];
|
2006-06-15 21:34:10 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* query parameters */
|
|
|
|
|
2006-09-19 23:09:57 +02:00
|
|
|
- (void) _parseQueryString: (NSString *) _s
|
2006-09-05 22:41:05 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSEnumerator *e;
|
2018-02-06 17:04:21 +01:00
|
|
|
NSMutableString *urlEncodedValue;
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *part;
|
2006-09-05 22:41:05 +02:00
|
|
|
NSRange r;
|
|
|
|
NSString *key, *value;
|
2006-07-11 19:43:58 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
e = [[_s componentsSeparatedByString:@"&"] objectEnumerator];
|
2009-06-04 17:08:03 +02:00
|
|
|
while ((part = [e nextObject]))
|
2006-09-05 22:41:05 +02:00
|
|
|
{
|
|
|
|
r = [part rangeOfString:@"="];
|
|
|
|
if (r.length == 0)
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* missing value of query parameter */
|
2009-06-04 17:08:03 +02:00
|
|
|
key = [part stringByUnescapingURL];
|
2006-09-05 22:41:05 +02:00
|
|
|
value = @"1";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-06-04 17:08:03 +02:00
|
|
|
key = [[part substringToIndex:r.location] stringByUnescapingURL];
|
2018-02-06 17:04:21 +01:00
|
|
|
urlEncodedValue = [NSMutableString stringWithString: [part substringFromIndex:(r.location + r.length)]];
|
|
|
|
[urlEncodedValue replaceString: @"+" withString: @" "];
|
|
|
|
value = [urlEncodedValue stringByUnescapingURL];
|
2006-09-05 22:41:05 +02:00
|
|
|
}
|
2009-06-04 17:08:03 +02:00
|
|
|
if (key && value)
|
|
|
|
[queryParameters setObject:value forKey:key];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
}
|
2006-09-05 22:41:05 +02:00
|
|
|
|
|
|
|
- (void) addKeepAliveFormValuesToQueryParameters
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) queryParameterForKey: (NSString *) _key
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self _queryParameters] objectForKey:_key];
|
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (void) setQueryParameter: (NSString *) _param
|
|
|
|
forKey: (NSString *) _key
|
|
|
|
{
|
|
|
|
if (_key)
|
|
|
|
{
|
|
|
|
if (_param)
|
|
|
|
[[self _queryParameters] setObject: _param forKey: _key];
|
|
|
|
else
|
|
|
|
[[self _queryParameters] removeObjectForKey: _key];
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSMutableDictionary *) _queryParameters
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: this code is weird, should use WORequest methods for parsing
|
|
|
|
WORequest *req;
|
|
|
|
NSString *uri;
|
|
|
|
NSRange r;
|
2006-09-05 22:41:05 +02:00
|
|
|
NSString *qs;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-06-27 23:25:40 +02:00
|
|
|
if (queryParameters)
|
|
|
|
return queryParameters;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-06-27 23:25:40 +02:00
|
|
|
queryParameters = [[NSMutableDictionary alloc] initWithCapacity:8];
|
2006-07-11 19:43:58 +02:00
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
req = [context request];
|
2006-06-15 21:34:10 +02:00
|
|
|
uri = [req uri];
|
|
|
|
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
|
2006-09-05 22:41:05 +02:00
|
|
|
if (r.length > 0)
|
|
|
|
{
|
|
|
|
qs = [uri substringFromIndex:NSMaxRange(r)];
|
|
|
|
[self _parseQueryString:qs];
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/* add form values */
|
|
|
|
[self addKeepAliveFormValuesToQueryParameters];
|
|
|
|
|
2007-06-27 23:25:40 +02:00
|
|
|
return queryParameters;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSDictionary *) queryParameters
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self _queryParameters];
|
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSDictionary *) queryParametersBySettingSelectedDate: (NSCalendarDate *) _date
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSMutableDictionary *qp;
|
|
|
|
|
|
|
|
qp = [[self queryParameters] mutableCopy];
|
|
|
|
[self setSelectedDateQueryParameter:_date inDictionary:qp];
|
|
|
|
return [qp autorelease];
|
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (void) setSelectedDateQueryParameter: (NSCalendarDate *) _newDate
|
|
|
|
inDictionary: (NSMutableDictionary *) _qp
|
2006-06-15 21:34:10 +02:00
|
|
|
{
|
2008-11-04 20:55:50 +01:00
|
|
|
NSString *day;
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
if (_newDate)
|
2008-11-04 20:55:50 +01:00
|
|
|
{
|
|
|
|
day = [self dateStringForDate: _newDate];
|
|
|
|
[_qp setObject: day forKey: @"day"];
|
|
|
|
[_qp setObject: [day substringToIndex: 6] forKey: @"month"];
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
else
|
2008-11-04 20:55:50 +01:00
|
|
|
{
|
|
|
|
[_qp removeObjectForKey:@"day"];
|
|
|
|
[_qp removeObjectForKey:@"month"];
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) completeHrefForMethod: (NSString *) _method
|
|
|
|
{
|
|
|
|
WOContext *ctx;
|
2006-06-15 21:34:10 +02:00
|
|
|
NSDictionary *qp;
|
2006-09-05 22:41:05 +02:00
|
|
|
NSString *qs, *qps, *href;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
qp = [self queryParameters];
|
2006-09-05 22:41:05 +02:00
|
|
|
if ([qp count] > 0)
|
|
|
|
{
|
2007-08-23 18:12:16 +02:00
|
|
|
ctx = context;
|
2006-09-05 22:41:05 +02:00
|
|
|
qps = [ctx queryPathSeparator];
|
|
|
|
[ctx setQueryPathSeparator: @"&"];
|
|
|
|
qs = [ctx queryStringFromDictionary: qp];
|
|
|
|
[ctx setQueryPathSeparator: qps];
|
|
|
|
href = [_method stringByAppendingFormat:@"?%@", qs];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
href = _method;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
return href;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) ownMethodName
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *uri;
|
|
|
|
NSRange r;
|
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
uri = [[context request] uri];
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/* first: cut off query parameters */
|
|
|
|
|
|
|
|
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
|
|
|
|
if (r.length > 0)
|
|
|
|
uri = [uri substringToIndex:r.location];
|
|
|
|
|
|
|
|
/* next: strip trailing slash */
|
2007-03-18 16:13:57 +01:00
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
if ([uri hasSuffix: @"/"])
|
|
|
|
uri = [uri substringToIndex: ([uri length] - 1)];
|
|
|
|
r = [uri rangeOfString:@"/" options: NSBackwardsSearch];
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/* then: cut of last path component */
|
|
|
|
|
|
|
|
if (r.length == 0) // no slash? are we at root?
|
|
|
|
return @"/";
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
return [uri substringFromIndex: (r.location + 1)];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-09-07 16:13:03 +02:00
|
|
|
- (NSString *) userFolderPath
|
2006-07-29 00:59:11 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
WOContext *ctx;
|
2006-09-07 16:13:03 +02:00
|
|
|
NSEnumerator *objects;
|
|
|
|
SOGoObject *currentObject;
|
|
|
|
BOOL found;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
ctx = context;
|
2006-09-07 16:13:03 +02:00
|
|
|
objects = [[ctx objectTraversalStack] objectEnumerator];
|
|
|
|
currentObject = [objects nextObject];
|
|
|
|
found = NO;
|
|
|
|
while (currentObject
|
|
|
|
&& !found)
|
|
|
|
if ([currentObject isKindOfClass: [SOGoUserFolder class]])
|
|
|
|
found = YES;
|
|
|
|
else
|
|
|
|
currentObject = [objects nextObject];
|
|
|
|
|
2007-02-09 17:53:05 +01:00
|
|
|
return [[currentObject baseURLInContext:ctx] hostlessURL];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) applicationPath
|
2009-11-10 22:39:40 +01:00
|
|
|
{
|
|
|
|
NSString *appName;
|
|
|
|
|
|
|
|
appName = [[context request] applicationName];
|
|
|
|
|
|
|
|
return [NSString stringWithFormat: @"/%@", appName];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) modulePath
|
2006-07-29 00:59:11 +02:00
|
|
|
{
|
2015-09-19 02:30:35 +02:00
|
|
|
if ([[self parent] respondsToSelector: @selector(modulePath)])
|
2006-09-07 00:25:46 +02:00
|
|
|
{
|
2015-09-21 14:59:36 +02:00
|
|
|
NSString *baseURL;
|
|
|
|
|
|
|
|
baseURL = [[self clientObject] baseURLInContext: context];
|
|
|
|
|
2016-04-11 20:53:17 +02:00
|
|
|
if (!baseURL)
|
|
|
|
baseURL = @"/SOGo/so/";
|
|
|
|
|
2015-09-21 14:59:36 +02:00
|
|
|
if ([baseURL hasSuffix: [NSString stringWithFormat: @"%@/", [[self parent] modulePath]]])
|
|
|
|
return baseURL;
|
|
|
|
|
|
|
|
return [NSString stringWithFormat: @"%@%@", baseURL, [[self parent] modulePath]];
|
2006-09-07 00:25:46 +02:00
|
|
|
}
|
|
|
|
|
2015-09-21 18:02:33 +02:00
|
|
|
return @"SOGo";
|
2006-07-29 00:59:11 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) ownPath
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *uri;
|
|
|
|
NSRange r;
|
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
uri = [[context request] uri];
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/* first: cut off query parameters */
|
|
|
|
|
|
|
|
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
|
|
|
|
if (r.length > 0)
|
|
|
|
uri = [uri substringToIndex:r.location];
|
2006-09-05 22:41:05 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) relativePathToUserFolderSubPath: (NSString *) _sub
|
|
|
|
{
|
2014-11-14 20:50:13 +01:00
|
|
|
NSString *dst, *rel, *theme;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-04-11 21:51:07 +02:00
|
|
|
dst = [[self userFolderPath] stringByAppendingPathComponent: _sub];
|
2006-06-15 21:34:10 +02:00
|
|
|
rel = [dst urlPathRelativeToPath:[self ownPath]];
|
2006-09-05 22:41:05 +02:00
|
|
|
|
2014-11-14 20:50:13 +01:00
|
|
|
theme = [[context request] formValueForKey: @"theme"];
|
|
|
|
if ([theme length])
|
|
|
|
rel = [NSString stringWithFormat: @"%@?theme=%@", rel, theme];
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return rel;
|
|
|
|
}
|
2006-09-07 16:13:03 +02:00
|
|
|
|
2006-10-04 21:21:45 +02:00
|
|
|
- (NSCalendarDate *) selectedDate
|
|
|
|
{
|
|
|
|
if (!_selectedDate)
|
|
|
|
{
|
|
|
|
_selectedDate
|
2006-10-05 01:13:09 +02:00
|
|
|
= [NSCalendarDate
|
|
|
|
dateFromShortDateString: [self queryParameterForKey: @"day"]
|
|
|
|
andShortTimeString: [self queryParameterForKey: @"hm"]
|
2012-09-22 03:48:39 +02:00
|
|
|
inTimeZone: [userDefaults timeZone]];
|
2006-09-05 22:13:16 +02:00
|
|
|
[_selectedDate retain];
|
2006-09-05 20:42:18 +02:00
|
|
|
}
|
|
|
|
|
2006-09-05 22:13:16 +02:00
|
|
|
return _selectedDate;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2015-03-26 13:52:48 +01:00
|
|
|
- (NSString *) currentDayDescription
|
|
|
|
{
|
2015-04-01 14:51:48 +02:00
|
|
|
NSDictionary *currentDay;
|
|
|
|
SOGoUser *user;
|
|
|
|
|
|
|
|
user = [context activeUser];
|
|
|
|
if (user)
|
|
|
|
currentDay = [user currentDay];
|
|
|
|
else
|
|
|
|
currentDay = [NSDictionary dictionary];
|
|
|
|
|
|
|
|
return [currentDay jsonRepresentation];
|
2015-03-26 13:52:48 +01:00
|
|
|
}
|
|
|
|
|
2006-09-19 23:09:57 +02:00
|
|
|
- (NSString *) dateStringForDate: (NSCalendarDate *) _date
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
[_date setTimeZone: [userDefaults timeZone]];
|
2006-09-19 23:09:57 +02:00
|
|
|
|
2007-09-11 21:32:52 +02:00
|
|
|
return [_date descriptionWithCalendarFormat: @"%Y%m%d"];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) hideFrame
|
|
|
|
{
|
|
|
|
return ([[self queryParameterForKey: @"noframe"] boolValue]);
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2006-10-12 18:44:40 +02:00
|
|
|
- (UIxComponent *) jsCloseWithRefreshMethod: (NSString *) methodName
|
|
|
|
{
|
|
|
|
UIxJSClose *jsClose;
|
|
|
|
|
|
|
|
jsClose = [UIxJSClose new];
|
|
|
|
[jsClose autorelease];
|
2015-06-10 15:08:10 +02:00
|
|
|
[jsClose setRefreshMethod: [methodName doubleQuotedString]];
|
2006-10-12 18:44:40 +02:00
|
|
|
|
|
|
|
return jsClose;
|
|
|
|
}
|
|
|
|
|
2007-11-09 17:40:15 +01:00
|
|
|
/* common conditions */
|
|
|
|
- (BOOL) canCreateOrModify
|
|
|
|
{
|
|
|
|
SoSecurityManager *sm;
|
|
|
|
|
|
|
|
sm = [SoSecurityManager sharedSecurityManager];
|
|
|
|
|
|
|
|
return (![sm validatePermission: SoPerm_ChangeImagesAndFiles
|
|
|
|
onObject: [self clientObject]
|
|
|
|
inContext: context]);
|
|
|
|
}
|
|
|
|
|
2011-12-02 08:22:47 +01:00
|
|
|
- (BOOL) singleWindowModeEnabled
|
|
|
|
{
|
|
|
|
//WEClientCapabilities *cc;
|
|
|
|
NSString *value;
|
|
|
|
BOOL result;
|
|
|
|
|
|
|
|
//cc = [[context request] clientCapabilities];
|
|
|
|
|
|
|
|
//NSLog(@"User agent = %@, Type = %@, OS = %@, CPU = %@, Browser major version = %i", [cc userAgent], [cc userAgentType], [cc os], [cc cpu], [cc majorVersion]);
|
|
|
|
|
|
|
|
value = [[context request] cookieValueForKey: @"SOGoWindowMode"];
|
|
|
|
result = ([value isEqualToString: @"single"]);
|
|
|
|
|
2011-12-09 17:34:11 +01:00
|
|
|
//NSLog(@"Single window mode %@", result?@"enabled":@"disabled");
|
2011-12-02 08:22:47 +01:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-12-09 15:53:44 +01:00
|
|
|
- (BOOL) userHasCalendarAccess
|
|
|
|
{
|
|
|
|
SOGoUser *user;
|
|
|
|
|
|
|
|
user = [context activeUser];
|
|
|
|
|
|
|
|
return [user canAccessModule: @"Calendar"];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) userHasMailAccess
|
|
|
|
{
|
|
|
|
SOGoUser *user;
|
|
|
|
|
|
|
|
user = [context activeUser];
|
|
|
|
|
|
|
|
return [user canAccessModule: @"Mail"];
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* SoUser */
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) shortUserNameForDisplay
|
|
|
|
{
|
2007-09-05 16:55:58 +02:00
|
|
|
return [[context activeUser] login];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2016-02-25 03:30:33 +01:00
|
|
|
/* Common defaults and settings */
|
|
|
|
|
|
|
|
- (int) minimumSearchLength
|
|
|
|
{
|
|
|
|
return [[[context activeUser] domainDefaults] searchMinimumWordLength];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) minimumSearchLengthLabel
|
|
|
|
{
|
|
|
|
NSDictionary *defaults;
|
|
|
|
|
|
|
|
defaults = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: [self minimumSearchLength]]
|
|
|
|
forKey: @"minimumSearchLength"];
|
|
|
|
return [defaults keysWithFormat: [self commonLabelForKey: @"Enter at least %{minimumSearchLength} characters"]];
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* labels */
|
|
|
|
|
2018-08-02 23:59:52 +02:00
|
|
|
- (NSString *) framework
|
|
|
|
{
|
|
|
|
return [[context page] frameworkName];
|
|
|
|
}
|
|
|
|
|
2006-09-05 22:41:05 +02:00
|
|
|
- (NSString *) labelForKey: (NSString *) _str
|
2006-08-15 22:56:38 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
WOResourceManager *rm;
|
2012-09-22 03:48:39 +02:00
|
|
|
/* find resource manager */
|
|
|
|
|
|
|
|
rm = [self pageResourceManager];
|
|
|
|
|
|
|
|
return [self labelForKey: _str withResourceManager: rm];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) commonLabelForKey: (NSString *) _str
|
|
|
|
{
|
|
|
|
WOResourceManager *rm;
|
|
|
|
|
|
|
|
rm = [commonProduct resourceManager];
|
|
|
|
|
|
|
|
return [self labelForKey: _str withResourceManager: rm];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) labelForKey: (NSString *) _str
|
|
|
|
withResourceManager: (WOResourceManager *) rm
|
|
|
|
{
|
2006-09-05 22:41:05 +02:00
|
|
|
NSString *lKey, *lTable, *lVal;
|
2006-06-15 21:34:10 +02:00
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
if ([_str length] == 0)
|
|
|
|
return nil;
|
2012-09-22 03:48:39 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
if (rm == nil)
|
|
|
|
[self warnWithFormat:@"missing resource manager!"];
|
2012-09-22 03:48:39 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* get parameters */
|
|
|
|
|
|
|
|
r = [_str rangeOfString:@"/"];
|
|
|
|
if (r.length > 0) {
|
|
|
|
lTable = [_str substringToIndex:r.location];
|
|
|
|
lKey = [_str substringFromIndex:(r.location + r.length)];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lTable = nil;
|
|
|
|
lKey = _str;
|
|
|
|
}
|
|
|
|
lVal = lKey;
|
|
|
|
|
|
|
|
if ([lKey hasPrefix:@"$"])
|
|
|
|
lKey = [self valueForKeyPath:[lKey substringFromIndex:1]];
|
|
|
|
|
|
|
|
if ([lTable hasPrefix:@"$"])
|
|
|
|
lTable = [self valueForKeyPath:[lTable substringFromIndex:1]];
|
|
|
|
|
|
|
|
/* lookup string */
|
2006-08-15 22:56:38 +02:00
|
|
|
return [rm stringForKey: lKey
|
|
|
|
inTableNamed: lTable
|
|
|
|
withDefaultValue: lVal
|
|
|
|
languages: languages];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-03-10 16:04:01 +01:00
|
|
|
- (NSString *) localizedNameForDayOfWeek: (unsigned) dayOfWeek
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
return [[locale objectForKey: NSWeekDayNameArray] objectAtIndex: dayOfWeek % 7];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-03-10 16:04:01 +01:00
|
|
|
- (NSString *) localizedAbbreviatedNameForDayOfWeek: (unsigned) dayOfWeek
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
// Defined in Common bundle
|
|
|
|
return [self commonLabelForKey: [abbrDayLabelKeys objectAtIndex: dayOfWeek % 7]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-03-10 16:04:01 +01:00
|
|
|
- (NSString *) localizedNameForMonthOfYear: (unsigned) monthOfYear
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
// Defined in Locale
|
|
|
|
return [[locale objectForKey: NSMonthNameArray] objectAtIndex: (monthOfYear - 1) % 12];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-03-10 16:04:01 +01:00
|
|
|
- (NSString *) localizedAbbreviatedNameForMonthOfYear: (unsigned) monthOfYear
|
|
|
|
{
|
2012-09-22 03:48:39 +02:00
|
|
|
// Defined in Locale
|
|
|
|
return [[locale objectForKey: NSShortMonthNameArray] objectAtIndex: (monthOfYear - 1) % 12];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* HTTP method safety */
|
|
|
|
|
|
|
|
- (BOOL)isInvokedBySafeMethod {
|
|
|
|
// TODO: move to WORequest?
|
|
|
|
NSString *m;
|
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
m = [[context request] method];
|
2006-06-15 21:34:10 +02:00
|
|
|
if ([m isEqualToString:@"GET"]) return YES;
|
|
|
|
if ([m isEqualToString:@"HEAD"]) return YES;
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* locale */
|
|
|
|
|
|
|
|
- (NSDictionary *)locale {
|
|
|
|
/* we need no fallback here, as locale is guaranteed to be set by sogod */
|
2007-06-11 23:26:11 +02:00
|
|
|
return [context valueForKey: @"locale"];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (WOResourceManager *) pageResourceManager
|
|
|
|
{
|
|
|
|
WOResourceManager *rm;
|
|
|
|
|
2007-08-23 18:12:16 +02:00
|
|
|
if ((rm = [[context page] resourceManager]) == nil)
|
2006-07-29 00:59:11 +02:00
|
|
|
rm = [[WOApplication application] resourceManager];
|
|
|
|
|
|
|
|
return rm;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) urlForResourceFilename: (NSString *) filename
|
|
|
|
{
|
|
|
|
static NSMutableDictionary *pageToURL = nil;
|
|
|
|
NSString *url;
|
|
|
|
WOComponent *page;
|
|
|
|
WOResourceManager *rm;
|
|
|
|
NSBundle *pageBundle;
|
|
|
|
|
2006-08-01 21:18:06 +02:00
|
|
|
if (filename)
|
2006-07-29 00:59:11 +02:00
|
|
|
{
|
2006-08-01 21:18:06 +02:00
|
|
|
if (!pageToURL)
|
|
|
|
pageToURL = [[NSMutableDictionary alloc] initWithCapacity: 32];
|
|
|
|
|
|
|
|
url = [pageToURL objectForKey: filename];
|
2006-07-29 00:59:11 +02:00
|
|
|
if (!url)
|
2006-08-01 21:18:06 +02:00
|
|
|
{
|
|
|
|
rm = [self pageResourceManager];
|
2007-08-23 18:12:16 +02:00
|
|
|
page = [context page];
|
2006-08-01 21:18:06 +02:00
|
|
|
pageBundle = [NSBundle bundleForClass: [page class]];
|
|
|
|
url = [rm urlForResourceNamed: filename
|
|
|
|
inFramework: [pageBundle bundlePath]
|
|
|
|
languages: nil
|
2007-08-23 18:12:16 +02:00
|
|
|
request: [context request]];
|
2006-08-01 21:18:06 +02:00
|
|
|
if (!url)
|
|
|
|
url = @"";
|
|
|
|
else
|
|
|
|
if ([url hasPrefix: @"http"])
|
|
|
|
url = [url hostlessURL];
|
|
|
|
[pageToURL setObject: url forKey: filename];
|
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
// NSLog (@"url for '%@': '%@'", filename, url);
|
2006-08-01 21:18:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
url = @"";
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2007-12-13 20:25:01 +01:00
|
|
|
- (WOResponse *) responseWithStatus: (unsigned int) status
|
2007-09-11 21:32:52 +02:00
|
|
|
{
|
|
|
|
WOResponse *response;
|
|
|
|
|
|
|
|
response = [context response];
|
2007-12-13 20:25:01 +01:00
|
|
|
[response setStatus: status];
|
2009-07-19 19:11:37 +02:00
|
|
|
[response setHeader: @"text/plain; charset=utf-8"
|
|
|
|
forKey: @"content-type"];
|
2007-12-13 20:25:01 +01:00
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (WOResponse *) responseWithStatus: (unsigned int) status
|
|
|
|
andString: (NSString *) contentString
|
|
|
|
{
|
|
|
|
WOResponse *response;
|
|
|
|
|
|
|
|
response = [self responseWithStatus: status];
|
|
|
|
[response appendContentString: contentString];
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (WOResponse *) responseWithStatus: (unsigned int) status
|
|
|
|
andJSONRepresentation: (NSObject *) contentObject;
|
|
|
|
{
|
2010-03-09 21:29:17 +01:00
|
|
|
WOResponse *response;
|
|
|
|
|
|
|
|
response = [self responseWithStatus: status
|
|
|
|
andString: [contentObject jsonRepresentation]];
|
|
|
|
[response setHeader: @"application/json" forKey: @"content-type"];
|
|
|
|
|
|
|
|
return response;
|
2007-12-13 20:25:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (WOResponse *) responseWith204
|
|
|
|
{
|
|
|
|
return [self responseWithStatus: 204];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (WOResponse *) redirectToLocation: (NSString *) newLocation
|
|
|
|
{
|
|
|
|
WOResponse *response;
|
2014-08-06 22:01:05 +02:00
|
|
|
NSURL *url;
|
|
|
|
NSMutableString *location;
|
|
|
|
NSString *theme, *query;
|
|
|
|
|
|
|
|
location = [NSMutableString stringWithString: newLocation];
|
|
|
|
theme = [[context request] formValueForKey: @"theme"];
|
|
|
|
if ([theme length])
|
|
|
|
{
|
|
|
|
url = [NSURL URLWithString: newLocation];
|
|
|
|
query = [url query];
|
|
|
|
if ([query length])
|
|
|
|
{
|
|
|
|
if ([query rangeOfString: @"theme="].length == 0)
|
|
|
|
[location appendFormat: @"&theme=%@", theme];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
[location appendFormat: @"?theme=%@", theme];
|
|
|
|
}
|
2007-12-13 20:25:01 +01:00
|
|
|
|
|
|
|
response = [self responseWithStatus: 302];
|
2014-08-06 22:01:05 +02:00
|
|
|
[response setHeader: location forKey: @"location"];
|
2007-09-11 21:32:52 +02:00
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* debugging */
|
|
|
|
|
2009-07-14 19:20:49 +02:00
|
|
|
- (NSString *) buildDate
|
|
|
|
{
|
|
|
|
return SOGoBuildDate;
|
|
|
|
}
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
- (BOOL) isUIxDebugEnabled
|
2009-07-14 19:20:49 +02:00
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
SOGoSystemDefaults *sd;
|
|
|
|
|
|
|
|
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
|
|
|
|
|
|
|
return [sd uixDebugEnabled];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2016-04-26 17:06:44 +02:00
|
|
|
//
|
|
|
|
// Protection against XSRF
|
|
|
|
//
|
|
|
|
- (id<WOActionResults>)performActionNamed:(NSString *)_actionName
|
|
|
|
{
|
|
|
|
SOGoWebAuthenticator *auth;
|
|
|
|
NSString *value, *token;
|
|
|
|
NSArray *creds;
|
|
|
|
|
2016-05-11 14:55:05 +02:00
|
|
|
auth = [[WOApplication application]
|
|
|
|
authenticatorInContext: context];
|
|
|
|
|
|
|
|
if (![[SOGoSystemDefaults sharedSystemDefaults] xsrfValidationEnabled] ||
|
|
|
|
![auth isKindOfClass: [SOGoWebAuthenticator class]])
|
2016-04-26 17:06:44 +02:00
|
|
|
return [super performActionNamed: _actionName];
|
|
|
|
|
|
|
|
// If the action is 'connect' (or 'logoff'), we let it go as the token
|
|
|
|
// needs to be created (or destroyed) during the session initialization
|
|
|
|
if ([_actionName isEqualToString: @"connect"] ||
|
|
|
|
[_actionName isEqualToString: @"logoff"])
|
|
|
|
{
|
|
|
|
return [super performActionNamed: _actionName];
|
|
|
|
}
|
|
|
|
|
|
|
|
// We grab the X-XSRF-TOKEN header
|
|
|
|
token = [[context request] headerForKey: @"X-XSRF-TOKEN"];
|
|
|
|
|
|
|
|
// We compare it with our session key
|
|
|
|
value = [[context request]
|
|
|
|
cookieValueForKey: [auth cookieNameInContext: context]];
|
|
|
|
creds = [auth parseCredentials: value];
|
|
|
|
|
|
|
|
value = [SOGoSession valueForSessionKey: [creds lastObject]];
|
|
|
|
|
|
|
|
if ([token isEqualToString: [value asSHA1String]])
|
|
|
|
return [super performActionNamed: _actionName];
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@end /* UIxComponent */
|