From 1289e14ec72651bb0baddac5203a067751641b45 Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 16 Nov 2005 13:31:33 +0000 Subject: [PATCH] added BasicAuthSession example git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1176 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- .../samples/BasicAuthSession/Application.m | 175 ++++++++++++++++++ .../samples/BasicAuthSession/GNUmakefile | 16 ++ .../samples/BasicAuthSession/Main.m | 23 +++ .../BasicAuthSession/Main.wo/Main.html | 10 + .../samples/BasicAuthSession/Main.wo/Main.wod | 13 ++ .../BasicAuthSession/NSString+BasicAuth.h | 15 ++ .../BasicAuthSession/NSString+BasicAuth.m | 48 +++++ .../samples/BasicAuthSession/README | 18 ++ .../samples/BasicAuthSession/common.h | 3 + 9 files changed, 321 insertions(+) create mode 100644 sope-appserver/samples/BasicAuthSession/Application.m create mode 100644 sope-appserver/samples/BasicAuthSession/GNUmakefile create mode 100644 sope-appserver/samples/BasicAuthSession/Main.m create mode 100644 sope-appserver/samples/BasicAuthSession/Main.wo/Main.html create mode 100644 sope-appserver/samples/BasicAuthSession/Main.wo/Main.wod create mode 100644 sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.h create mode 100644 sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.m create mode 100644 sope-appserver/samples/BasicAuthSession/README create mode 100644 sope-appserver/samples/BasicAuthSession/common.h diff --git a/sope-appserver/samples/BasicAuthSession/Application.m b/sope-appserver/samples/BasicAuthSession/Application.m new file mode 100644 index 00000000..32fcaa83 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/Application.m @@ -0,0 +1,175 @@ +// $Id: Application.m,v 1.1 2004/06/08 11:08:07 helge Exp $ + +#include + +@interface Application : WOApplication +@end + +#include "NSString+BasicAuth.h" +#include +#include "common.h" + +@interface NSString(ValidSessionID) +- (NSString *)asValidSessionIDString; +@end + +@implementation NSString(ValidSessionID) + +- (NSString *)asValidSessionIDString { + unsigned len; + + if ((len = [self length]) == 0) + return nil; + else if (len == 18) + return [[self copy] autorelease]; + else if (len > 18) + return [self substringToIndex:18]; + else { + /* increase string length .. */ + NSMutableString *sid; + + sid = [[self mutableCopy] autorelease]; + while ([sid length] < 18) + [sid appendString:@"X"]; + return sid; + } +} + +@end /* NSString(ValidSessionID) */ + +@implementation Application + +- (id)init { + if ((self = [super init])) { + WORequestHandler *rh; + + rh = [[NSClassFromString(@"OWViewRequestHandler") alloc] init]; + [self setDefaultRequestHandler:rh]; + [self registerRequestHandler:rh + forKey:[WOApplication componentRequestHandlerKey]]; + RELEASE(rh); rh = nil; + } + return self; +} + +/* auth check */ + +- (BOOL)isValidAuthorization:(NSString *)_credentials + inContext:(WOContext *)_ctx +{ + NSString *login, *pwd; + + login = [_credentials loginOfHTTPBasicAuthorizationValue]; + pwd = [_credentials passwordOfHTTPBasicAuthorizationValue]; + + [self debugWithFormat:@"login '%@', pwd=%s", login, [pwd length]?"yes":"no"]; + + return [login length] > 0; +} + +- (NSString *)sessionIDForAuthorization:(NSString *)_credentials + inContext:(WOContext *)_ctx +{ + return [[_credentials loginOfHTTPBasicAuthorizationValue] + asValidSessionIDString]; +} + +/* session callbacks */ + +- (WOSession *)createSessionForRequest:(WORequest *)_request { + [self debugWithFormat:@"creating session ..."]; + return [super createSessionForRequest:_request]; +} + +- (WOResponse *)handleSessionCreationErrorInContext:(WOContext *)_ctx { + /* a session could not be created */ + WOResponse *response; + NSString *header; + + header = [NSString stringWithFormat:@"basic realm=\"%@\"", [self name]]; + + response = [_ctx response]; + [response setStatus:401 /* unauthorized */]; + [response setContent:[NSData data]]; + [response setHeader:header forKey:@"www-authenticate"]; + return response; +} + +- (WOResponse *)handleSessionRestorationErrorInContext:(WOContext *)_ctx { + /* + A session could not be restored, an ID is available + + This is too late to create a session, so use the thing below ... + */ + return [super handleSessionRestorationErrorInContext:_ctx]; +} +- (WOSession *)restoreSessionWithID:(NSString *)_sid + inContext:(WOContext *)_ctx +{ + WOSession *sn; + + if ([_sid length] == 0) + return nil; + + if ((sn = [super restoreSessionWithID:_sid inContext:_ctx])) + return sn; + + /* have a valid? sid, so create a session ... */ + [self debugWithFormat:@"couldn't restore sid '%@', create a new session ..", + _sid]; + return [self createSessionForRequest:[_ctx request]]; +} + +/* generating session IDs */ + +- (NSString *)sessionIDFromRequest:(WORequest *)_request { + /* session id must be 18 chars long for snsd to work ! */ + NSString *sid; + + if ((sid = [super sessionIDFromRequest:_request])) + return sid; + + /* if no 'regular' session ID is provided, use authorization header .. */ + + if ((sid = [_request headerForKey:@"authorization"])) { + if ([self isValidAuthorization:sid inContext:nil]) { + sid = [self sessionIDForAuthorization:sid inContext:nil]; + [self debugWithFormat:@"got sid from auth: '%@'", sid]; + return sid; + } + else { + [self logWithFormat:@"got invalid auth: '%@'", sid]; + sid = nil; + } + } + return nil; +} + +- (NSString *)createSessionIDForSession:(WOSession *)_session { + /* session id must be 18 chars long for snsd to work ! */ + NSString *sid; + WORequest *request; + + request = [[self context] request]; + + if ((sid = [request headerForKey:@"authorization"])) { + if ([self isValidAuthorization:sid inContext:nil]) { + sid = [self sessionIDForAuthorization:sid inContext:[self context]]; + [self debugWithFormat:@"got sid from auth: '%@'", sid]; + return sid; + } + else { + [self logWithFormat:@"got invalid auth: '%@'", sid]; + sid = nil; + } + } + return nil; +} + +@end /* Application */ + +int main(int argc, char **argv) { + WOApplicationMain(@"Application", argc, (void*)argv); + exit(0); + return 0; +} diff --git a/sope-appserver/samples/BasicAuthSession/GNUmakefile b/sope-appserver/samples/BasicAuthSession/GNUmakefile new file mode 100644 index 00000000..a59a18e4 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/GNUmakefile @@ -0,0 +1,16 @@ +# $Id: GNUmakefile,v 1.1 2004/06/08 11:08:07 helge Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +WOAPP_NAME = BasicAuthSn + +BasicAuthSn_OBJC_FILES = \ + Application.m \ + Main.m \ + NSString+BasicAuth.m \ + +BasicAuthSn_COMPONENTS += Main.wo + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/woapp.make +-include GNUmakefile.postamble diff --git a/sope-appserver/samples/BasicAuthSession/Main.m b/sope-appserver/samples/BasicAuthSession/Main.m new file mode 100644 index 00000000..8a5c3afc --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/Main.m @@ -0,0 +1,23 @@ +// $Id: Main.m,v 1.1 2004/06/08 11:08:07 helge Exp $ + +#include + +@interface Main : WOComponent +{ + unsigned clickCount; +} + +@end + +@implementation Main + +- (unsigned)clickCount { + return self->clickCount; +} + +- (id)click { + self->clickCount++; + return nil; +} + +@end /* Main */ diff --git a/sope-appserver/samples/BasicAuthSession/Main.wo/Main.html b/sope-appserver/samples/BasicAuthSession/Main.wo/Main.html new file mode 100644 index 00000000..744cd2b8 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/Main.wo/Main.html @@ -0,0 +1,10 @@ + + BasicAuthTest + + + + SessionID:
+ ClickCount:
+ + + diff --git a/sope-appserver/samples/BasicAuthSession/Main.wo/Main.wod b/sope-appserver/samples/BasicAuthSession/Main.wo/Main.wod new file mode 100644 index 00000000..110d5f65 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/Main.wo/Main.wod @@ -0,0 +1,13 @@ +// $Id: Main.wod,v 1.1 2004/06/08 11:08:23 helge Exp $ + +ClickCount: WOString { + value = clickCount; +} +SID: WOString { + value = session.sessionID; +} + +Click: WOHyperlink { + action = click; + string = "click"; +} diff --git a/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.h b/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.h new file mode 100644 index 00000000..0dbdc9f2 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.h @@ -0,0 +1,15 @@ +// $Id: NSString+BasicAuth.h,v 1.1 2004/06/08 11:08:07 helge Exp $ + +#ifndef __NSString_BasicAuth_H__ +#define __NSString_BasicAuth_H__ + +#import + +@interface NSString(BasicAuth) +- (BOOL)isHTTPBasicAuthorizationValue; +- (NSString *)decodedHTTPBasicAuthorizationValue; +- (NSString *)loginOfHTTPBasicAuthorizationValue; +- (NSString *)passwordOfHTTPBasicAuthorizationValue; +@end + +#endif /* __NSString_BasicAuth_H__ */ diff --git a/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.m b/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.m new file mode 100644 index 00000000..47451290 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/NSString+BasicAuth.m @@ -0,0 +1,48 @@ +// $Id: NSString+BasicAuth.m,v 1.1 2004/06/08 11:08:07 helge Exp $ + +#include "NSString+BasicAuth.h" +#include +#include "common.h" + +@implementation NSString(BasicAuth) + +/* eg: authorization: "basic aGVsZ2U6aGVsZ2VoZWxnZQ==" */ + +- (BOOL)isHTTPBasicAuthorizationValue { + return [self hasPrefix:@"basic"]; +} + +- (NSString *)decodedHTTPBasicAuthorizationValue { + NSRange r; + NSString *s; + + r = [self rangeOfString:@" " options:NSBackwardsSearch]; + if (r.length == 0) + return nil; + + s = [self substringFromIndex:(r.location + r.length)]; + return [s stringByDecodingBase64]; +} + +- (NSString *)loginOfHTTPBasicAuthorizationValue { + NSString *s; + unsigned idx; + + if ((s = [self decodedHTTPBasicAuthorizationValue]) == nil) + return nil; + if ((idx = [s indexOfString:@":"]) == NSNotFound) + return nil; + return [s substringToIndex:idx]; +} +- (NSString *)passwordOfHTTPBasicAuthorizationValue { + NSString *s; + unsigned idx; + + if ((s = [self decodedHTTPBasicAuthorizationValue]) == nil) + return nil; + if ((idx = [s indexOfString:@":"]) == NSNotFound) + return nil; + return [s substringFromIndex:(idx + 1)]; +} + +@end /* NSString(BasicAuth) */ diff --git a/sope-appserver/samples/BasicAuthSession/README b/sope-appserver/samples/BasicAuthSession/README new file mode 100644 index 00000000..256f3ce4 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/README @@ -0,0 +1,18 @@ + +Session's bound to basic-authentication ... + +States +a) auth is invalid +b) auth is valid, session is available +c) auth is valid, session is missing + + +What is called: + +- handleSessionCreationErrorInContext: + -> is called, if no authorization header was provided, so that session-id + generation failed + +- handleSessionRestorationErrorInContext: + -> is called if an authorization header is present, but the session couldn't + be found diff --git a/sope-appserver/samples/BasicAuthSession/common.h b/sope-appserver/samples/BasicAuthSession/common.h new file mode 100644 index 00000000..a9bbfa39 --- /dev/null +++ b/sope-appserver/samples/BasicAuthSession/common.h @@ -0,0 +1,3 @@ +// $Id: common.h,v 1.1 2004/06/08 11:08:07 helge Exp $ + +#import -- 2.39.5