diff --git a/API/SOGoAPIDispatcher.m b/API/SOGoAPIDispatcher.m index bb1613bcb..491c15c3e 100644 --- a/API/SOGoAPIDispatcher.m +++ b/API/SOGoAPIDispatcher.m @@ -100,13 +100,76 @@ void handle_api_terminate(int signum) [super dealloc]; } +- (void) _sendAPIErrorResponse: (WOResponse* ) response + withMessage: (NSString *) message + withStatus: (unsigned int) status +{ + NSDictionary *msg; + msg = [[NSDictionary alloc] initWithObjectsAndKeys: + message, @"error", + nil]; + [response setStatus: status]; + [response setContent: [msg jsonRepresentation]]; +} + +- (NSString *) _getActionFromUri: (NSString *) _uri +{ + /* + _uri always start with /SOGo/SOGoAPI + full _uri example /SOGo/SOGoAPI/Action/subaction1?param1¶m2 + */ + + NSString *uriWithoutParams, *action, *prefix; + NSArray *uriSplits; + + prefix = @"/SOGo/SOGoAPI"; + action = @""; + + uriWithoutParams = [_uri urlWithoutParameters]; + if(![uriWithoutParams hasPrefix: prefix]) + { + [self errorWithFormat: @"Uri for API request does not start with /SOGo/SOGoAPI: %@", uriWithoutParams]; + return nil; + } + else + { + uriWithoutParams = [uriWithoutParams substringFromIndex:[prefix length]]; + } + + //remove first and last '/'' if needed + if([uriWithoutParams hasPrefix: @"/"]) + { + uriWithoutParams = [uriWithoutParams substringFromIndex:1]; + } + if([uriWithoutParams hasSuffix: @"/"]) + { + uriWithoutParams = [uriWithoutParams substringToIndex:([uriWithoutParams length] -1)]; + } + if([uriWithoutParams length] == 0) + { + [self warnWithFormat: @"Uri for API request has no action, make Version instead: %@", uriWithoutParams]; + return @"SOGoAPIVersion"; + } + else + { + uriSplits = [uriWithoutParams componentsSeparatedByString: @"/"]; + action = [@"SOGoAPI" stringByAppendingString: [uriSplits objectAtIndex: 0]]; + if(debugOn) + [self logWithFormat: @"API request, action made is %@", action]; + } + + return action; +} + + + - (NSException *) dispatchRequest: (WORequest*) theRequest inResponse: (WOResponse*) theResponse context: (id) theContext { NSAutoreleasePool *pool; id activeUser; - NSString *method, *action; + NSString *method, *action, *error; NSDictionary *form; NSMutableDictionary *ret; NSBundle *bundle; @@ -115,22 +178,55 @@ void handle_api_terminate(int signum) pool = [[NSAutoreleasePool alloc] init]; - ASSIGN(context, theContext); activeUser = [context activeUser]; //Get the api action, check it - action = [theRequest uri]; //il retourne /SOGo/SOGoAPI - + action = [self _getActionFromUri: [theRequest uri]]; + if(!action) + { + error = [NSString stringWithFormat: @"No actions found for request to API: %@", [theRequest uri]]; + [self errorWithFormat: error]; + [self _sendAPIErrorResponse: theResponse withMessage: error withStatus: 400]; + return nil; + } + //Get the class for this action, check it bundle = [NSBundle bundleForClass: NSClassFromString(@"SOGoAPIProduct")]; - clazz = [bundle classNamed: @"SOGoAPIVersion"]; - classAction = [[clazz alloc] init]; + clazz = [bundle classNamed: action]; + if(!clazz) + { + error = [NSString stringWithFormat: @"No backend API found for action: %@", action]; + [self errorWithFormat: error]; + [self _sendAPIErrorResponse: theResponse withMessage: error withStatus: 400]; + return nil; + } + + //try to instantiate the class + NS_DURING + { + classAction = [[clazz alloc] init]; + } + NS_HANDLER + { + error = [NSString stringWithFormat: @"Can't alloc and init class: %@", classAction]; + [self errorWithFormat: error]; + [self _sendAPIErrorResponse: theResponse withMessage: error withStatus: 500]; + } + NS_ENDHANDLER; + //Check user auth - //retreive data if needed and execute action + + //Check method + + + //Check parameters + + + //Execute action ret = [classAction action]; //Make the response diff --git a/Main/SOGo.m b/Main/SOGo.m index 9218a53ad..5faf318a0 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -417,7 +417,7 @@ static BOOL debugLeaks; { id obj; WORequest *request; - BOOL isDAVRequest; + BOOL isDAVRequest, isAPIRequest; SOGoSystemDefaults *sd; /* put locale info into the context in case it's not there */ @@ -425,8 +425,14 @@ static BOOL debugLeaks; sd = [SOGoSystemDefaults sharedSystemDefaults]; request = [_ctx request]; + isAPIRequest = [[request requestHandlerKey] isEqualToString:@"SOGoAPI"]; isDAVRequest = [[request requestHandlerKey] isEqualToString:@"dav"]; - if (isDAVRequest || [sd isWebAccessEnabled]) + if(isAPIRequest && ![_key isEqualToString:@"SOGo"] && ![_key isEqualToString:@"SOGoAPI"]) + { + //The request will be handle by the API Dispatcher + obj = nil; + } + else if (isDAVRequest || [sd isWebAccessEnabled]) { if (isDAVRequest) { diff --git a/UI/MainUI/SOGoAPIActions.m b/UI/MainUI/SOGoAPIActions.m index 4e6ce6ad2..07bf15fe2 100644 --- a/UI/MainUI/SOGoAPIActions.m +++ b/UI/MainUI/SOGoAPIActions.m @@ -35,9 +35,7 @@ @implementation SOGoAPIActions -// -// Invoked on POST actions -// + - (WOResponse *) sogoAPIAction { WOResponse *response;