Skip to content

Commit

Permalink
Merge pull request #2 from Hexaville/v0.2
Browse files Browse the repository at this point in the history
v0.2
  • Loading branch information
noppoMan committed Jun 25, 2017
2 parents 6409e25 + b97a7e9 commit da758ca
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 88 deletions.
56 changes: 55 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ let facebookProvider = FacebookAuthorizationProvider(

auth.add(facebookProvider)

app.use(auth.asRouter())
app.use(auth)

app.catch { error in
switch error {
Expand All @@ -87,6 +87,60 @@ app.catch { error in
try app.run()
```

## Getting loginUser object on the every requests.

If you register `HexavilleAuth.AuthenticationMiddleware` and loginUser information is stored in the session, You can get it from `ApplicationContext` as `LoginUser` Object.

### LoginUser
```swift
public struct LoginUser {
public let id: String
public let name: String
public let screenName: String?
public let email: String?
public let picture: String?
public let raw: [String: Any]
}
```

### Example

```swift
import Foundation
import HexavilleAuth
import HexavilleFramework

let app = HexavilleFramework()

var auth = HexavilleAuth()

let APP_URL = ProcessInfo.processInfo.environment["APP_URL"] ?? "http://localhost:3000"

let twitterProvider = TwitterAuthorizationProvider(
path: "/auth/twitter",
consumerKey: ProcessInfo.processInfo.environment["TWITTER_APP_ID"] ?? "",
consumerSecret: ProcessInfo.processInfo.environment["TWITTER_APP_SECRET"] ?? "",
callbackURL: CallbackURL(baseURL: APP_URL, path: "/auth/twitter/callback"),
scope: ""
) { credential, user, request, context in
return Response(body: "\(user)")
}

app.use(HexavilleAuth.AuthenticationMiddleware()) // register to get loginUser Object

app.use { req, context in
print(context.isAuthenticated()) // => true
print(context.loginUser) // Get the loginUser object
return .next(req)
}

auth.add(twitterProvider)

app.use(auth)

try app.run()
```

## Try Example!

[Here is an official full example code](https://github.com/Hexaville/HexavilleAuth/blob/master/Sources/HexavilleAuthExample/main.swift).
Expand Down
29 changes: 29 additions & 0 deletions Sources/HexavilleAuth/AuthenticationMiddleware.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// AuthenticationMiddleware.swift
// HexavilleAuth
//
// Created by Yuki Takei on 2017/06/25.
//
//

import Foundation
import HexavilleFramework


extension HexavilleAuth {
public struct AuthenticationMiddleware: Middleware {

public init(){}

static var sessionKey = "hexaville.auth.loginUser"

public func respond(to request: Request, context: ApplicationContext) throws -> Chainer {
if let dict = context.session?[AuthenticationMiddleware.sessionKey] as? [String: Any] {
context.loginUser = try LoginUser(fromDictionary: dict)
}

return .next(request)
}
}

}
95 changes: 11 additions & 84 deletions Sources/HexavilleAuth/HexaviileAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,6 @@ public enum CredentialProviderType {
case oauth1(OAuth1AuthorizationProvidable)
}

extension ApplicationContext {
public func isAuthenticated() -> Bool {
return loginUser != nil
}

public var loginUser: LoginUser? {
get {
return memory[AuthenticationMiddleware.sessionKey] as? LoginUser
}
set {
return memory[AuthenticationMiddleware.sessionKey] = newValue
}
}
}

public struct AuthenticationMiddleware: Middleware {

static var sessionKey = "hexaville.auth.loginUser"

public func respond(to request: Request, context: ApplicationContext) throws -> Chainer {
if let dict = context.session?[AuthenticationMiddleware.sessionKey] as? [String: Any] {
context.loginUser = try LoginUser(fromDictionary: dict)
}

return .next(request)
}
}

public struct HexavilleAuth {
var providers: [CredentialProviderType] = []

Expand All @@ -52,64 +24,19 @@ public struct HexavilleAuth {
public mutating func add(_ provider: OAuth2AuthorizationProvidable) {
self.providers.append(.oauth2(provider))
}

public func authenticationMiddleware() -> Middleware {
return AuthenticationMiddleware()
}

extension ApplicationContext {
public func isAuthenticated() -> Bool {
return loginUser != nil
}

public func asRouter() -> Router {
let router = Router()
for type in providers {
switch type {
case .oauth1(let provider):
router.use(.get, provider.path) { request, context in
let requestToken = try provider.getRequestToken()
context.session?["hexaville.oauth_token_secret"] = requestToken.oauthTokenSecret
context.session?["hexaville.oauth_token"] = requestToken.oauthToken
let location = try provider.createAuthorizeURL(requestToken: requestToken).absoluteString

return Response(status: .found, headers: ["Location": location])
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
guard let secret = context.session?["hexaville.oauth_token_secret"] as? String else {
throw OAuth1Error.accessTokenIsMissingInSession
}

guard let token = context.session?["hexaville.oauth_token"] as? String else {
throw OAuth1Error.accessTokenIsMissingInSession
}

let requestToken = RequestToken(
oauthToken: token,
oauthTokenSecret: secret,
oauthCallbackConfirmed: nil
)

let (cred, user) = try provider.authorize(request: request, requestToken: requestToken)
context.session?[AuthenticationMiddleware.sessionKey] = user.serialize()
return try provider.callback(cred, user, request, context)
}


case .oauth2(let provider):
router.use(.get, provider.path) { request, context in
return Response(
status: .found,
headers: [
"Location": try provider.createAuthorizeURL().absoluteString
]
)
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
let (cred, user) = try provider.authorize(request: request)
context.session?[AuthenticationMiddleware.sessionKey] = user.serialize()
return try provider.callback(cred, user, request, context)
}
}
public var loginUser: LoginUser? {
get {
return memory[HexavilleAuth.AuthenticationMiddleware.sessionKey] as? LoginUser
}
set {
return memory[HexavilleAuth.AuthenticationMiddleware.sessionKey] = newValue
}

return router
}
}
74 changes: 74 additions & 0 deletions Sources/HexavilleAuth/HexavilleAuth+Router.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// HexavilleAuth+Router.swift
// HexavilleAuth
//
// Created by Yuki Takei on 2017/06/25.
//
//

import Foundation
import HexavilleFramework

extension HexavilleAuth {
func asRouter() -> Router {
let router = Router()
for type in providers {
switch type {
case .oauth1(let provider):
router.use(.get, provider.path) { request, context in
let requestToken = try provider.getRequestToken()
context.session?["hexaville.oauth_token_secret"] = requestToken.oauthTokenSecret
context.session?["hexaville.oauth_token"] = requestToken.oauthToken
let location = try provider.createAuthorizeURL(requestToken: requestToken).absoluteString

return Response(status: .found, headers: ["Location": location])
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
guard let secret = context.session?["hexaville.oauth_token_secret"] as? String else {
throw OAuth1Error.accessTokenIsMissingInSession
}

guard let token = context.session?["hexaville.oauth_token"] as? String else {
throw OAuth1Error.accessTokenIsMissingInSession
}

let requestToken = RequestToken(
oauthToken: token,
oauthTokenSecret: secret,
oauthCallbackConfirmed: nil
)

let (cred, user) = try provider.authorize(request: request, requestToken: requestToken)
context.session?[AuthenticationMiddleware.sessionKey] = user.serialize()
return try provider.callback(cred, user, request, context)
}


case .oauth2(let provider):
router.use(.get, provider.path) { request, context in
return Response(
status: .found,
headers: [
"Location": try provider.createAuthorizeURL().absoluteString
]
)
}

router.use(.get, provider.oauth.callbackURL.path) { request, context in
let (cred, user) = try provider.authorize(request: request)
context.session?[AuthenticationMiddleware.sessionKey] = user.serialize()
return try provider.callback(cred, user, request, context)
}
}
}

return router
}
}

extension HexavilleFramework {
public func use(_ auth: HexavilleAuth) {
self.use(auth.asRouter())
}
}
5 changes: 2 additions & 3 deletions Sources/HexavilleAuthExample/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,9 @@ auth.add(googleProvider)
auth.add(instagramProvider)
auth.add(twitterProvider)

app.use(auth.authenticationMiddleware())

app.use(auth.asRouter())
app.use(HexavilleAuth.AuthenticationMiddleware())

app.use(auth)

let router = Router()

Expand Down

0 comments on commit da758ca

Please sign in to comment.