Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth Token specs #26

Merged
merged 14 commits into from
Oct 16, 2015
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Podfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
pod 'SocketRocket', '~> 0.3.1-beta2'
pod 'SocketRocket', '~> 0.4.1'
#pod 'msgpack', '~> 0.1.3'

target 'ablySpec' do
platform :ios, '8.0'
use_frameworks!

pod 'Quick', '~> 0.3.0'
pod 'Nimble', '~> 1.0.0'
pod 'Quick', '~> 0.6.0'
pod 'Nimble', '~> 2.0.0'
# Helpers
pod 'Runes', '~> 2.0.0'
pod 'SwiftyJSON', '~> 2.2.1'
end
pod 'Runes', '~> 3.0.0'
pod 'SwiftyJSON', '~> 2.3.0'
end
30 changes: 15 additions & 15 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
PODS:
- Nimble (1.0.0)
- Quick (0.3.1)
- Runes (2.0.0)
- SocketRocket (0.3.1-beta2)
- SwiftyJSON (2.2.1)
- Nimble (2.0.0)
- Quick (0.6.0)
- Runes (3.0.0)
- SocketRocket (0.4.1)
- SwiftyJSON (2.3.0)

DEPENDENCIES:
- Nimble (~> 1.0.0)
- Quick (~> 0.3.0)
- Runes (~> 2.0.0)
- SocketRocket (~> 0.3.1-beta2)
- SwiftyJSON (~> 2.2.1)
- Nimble (~> 2.0.0)
- Quick (~> 0.6.0)
- Runes (~> 3.0.0)
- SocketRocket (~> 0.4.1)
- SwiftyJSON (~> 2.3.0)

SPEC CHECKSUMS:
Nimble: 8bee528e5fcc403653076545db562d2b5db7bb87
Quick: 824572d3d198d51e52cf4aa722cebf7e59952a35
Runes: 4fe81355f4620b76b02176222d264b33e60dba51
SocketRocket: 7284ab9370a06c99aba92b2fe3a32aedd0f9a6fa
SwiftyJSON: ae2d0a3d68025d136602a33c4ee215091ced3e33
Nimble: 472e75466819eb8c06299233e87c694a9b51328a
Quick: 563686dbcf0ae0f9f7401ac9cd2d786ee1b7f3d7
Runes: b0ffeed58b9577155e53571508b4309c904ef587
SocketRocket: ee0b5c34182d37bb4f1f8d628bbe737718126daa
SwiftyJSON: 8d6b61a70277ef2a5d710d372e06e7e2d87fb9e4

COCOAPODS: 0.38.2
10 changes: 0 additions & 10 deletions ably-ios.xcworkspace/contents.xcworkspacedata

This file was deleted.

53 changes: 0 additions & 53 deletions ably-ios.xcworkspace/xcshareddata/ably-ios.xccheckout

This file was deleted.

12 changes: 8 additions & 4 deletions ably-ios/ARTAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ typedef NS_ENUM(NSUInteger, ARTAuthMethod) {

@interface ARTAuth : NSObject

@property (nonatomic, weak) ARTLog *logger;
@property (nonatomic, readonly, strong) ARTAuthOptions *options;
@property (nonatomic, readonly, strong) ARTAuthTokenDetails *tokenDetails;
@property (nonatomic, readonly, assign) ARTAuthMethod method;

@property (nonatomic, weak) ARTLog *logger;

@property (art_nullable, readonly, getter=getClientId) NSString *clientId;
@property (art_nullable, nonatomic, readonly, strong) ARTAuthTokenDetails *tokenDetails;

// FIXME: review (Why rest?)
- (instancetype)init:(ARTRest *)rest withOptions:(ARTClientOptions *)options;

/**
Expand All @@ -49,10 +53,10 @@ typedef NS_ENUM(NSUInteger, ARTAuthMethod) {
- Parameter callback: Completion callback (ARTAuthTokenDetails, NSError).
*/
- (void)requestToken:(art_nullable ARTAuthTokenParams *)tokenParams withOptions:(art_nullable ARTAuthOptions *)authOptions
callback:(void (^)(ARTAuthTokenDetails *__art_nullable tokenDetails, NSError *__art_nullable error))callback;
callback:(ARTTokenCallback)callback;

- (void)authorise:(art_nullable ARTAuthTokenParams *)tokenParams options:(art_nullable ARTAuthOptions *)options force:(BOOL)force
callback:(void (^)(ARTAuthTokenDetails *__art_nullable tokenDetails, NSError *__art_nullable error))callback;
callback:(ARTTokenCallback)callback;

- (void)createTokenRequest:(art_nullable ARTAuthTokenParams *)tokenParams options:(art_nullable ARTAuthOptions *)options
callback:(void (^)(ARTAuthTokenRequest *__art_nullable tokenRequest, NSError *__art_nullable error))callback;
Expand Down
81 changes: 59 additions & 22 deletions ably-ios/ARTAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,42 @@ - (instancetype)init:(ARTRest *)rest withOptions:(ARTClientOptions *)options {
_options = options;
_logger = rest.logger;

if ([options isBasicAuth]) {
if (!options.tls) {
[NSException raise:@"ARTAuthException" format:@"Basic authentication only connects over HTTPS (tls)."];
}
[self.logger debug:@"ARTAuth: setting up auth method Basic"];
_method = ARTAuthMethodBasic;
} else if (options.tokenDetails) {
[self.logger debug:@"ARTAuth: setting up auth method Token with supplied token only"];
_method = ARTAuthMethodToken;
} else if (options.authUrl) {
[self.logger debug:@"ARTAuth: setting up auth method Token with authUrl"];
_method = ARTAuthMethodToken;
} else if (options.authCallback) {
[self.logger debug:@"ARTAuth: setting up auth method Token with authCallback"];
_method = ARTAuthMethodToken;
} else {
[NSException raise:@"ARTAuthException" format:@"Could not setup authentication method with given options."];
}
[self validate:options];
}

return self;
}

- (void)validate:(ARTClientOptions *)options {
if ([options isBasicAuth]) {
if (!options.tls) {
[NSException raise:@"ARTAuthException" format:@"Basic authentication only connects over HTTPS (tls)."];
}
[self.logger debug:@"ARTAuth: setting up auth method Basic"];
_method = ARTAuthMethodBasic;
} else if (options.tokenDetails) {
[self.logger debug:@"ARTAuth: setting up auth method Token with supplied token only"];
_method = ARTAuthMethodToken;
} else if (options.authUrl && options.authCallback) {
[NSException raise:@"ARTAuthException" format:@"Incompatible authentication configuration: please specify either authCallback and authUrl."];
} else if (options.authUrl) {
[self.logger debug:@"ARTAuth: setting up auth method Token with authUrl"];
_method = ARTAuthMethodToken;
} else if (options.authCallback) {
[self.logger debug:@"ARTAuth: setting up auth method Token with authCallback"];
_method = ARTAuthMethodToken;
} else if (options.key && options.useTokenAuth) {
[self.logger debug:@"ARTAuth: setting up auth method Token with key"];
_method = ARTAuthMethodToken;
} else {
[NSException raise:@"ARTAuthException" format:@"Could not setup authentication method with given options."];
}

if ([options.clientId isEqual:@"*"]) {
[NSException raise:@"ARTAuthException" format:@"Invalid clientId: cannot contain only a wilcard \"*\"."];
}
}

- (ARTAuthOptions *)mergeOptions:(ARTAuthOptions *)customOptions {
return customOptions ? [self.options mergeWith:customOptions] : self.options;
}
Expand Down Expand Up @@ -126,7 +139,7 @@ - (void)requestToken:(ARTAuthTokenParams *)tokenParams withOptions:(ARTAuthOptio
ARTAuthCallback tokenRequestFactory = mergedOptions.authCallback? : ^(ARTAuthTokenParams *tokenParams, void(^callback)(ARTAuthTokenRequest *tokenRequest, NSError *error)) {
[self createTokenRequest:currentTokenParams options:mergedOptions callback:callback];
};

tokenRequestFactory(currentTokenParams, ^(ARTAuthTokenRequest *tokenRequest, NSError *error) {
if (error) {
callback(nil, error);
Expand Down Expand Up @@ -169,16 +182,22 @@ - (void)authorise:(ARTAuthTokenParams *)tokenParams options:(ARTAuthOptions *)op
callback:(void (^)(ARTAuthTokenDetails *, NSError *))callback {
if (!force && self.tokenDetails && [self.tokenDetails.expires timeIntervalSinceNow] > 0) {
[self.logger verbose:@"ARTAuth authorise not forced and current token is not expired yet, reuse current token."];
callback(self.tokenDetails, nil);
if (callback) {
callback(self.tokenDetails, nil);
}
} else {
[self.logger verbose:@"ARTAuth authorise requesting new token."];
[self requestToken:tokenParams withOptions:options callback:^(ARTAuthTokenDetails *tokenDetails, NSError *error) {
if (error) {
callback(nil, error);
if (callback) {
callback(nil, error);
}
} else {
_tokenDetails = tokenDetails;
_method = ARTAuthMethodToken;
callback(tokenDetails, nil);
if (callback) {
callback(tokenDetails, nil);
}
}
}];
}
Expand Down Expand Up @@ -206,6 +225,7 @@ - (void)createTokenRequest:(ARTAuthTokenParams *)tokenParams options:(ARTAuthOpt
}

- (BOOL)canRequestToken {
// FIXME: not used?!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will this get resolved Is it not possible to do it with this PR?

if (self.options.authCallback) {
[self.logger verbose:@"ARTAuth can request token via authCallback"];
return YES;
Expand All @@ -221,4 +241,21 @@ - (BOOL)canRequestToken {
}
}

- (NSString *)getClientId {
if (self.tokenDetails) {
// Check wildcard
if ([self.tokenDetails.clientId isEqual:@"*"])
// Any client
return nil;
else
return self.tokenDetails.clientId;
}
else if (self.options) {
return self.options.clientId;
}
else {
return nil;
}
}

@end
20 changes: 18 additions & 2 deletions ably-ios/ARTAuthOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,35 @@ ART_ASSUME_NONNULL_BEGIN
/**
Headers to be included in any request made by the library to the authURL.
*/
@property (nonatomic, copy, art_nullable) NSDictionary *authHeaders; //X7: NSDictionary<NSString *, NSString *> *authHeaders;
@property (nonatomic, copy, art_nullable) __GENERIC(NSDictionary, NSString *, NSString *) *authHeaders;

/**
Additional params to be included in any request made by the library to the authUrl, either as query params in the case of GET or in the body in the case of POST.
*/
@property (nonatomic, copy, art_nullable) NSArray *authParams; //X7: NSArray<NSURLQueryItem *> *authParams;
@property (nonatomic, copy, art_nullable) __GENERIC(NSArray, NSURLQueryItem *) *authParams;

/**
This may be set in instances that the library is to sign token requests based on a given key.
If true, the library will query the Ably system for the current time instead of relying on a locally-available time of day.
*/
@property (nonatomic, assign, nonatomic) BOOL queryTime;

/**
Forces authentication with token.
*/
@property (readwrite, assign, nonatomic) BOOL useTokenAuth;

/**
Indicates that a new token should be requested.
*/
@property (readwrite, assign, nonatomic) BOOL force;

/**
The id of the client represented by this instance.
The clientId is relevant to presence operations, where the clientId is the principal identifier of the client in presence update messages. The clientId is also relevant to authentication; a token issued for a specific client may be used to authenticate the bearer of that token to the service.
*/
@property (readwrite, strong, nonatomic) NSString *clientId;

- (instancetype)init;
- (instancetype)initWithKey:(NSString *)key;
- (instancetype)initDefaults;
Expand Down
18 changes: 13 additions & 5 deletions ably-ios/ARTAuthOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

#import "ARTAuthTokenDetails.h"

//X7: NSArray<NSString *>
static NSArray *decomposeKey(NSString *key) {
static __GENERIC(NSArray, NSString *) *decomposeKey(NSString *key) {
return [key componentsSeparatedByString:@":"];
}

Expand Down Expand Up @@ -57,13 +56,16 @@ - (id)copyWithZone:(NSZone *)zone {
options.authHeaders = self.authHeaders;
options.authParams = self.authParams;
options.queryTime = self.queryTime;
options.useTokenAuth = self.useTokenAuth;
options.force = self.force;
options.clientId = self.clientId;

return options;
}

- (NSString *)description {
return [NSString stringWithFormat: @"ARTAuthOptions: key=%@ token=%@ authUrl=%@ authMethod=%@ hasAuthCallback=%d",
self.key, self.token, self.authUrl, self.authMethod, self.authCallback != nil];
return [NSString stringWithFormat: @"%@: key=%@ token=%@ authUrl=%@ authMethod=%@ hasAuthCallback=%d",
NSStringFromClass([self class]), self.key, self.token, self.authUrl, self.authMethod, self.authCallback != nil];
}

- (NSString *)token {
Expand Down Expand Up @@ -99,12 +101,18 @@ - (ARTAuthOptions *)mergeWith:(ARTAuthOptions *)precedenceOptions {
merged.authParams = precedenceOptions.authParams;
if (precedenceOptions.queryTime)
merged.queryTime = precedenceOptions.queryTime;
if (precedenceOptions.useTokenAuth)
merged.useTokenAuth = precedenceOptions.useTokenAuth;
if (precedenceOptions.force)
merged.force = precedenceOptions.force;
if (precedenceOptions.clientId)
merged.clientId = precedenceOptions.clientId;

return merged;
}

- (BOOL)isBasicAuth {
return self.key != nil;
return self.key != nil && !self.useTokenAuth;
}

- (BOOL)isMethodPOST {
Expand Down
Loading