Skip to content

Commit 4e14187

Browse files
committed
some work on oauth + dummy module definition for common crypto
1 parent 2d1052e commit 4e14187

File tree

17 files changed

+574
-65
lines changed

17 files changed

+574
-65
lines changed

.gitmodules

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[submodule "Carthage/Checkouts/Quick"]
2+
path = Carthage/Checkouts/Quick
3+
url = https://github.com/Quick/Quick.git
4+
[submodule "Carthage/Checkouts/Alamofire"]
5+
path = Carthage/Checkouts/Alamofire
6+
url = https://github.com/Alamofire/Alamofire.git
7+
[submodule "Carthage/Checkouts/Nimble"]
8+
path = Carthage/Checkouts/Nimble
9+
url = https://github.com/Quick/Nimble.git

AlamofireOAuth1.xcodeproj/project.pbxproj

Lines changed: 273 additions & 36 deletions
Large diffs are not rendered by default.

AlamofireOAuth1/AlamofireOAuth1.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,4 @@ FOUNDATION_EXPORT double AlamofireOAuth1VersionNumber;
1414
//! Project version string for AlamofireOAuth1.
1515
FOUNDATION_EXPORT const unsigned char AlamofireOAuth1VersionString[];
1616

17-
// In this header, you should import all the public headers of your framework using statements like #import <AlamofireOAuth1/PublicHeader.h>
18-
19-
17+
// In this header, you should import all the public headers of your framework using statements like #import <AlamofireOAuth1/PublicHeader.h>

AlamofireOAuth1/OAuth1.swift

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
//
2+
// OAuth1.swift
3+
// AlamofireOAuth1
4+
//
5+
// Created by Hakon Hanesand on 4/27/15.
6+
// Copyright (c) 2015 Hakon Hanesand. All rights reserved.
7+
8+
import Alamofire
9+
import CommonCrypto
10+
11+
extension Dictionary {
12+
mutating func merge<K, V>(dict: [K: V]){
13+
for (k, v) in dict {
14+
self.updateValue(v as! Value, forKey: k as! Key)
15+
}
16+
}
17+
}
18+
19+
//from http://stackoverflow.com/a/24888789/4080860
20+
extension String {
21+
func stringByAddingPercentEncodingForFormUrlencoded() -> String? {
22+
let characterSet = NSMutableCharacterSet.alphanumericCharacterSet()
23+
characterSet.addCharactersInString("-._* ")
24+
25+
return stringByAddingPercentEncodingWithAllowedCharacters(characterSet)?.stringByReplacingOccurrencesOfString(" ", withString: "+")
26+
}
27+
28+
func indexOf(target: String) -> Int {
29+
var range = self.rangeOfString(target)
30+
31+
if let range = range {
32+
return distance(self.startIndex, range.startIndex)
33+
} else {
34+
return -1
35+
}
36+
}
37+
}
38+
39+
public enum Factual: URLRequestConvertible {
40+
41+
static let baseURLString = "http://api.v3.factual.com/t/"
42+
43+
static let clientId = "n5md5zTCv67RV2ctEQKrhK2cAzggCqs3khynDhKT"
44+
static let clientSecret = "Utn7HYXJ77lW3fTYMFiB9Zvu0GjT1AInnjeqYFct"
45+
46+
case GetBarcode(String)
47+
48+
var method: Alamofire.Method {
49+
switch self {
50+
case .GetBarcode:
51+
return .GET
52+
}
53+
}
54+
55+
var path: String {
56+
switch self {
57+
case .GetBarcode:
58+
return "products-cpg"
59+
}
60+
}
61+
62+
public var URLRequest: NSURLRequest {
63+
let URL = NSURL(string: Factual.baseURLString)!
64+
let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path))
65+
mutableURLRequest.HTTPMethod = method.rawValue;
66+
var parameters = OAuth.constructOAuthParametersWith(ClientId: Factual.clientId, clientSecret: Factual.clientSecret, tokenId: nil, tokenSecret: nil)
67+
68+
switch self {
69+
case .GetBarcode(let barcode):
70+
parameters.merge(["q" : barcode])
71+
let request = OAuth.process(Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters)).0
72+
73+
//we want to build the OAuth signature base string described here http://nouncer.com/oauth/authentication.html
74+
75+
let indexOfQueryParameters = request.URLString.rangeOfString("?")!.startIndex
76+
77+
let urlString = request.URLString.substringToIndex(indexOfQueryParameters)
78+
let queryParameters = request.URLString.substringFromIndex(advance(indexOfQueryParameters, 1)) //exclude ? in string
79+
let encodedQueryParameters = queryParameters.stringByAddingPercentEncodingForFormUrlencoded()!
80+
81+
let oauthBaseString = "\(Alamofire.Method.GET.rawValue)&\(urlString)&\(encodedQueryParameters)"
82+
83+
let oauthRequestKey = "\(Factual.clientSecret)&"
84+
85+
let key = oauthRequestKey.cStringUsingEncoding(NSUTF8StringEncoding)
86+
let text = oauthBaseString.cStringUsingEncoding(NSUTF8StringEncoding)
87+
// let digestLength =
88+
89+
90+
return request
91+
}
92+
}
93+
}
94+
95+
public extension NSMutableURLRequest {
96+
97+
98+
}
99+
100+
101+
public class OAuth {
102+
103+
private struct Variables { //class vars not supported yet
104+
static let nonceHistory: Set<String> = []
105+
static var previousTimestamp: String = ""
106+
static var timestamp: String = ""
107+
}
108+
109+
private class var previousTimestamp: String {
110+
get {return Variables.previousTimestamp}
111+
set {Variables.previousTimestamp = newValue}
112+
}
113+
114+
private class var timestamp: String {
115+
var time = timeval()
116+
gettimeofday(&time, nil)
117+
118+
Variables.previousTimestamp = Variables.timestamp
119+
Variables.timestamp = "\(time.tv_sec)"
120+
return Variables.timestamp
121+
}
122+
123+
private class var nonceHistory: Set<String> {
124+
return Variables.nonceHistory
125+
}
126+
127+
public class func generateNonceAndTimestamp() -> (nonce: String, timestamp: String) {
128+
var nonce: String
129+
var timestamp: String
130+
131+
do {
132+
timestamp = self.timestamp;
133+
134+
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
135+
let length = UInt32(count(letters))
136+
137+
nonce = (0..<32).map { (_) in letters[advance(letters.startIndex, Int(arc4random_uniform(length)))]}
138+
.reduce("") { (string, char) in string + [char]}
139+
140+
141+
} while timestamp != previousTimestamp && nonceHistory.contains(nonce)
142+
143+
return (nonce, timestamp)
144+
}
145+
146+
struct Constants {
147+
static let OAuthVersionKey = "oauth_version"
148+
static let OAuthVersion = "1.0"
149+
150+
static let OAuthConsumerIdentifierKey = "oauth_consumer_key"
151+
static let OAuthTokenIdentifierKey = "oauth_token"
152+
153+
static let OAuthSignatureMethod = "HMAC-SHA1"
154+
static let OAuthSignatureMethodKey = "oauth_signature_method"
155+
156+
static let OAuthTimestampKey = "oauth_timestamp"
157+
static let OAuthNonceKey = "oauth_nonce"
158+
}
159+
160+
public class func constructOAuthParametersWith(ClientId clientId: String, clientSecret: String, tokenId: String?, tokenSecret: String?) -> [String : AnyObject] {
161+
var parameters = [String : AnyObject]()
162+
163+
if let tokenId = tokenId {
164+
parameters.updateValue(tokenId, forKey: Constants.OAuthTokenIdentifierKey)
165+
}
166+
167+
parameters.updateValue(Constants.OAuthVersion, forKey: Constants.OAuthVersionKey)
168+
parameters.updateValue(Constants.OAuthSignatureMethod, forKey: Constants.OAuthSignatureMethodKey)
169+
parameters.updateValue(clientId, forKey: Constants.OAuthConsumerIdentifierKey)
170+
171+
let (nonce, timestamp) = OAuth.generateNonceAndTimestamp()
172+
parameters.updateValue(nonce, forKey: Constants.OAuthNonceKey)
173+
parameters.updateValue(timestamp, forKey: Constants.OAuthTimestampKey)
174+
175+
return parameters
176+
}
177+
178+
public class func process(tuple: (NSURLRequest, NSError?)) -> (NSURLRequest, NSError?) {
179+
let mutableCopy = tuple.0.mutableCopy() as! NSMutableURLRequest
180+
return (tuple.0, tuple.1)
181+
}
182+
}
183+
184+
public enum OAuth1SignatureMethod {
185+
case PlainText
186+
case HMAC_SHA1
187+
}
188+

AlamofireOAuth1Tests/AlamofireOAuth1Tests.swift

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,36 @@
22
// AlamofireOAuth1Tests.swift
33
// AlamofireOAuth1Tests
44
//
5-
// Created by Hakon Hanesand on 4/27/15.
5+
// Created by Hakon Hanesand on 4/28/15.
66
// Copyright (c) 2015 Hakon Hanesand. All rights reserved.
7-
//
87

8+
import Quick
9+
import Nimble
10+
import AlamofireOAuth1
11+
import Alamofire
912
import UIKit
10-
import XCTest
1113

12-
class AlamofireOAuth1Tests: XCTestCase {
13-
14-
override func setUp() {
15-
super.setUp()
16-
// Put setup code here. This method is called before the invocation of each test method in the class.
17-
}
18-
19-
override func tearDown() {
20-
// Put teardown code here. This method is called after the invocation of each test method in the class.
21-
super.tearDown()
22-
}
23-
24-
func testExample() {
25-
// This is an example of a functional test case.
26-
XCTAssert(true, "Pass")
27-
}
28-
29-
func testPerformanceExample() {
30-
// This is an example of a performance test case.
31-
self.measureBlock() {
32-
// Put the code you want to measure the time of here.
14+
class OAuthSpec: QuickSpec {
15+
override func spec() {
16+
describe("The OAuth1 Specification") {
17+
describe("nonce generation") {
18+
it("generates a unique stream of strings that have length 32") {
19+
var set: Set<String> = []
20+
21+
for index in 1...100 {
22+
let nonce = OAuth.generateNonceAndTimestamp().nonce
23+
24+
expect(set.contains(nonce)).toNot(beTrue())
25+
expect(count(nonce)).to(equal(32))
26+
}
27+
}
28+
}
29+
30+
describe("OAuth Request Setup") {
31+
it("should properly configure an NSURLRequest with OAuth headers") {
32+
var request = Alamofire.request(Factual.GetBarcode("barcodeHERE"))
33+
}
34+
}
3335
}
3436
}
35-
36-
}
37+
}

Cartfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github "Alamofire/Alamofire"

Cartfile.private

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github "Quick/Quick"
2+
github "Quick/Nimble"

Cartfile.resolved

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
github "Alamofire/Alamofire" "1.2.1"
2+
github "Quick/Nimble" "v0.4.2"
3+
github "Quick/Quick" "v0.3.1"

Carthage/Checkouts/Alamofire

Submodule Alamofire added at 9faceea

Carthage/Checkouts/Nimble

Submodule Nimble added at 8927113

0 commit comments

Comments
 (0)