Skip to content

Commit

Permalink
[Encoding] Introduce a builder pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
kylef committed Apr 5, 2015
1 parent 2b5bc6c commit 7455c9d
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
76 changes: 76 additions & 0 deletions JWT/JWT.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,79 @@ public func encode(payload:Payload, algorithm:Algorithm) -> String {
let signature = algorithm.sign(signingInput)
return "\(signingInput).\(signature)"
}

public class PayloadBuilder {
var payload = Payload()

public var issuer:String? {
get {
return payload["iss"] as? String
}
set {
payload["iss"] = newValue
}
}

public var audience:String? {
get {
return payload["aud"] as? String
}
set {
payload["aud"] = newValue
}
}

public var expiration:NSDate? {
get {
if let expiration = payload["exp"] as? NSTimeInterval {
return NSDate(timeIntervalSince1970: expiration)
}

return nil
}
set {
payload["exp"] = newValue?.timeIntervalSince1970
}
}

public var notBefore:NSDate? {
get {
if let notBefore = payload["nbf"] as? NSTimeInterval {
return NSDate(timeIntervalSince1970: notBefore)
}

return nil
}
set {
payload["nbf"] = newValue?.timeIntervalSince1970
}
}

public var issuedAt:NSDate? {
get {
if let issuedAt = payload["iat"] as? NSTimeInterval {
return NSDate(timeIntervalSince1970: issuedAt)
}

return nil
}
set {
payload["iat"] = newValue?.timeIntervalSince1970
}
}

public subscript(key: String) -> AnyObject? {
get {
return payload[key]
}
set {
payload[key] = newValue
}
}
}

public func encode(algorithm:Algorithm, closure:(PayloadBuilder -> ())) -> String {
let builder = PayloadBuilder()
closure(builder)
return encode(builder.payload, algorithm)
}
63 changes: 63 additions & 0 deletions JWTTests/JWTTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,69 @@ class JWTEncodeTests : XCTestCase {
let fixture = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiS3lsZSJ9.zxm7xcp1eZtZhp4t-nlw09ATQnnFKIiSN83uG8u6cAg"
XCTAssertEqual(jwt, fixture)
}

func testEncodingWithBuilder() {
let algorithm = Algorithm.HS256("secret")
let jwt = JWT.encode(algorithm) { builder in
builder.issuer = "fuller.li"
}

assertSuccess(JWT.decode(jwt, algorithm)) { payload in
XCTAssertEqual(payload as NSDictionary, ["iss": "fuller.li"])
}
}
}

class JWTPayloadBuilder : XCTestCase {
func testIssuer() {
JWT.encode(.None) { builder in
builder.issuer = "fuller.li"
XCTAssertEqual(builder.issuer!, "fuller.li")
XCTAssertEqual(builder["iss"] as String, "fuller.li")
}
}

func testAudience() {
JWT.encode(.None) { builder in
builder.audience = "cocoapods"
XCTAssertEqual(builder.audience!, "cocoapods")
XCTAssertEqual(builder["aud"] as String, "cocoapods")
}
}

func testExpiration() {
JWT.encode(.None) { builder in
let date = NSDate(timeIntervalSince1970: NSDate().timeIntervalSince1970)
builder.expiration = date
XCTAssertEqual(builder.expiration!, date)
XCTAssertEqual(builder["exp"] as NSTimeInterval, date.timeIntervalSince1970)
}
}

func testNotBefore() {
JWT.encode(.None) { builder in
let date = NSDate(timeIntervalSince1970: NSDate().timeIntervalSince1970)
builder.notBefore = date
XCTAssertEqual(builder.notBefore!, date)
XCTAssertEqual(builder["nbf"] as NSTimeInterval, date.timeIntervalSince1970)
}
}

func testIssuedAt() {
JWT.encode(.None) { builder in
let date = NSDate(timeIntervalSince1970: NSDate().timeIntervalSince1970)
builder.issuedAt = date
XCTAssertEqual(builder.issuedAt!, date)
XCTAssertEqual(builder["iat"] as NSTimeInterval, date.timeIntervalSince1970)
}
}

func testCustomAttributes() {
JWT.encode(.None) { builder in
builder["user"] = "kyle"
XCTAssertEqual(builder["user"] as String, "kyle")
}
}
}

class JWTDecodeTests : XCTestCase {
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ import JWT
JWT.encode(["my": "payload"], .HS256("secret"))
```

#### Building a JWT with the builder pattern

```swift
JWT.encode(.HS256("secret")) { builder in
builder.issuer = "fuller.li"
builder.issuedAt = NSDate()
builder["custom"] = "Hi"
}
```

### Decoding a JWT

When decoding a JWT, you must supply one or more algorithms and keys.
Expand Down

0 comments on commit 7455c9d

Please sign in to comment.