-
Notifications
You must be signed in to change notification settings - Fork 0
/
PTPusherChannelServerBasedAuthorization.m
151 lines (117 loc) · 4.62 KB
/
PTPusherChannelServerBasedAuthorization.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// PTPusherChannelServerBasedAuthorization.m
// libPusher
//
// Created by Luke Redpath on 14/08/2011.
// Copyright 2011 LJR Software Limited. All rights reserved.
//
#import "PTPusherChannelServerBasedAuthorization.h"
#import "NSDictionary+QueryString.h"
#import "PTJSON.h"
#import "PTPusherChannel.h"
#import "PTPusher.h"
@implementation PTPusherChannelServerBasedAuthorization {
NSOperationQueue *authorizationQueue;
void (^_requestBlock)(PTPusherChannelAuthorizationOperation *, PTPusherChannel *);
}
- (id)initWithAuthorizationURL:(NSURL *)URL
{
if ((self = [super init])) {
_authorizationURL = URL;
authorizationQueue = [[NSOperationQueue alloc] init];
authorizationQueue.maxConcurrentOperationCount = 5;
authorizationQueue.name = @"com.pusher.libPusher.authorizationQueue";
}
return self;
}
- (void)customizeOperationsWithBlock:(void (^)(PTPusherChannelAuthorizationOperation *request, PTPusherChannel *))requestBlock
{
_requestBlock = [requestBlock copy];
}
- (void)pusherChannel:(PTPusherChannel *)channel requiresAuthorizationForSocketID:(NSString *)socketID completionHandler:(void (^)(BOOL, NSDictionary *, NSError *))completionHandler
{
PTPusherChannelAuthorizationOperation *authOperation = [PTPusherChannelAuthorizationOperation operationWithAuthorizationURL:self.authorizationURL channelName:channel.name socketID:socketID];
[authOperation setCompletionHandler:^(PTPusherChannelAuthorizationOperation *operation) {
completionHandler(operation.isAuthorized, operation.authorizationData, operation.error);
}];
if (_requestBlock) {
_requestBlock(authOperation, channel);
}
[authorizationQueue addOperation:authOperation];
}
@end
#pragma mark -
@interface PTPusherChannelAuthorizationOperation ()
@property (nonatomic, strong, readwrite) NSDictionary *authorizationData;
@property (nonatomic, readwrite) NSError *error;
@end
@implementation PTPusherChannelAuthorizationOperation {
NSDictionary *requestParameters;
}
- (NSMutableURLRequest *)mutableURLRequest
{
// we can be sure this is always mutable
return (NSMutableURLRequest *)URLRequest;
}
+ (id)operationWithAuthorizationURL:(NSURL *)URL channelName:(NSString *)channelName socketID:(NSString *)socketID
{
NSAssert(URL, @"URL is required for authorization! (Did you set PTPusher.authorizationURL?)");
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSMutableDictionary *requestParameters = [NSMutableDictionary dictionary];
[requestParameters setObject:socketID forKey:@"socket_id"];
[requestParameters setObject:channelName forKey:@"channel_name"];
return [[self alloc] initWithURLRequest:request parameters:requestParameters];
}
- (id)initWithURLRequest:(NSURLRequest *)request parameters:(NSDictionary *)parameters
{
if ((self = [super initWithURLRequest:request])) {
requestParameters = [parameters copy];
}
return self;
}
- (void)start
{
NSMutableDictionary *parameters = [requestParameters mutableCopy];
if (self.customRequestParameters) {
[parameters addEntriesFromDictionary:self.customRequestParameters];
}
[self.mutableURLRequest setHTTPBody:[[parameters sortedQueryString] dataUsingEncoding:NSUTF8StringEncoding]];
[super start];
}
- (void)finish
{
if (self.isCancelled) {
[super finish];
return;
}
if (self.connectionError) {
self.error = [NSError errorWithDomain:PTPusherErrorDomain code:PTPusherChannelAuthorizationConnectionError userInfo:@{NSUnderlyingErrorKey: self.connectionError}];
}
else {
_authorized = YES;
if ([URLResponse isKindOfClass:[NSHTTPURLResponse class]]) {
_authorized = ([(NSHTTPURLResponse *)URLResponse statusCode] == 200 || [(NSHTTPURLResponse *)URLResponse statusCode] == 201);
}
if (_authorized) {
_authorizationData = [[PTJSON JSONParser] objectFromJSONData:responseData];
if (![_authorizationData isKindOfClass:[NSDictionary class]]) {
NSDictionary *userInfo = nil;
if (_authorizationData) { // make sure it isn't nil as a result of invalid JSON first
userInfo = @{@"reason": @"Authorization data was not a dictionary", @"authorization_data": _authorizationData};
}
else {
userInfo = @{@"reason": @"Authorization data was not valid JSON"};
}
self.error = [NSError errorWithDomain:PTPusherErrorDomain code:PTPusherChannelAuthorizationBadResponseError userInfo:userInfo];
_authorized = NO;
}
}
}
if (self.completionHandler) {
self.completionHandler(self);
}
[super finish];
}
@end