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

feat: Multiple Type-Safe Authentication Methods #68

Merged
merged 6 commits into from
Jun 18, 2018

Conversation

Andrew-Lees11
Copy link
Contributor

@Andrew-Lees11 Andrew-Lees11 commented Jun 11, 2018

Description

Added a new protocol TypeSafeMultiCredentials. A user can create a final class or struct that conforms to this protocol to add authentication to a route with multiple authentication methods. The user defines an array of TypeSafeCredentials and then this class will iterate through the array trying to authenticate. When one the authentications is successful the users type will initialize an instance of itself which is passed to the route handler.

Example of usage:

public struct MultiAuthedUser : TypeSafeMultiCredentials {

    public let id: String
    public let provider: String
    public let name: String?

    public static var authenticationMethods: [TypeSafeCredentials.Type] = [BasicAuthedUser.self, TokenAuthedUser.self]

    public init(successfulAuth: TypeSafeCredentials) {
        // Initialize common attributes of an authenticated user
        self.id = successfulAuth.id
        self.provider = successfulAuth.provider
        // Initialize extended attributes that depend on the type of authentication
        switch(successAuth.self) {
        case let tokenProfile as TokenAuthedUser:
            self.name = tokenProfile.name
        default:
            self.name = nil
        }
    }
}

router.get("/multiauth") { (userProfile: MultiAuthedUser, respondWith: (MultiAuthedUser?, RequestError?) -> Void) in
    print("authenticated \(userProfile.id) using \(userProfile.provider)")
    respondWith(userProfile, nil)
}

@codecov-io
Copy link

codecov-io commented Jun 11, 2018

Codecov Report

Merging #68 into master will increase coverage by 8.73%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #68      +/-   ##
==========================================
+ Coverage   58.15%   66.89%   +8.73%     
==========================================
  Files           6        7       +1     
  Lines         282      293      +11     
==========================================
+ Hits          164      196      +32     
+ Misses        118       97      -21
Flag Coverage Δ
#Credentials 66.89% <100%> (+8.73%) ⬆️
Impacted Files Coverage Δ
Sources/Credentials/TypeSafeCredentials.swift 67.74% <ø> (+67.74%) ⬆️
Sources/Credentials/MultiTypeSafeCredentials.swift 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4459dbf...a3e7ee1. Read the comment docs.

@djones6 djones6 changed the title feat: added TypeSafeMultiCredentials feat: Multiple Type-Safe Authentication Methods Jun 15, 2018
Copy link
Contributor

@djones6 djones6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I think we might want to tweak the example for init(successfulAuth:) a bit (see comments below)

This initalizer creates an instance of the type conforming to `TypeSafeMultiCredentials` from a successfully authenticated `TypeSafeCredentials` instance.
```swift
### Usage Example: ###
init(successfulAuth: TypeSafeCredentials) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be rewritten to initialize self.id and self.provider before the switch, and then initialize the more specific fields (in this case self.name) within each case.

self.name = googleProfile.name
default:
self.id = successfulAuth.id
self.provider = successfulAuth.provider
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example you are not initializing self.name in the default case - I presume that means it's an optional which takes an implicit nil value? It might be nicer for the example to explicitly set self.name = nil in the default case.

README.md Outdated
Within Codable routes, you implement a single credentials plugin by defining a Swift type that conforms to the plugins implementation of `TypeSafeCredentials`. This can then be applied to a codable route by defining it in the route signiture:

```swift
router.get("/authenticated") { (userProfile: ExampleAuth, respondWith: (ExampleAuth?, RequestError?) -> Void) in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be AuthedUser (or SingleAuthedUser) to be consistent with the multi-auth example below?

@djones6 djones6 merged commit 7fb7dc7 into master Jun 18, 2018
@djones6 djones6 deleted the typeSafeMultiCredentials branch June 18, 2018 15:16
@djones6 djones6 mentioned this pull request Jun 27, 2018
3 tasks
djones6 added a commit that referenced this pull request Jun 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants