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

NativeAuth provider check and fallback in Auth0OAuth2Interactor #418

Merged
merged 4 commits into from
Apr 4, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "auth0/Auth0.swift" ~> 1.4
github "auth0/Auth0.swift" ~> 1.5
4 changes: 2 additions & 2 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github "auth0/Auth0.swift" "1.4.0"
github "auth0/Auth0.swift" "1.5.0"
github "emaloney/CleanroomLogger" "5.0.3"
github "Quick/Nimble" "v6.0.1"
github "Quick/Nimble" "v6.1.0"
github "AliSoftware/OHHTTPStubs" "5.2.3-swift3"
github "Quick/Quick" "v1.1.0"
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.0)
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
aws-sdk (2.8.11)
aws-sdk-resources (= 2.8.11)
Expand Down Expand Up @@ -73,7 +73,7 @@ GEM
faraday_middleware (0.11.0.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.0)
fastlane (2.23.0)
fastlane (2.24.0)
activesupport (< 5)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
Expand Down Expand Up @@ -205,4 +205,4 @@ DEPENDENCIES
xcpretty-travis-formatter

BUNDLED WITH
1.14.5
1.14.6
2 changes: 1 addition & 1 deletion Lock.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Auth0 is a SaaS that helps you with Authentication and Authorization. You can us
s.requires_arc = true


s.dependency 'Auth0', '~> 1.2'
s.dependency 'Auth0', '~> 1.5'
s.default_subspecs = 'Classic'

s.subspec 'Classic' do |classic|
Expand Down
4 changes: 2 additions & 2 deletions Lock/Auth0OAuth2Interactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
import Foundation
import Auth0

struct Auth0OAuth2Interactor: OAuth2Authenticatable {
struct Auth0OAuth2Interactor: OAuth2Authenticatable, Loggable {

let authentication: Authentication
let dispatcher: Dispatcher
let options: Options
let nativeHandlers: [String: AuthProvider]

func login(_ connection: String, loginHint: String?, callback: @escaping (OAuth2AuthenticatableError?) -> Void) {
if let nativeHandler = self.nativeHandlers[connection] {
if let nativeHandler = self.nativeHandlers[connection], type(of: nativeHandler).isAvailable() {
self.nativeAuth(withConnection: connection, nativeAuth: nativeHandler, callback: callback)
} else {
self.webAuth(withConnection: connection, loginHint: loginHint, callback: callback)
Expand Down
33 changes: 25 additions & 8 deletions LockTests/Interactors/Auth0OAuth2InteractorSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,51 +70,51 @@ class Auth0OAuth2InteractorSpec: QuickSpec {

it("should set connection") {
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.connection) == "facebook"
expect(authentication.webAuth?.connection) == "facebook"
}

it("should set scope") {
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.scope) == "openid"
expect(authentication.webAuth?.scope) == "openid"
}

it("should set connection scope for specified connection") {
options.connectionScope = ["facebook": "user_friends,email"]
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.parameters["connection_scope"]) == "user_friends,email"
expect(authentication.webAuth?.parameters["connection_scope"]) == "user_friends,email"
}

it("should set connection scope for matching connections only") {
options.connectionScope = ["facebook": "user_friends,email",
"google-oauth2": "gmail,ads"]
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.parameters["connection_scope"]) == "user_friends,email"
expect(authentication.webAuth?.parameters["connection_scope"]) == "user_friends,email"
interactor.login("google-oauth2", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.parameters["connection_scope"]) == "gmail,ads"
expect(authentication.webAuth?.parameters["connection_scope"]) == "gmail,ads"
}

it("should not set audience if nil") {
options.audience = nil
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.audience).to(beNil())
expect(authentication.webAuth?.audience).to(beNil())
}

it("should set audience") {
options.audience = "https://myapi.com/v1"
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.audience) == "https://myapi.com/v1"
expect(authentication.webAuth?.audience) == "https://myapi.com/v1"
}

it("should set parameters") {
let state = UUID().uuidString
options.parameters = ["state": state as Any]
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
interactor.login("facebook", loginHint: nil, callback: { _ in })
expect(authentication.webAuth.parameters["state"]) == state
expect(authentication.webAuth?.parameters["state"]) == state
}

it("should not yield error on success") {
Expand Down Expand Up @@ -177,6 +177,23 @@ class Auth0OAuth2InteractorSpec: QuickSpec {
_ = authHandler.transaction.resume(DomainURL, options: [:])
}
}

context("native provider unavailable") {

beforeEach {
MockNativeAuthHandler.validProvider = false
authentication.webAuth = nil
nativeHandlers.removeAll()
nativeHandlers["twitter"] = authHandler
interactor = Auth0OAuth2Interactor(authentication: authentication, dispatcher: dispatcher, options: options, nativeHandlers: nativeHandlers)
}

it("should fallback to webAuth with connection") {
interactor.login("twitter", loginHint: nil, callback: { _ in })
expect(authentication.webAuth?.connection) == "twitter"
}

}

}
}
Expand Down
12 changes: 9 additions & 3 deletions LockTests/Utils/Mocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ class MockAuthentication: Authentication {

var telemetry: Telemetry

var webAuth: MockWebAuth!
var webAuth: MockWebAuth?

var webAuthResult: () -> Auth0.Result<Credentials> = { _ in return Auth0.Result.failure(error: AuthenticationError(string: "FAILED", statusCode: 500)) }

required init(clientId: String, domain: String) {
Expand All @@ -248,8 +249,8 @@ class MockAuthentication: Authentication {
func webAuth(withConnection connection: String) -> WebAuth {
let mockWebAuth = MockWebAuth().connection(connection)
self.webAuth = mockWebAuth.connection(connection)
self.webAuth.result = self.webAuthResult
return self.webAuth
self.webAuth?.result = self.webAuthResult
return self.webAuth!
}

func tokenInfo(token: String) -> Request<Profile, AuthenticationError> {
Expand Down Expand Up @@ -386,12 +387,17 @@ class MockNativeAuthHandler: AuthProvider {

var transaction: MockNativeAuthTransaction!
var authentication: Authentication!
static var validProvider: Bool = true

func login(withConnection connection: String, scope: String, parameters: [String : Any]) -> NativeAuthTransaction {
let transaction = MockNativeAuthTransaction(connection: connection, scope: scope, parameters: parameters, authentication: self.authentication)
self.transaction = transaction
return transaction
}

static func isAvailable() -> Bool {
return MockNativeAuthHandler.validProvider
}
}

class MockNativeAuthTransaction: NativeAuthTransaction {
Expand Down