Skip to content

feat: Add basic, google token and facebook token authentication#33

Merged
djones6 merged 14 commits intodevelopfrom
authentication
Jun 27, 2018
Merged

feat: Add basic, google token and facebook token authentication#33
djones6 merged 14 commits intodevelopfrom
authentication

Conversation

@Andrew-Lees11
Copy link
Copy Markdown
Contributor

Pull request to add client side authentication to KituraKIt

The user adds their authentication to the client using either:

client.addBasicAuth(username: username, password: password)
client.addFacebookToken(token)
client.addGoogleToken(token)

The correct headers will then be added to all requests to allow authentication with the corresponding TypeSafeMiddlewares on Kitura.

This required internal fields for the request headers and Credentials be added to KituraKit and these are then added to the client request before it is sent.

Docs and tests have been added to cover these changes.

@codecov-io
Copy link
Copy Markdown

codecov-io commented Jun 15, 2018

Codecov Report

Merging #33 into develop will increase coverage by 4.46%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #33      +/-   ##
===========================================
+ Coverage    80.15%   84.61%   +4.46%     
===========================================
  Files            2        3       +1     
  Lines          131      169      +38     
===========================================
+ Hits           105      143      +38     
  Misses          26       26
Flag Coverage Δ
#KituraKit 84.61% <100%> (+4.46%) ⬆️
Impacted Files Coverage Δ
Sources/KituraKit/ClientCredentials.swift 100% <100%> (ø)
Sources/KituraKit/Client.swift 85.71% <100%> (+2.38%) ⬆️

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 7d86140...2b3034f. Read the comment docs.


/// Generate headers for a authenticating with a Facebook oauth token
/// - Parameter token: The Facebook oauth token
public static func facebookToken(_ token: String) -> [String: String] {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

getFacebookAuthHeaders(token:)?


/// Generate headers for a authenticating with a Google oauth token
/// - Parameter token: The Google oauth token
public static func googleToken(_ token: String) -> [String: String] {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

getGoogleAuthHeaders(token:)?

/// Generate headers for a authenticating with a username and password using HTTP basic
/// - Parameter username: The unique user id that identifies the user
/// - Parameter password: The password for the given username
public static func HTTPBasic(username: String, password: String) -> [String: String] {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

getHTTPBasicAuthHeaders(username:password:)?

/// Generate headers for a authenticating with a Facebook oauth token
/// - Parameter token: The Facebook oauth token
public static func facebookToken(_ token: String) -> [String: String] {
return(["X-token-type": "FacebookToken", "access_token": token])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove parentheses.

/// Generate headers for a authenticating with a Google oauth token
/// - Parameter token: The Google oauth token
public static func googleToken(_ token: String) -> [String: String] {
return(["X-token-type": "GoogleToken", "access_token": token])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove parentheses.

public static func HTTPBasic(username: String, password: String) -> [String: String] {
let authData = (username + ":" + password).data(using: .utf8)!
let authString = authData.base64EncodedString()
return(["Authorization": "Basic \(authString)"])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove parentheses.

import SwiftyRequest
import KituraContracts

public struct AuthHeaders {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this might be better called AuthHelpers

* limitations under the License.
**/

import Foundation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove this, it's a duplicate. And are all the others actually used?

Copy link
Copy Markdown
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.

I'd prefer us to have a protocol ClientAuthentication which defines something like func getHeaders() -> [String: String].

Then concrete implementations for each type (GoogleToken, FacebookToken, HTTPBasic) which init either from a token or a username and password. Then the user passes an instance of one of these types to an authentication: ClientAuthentication param on the client.

You could still have the default auth as an optional ClientAuthentication.

Copy link
Copy Markdown
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.

The refactor looks much nicer, I like this. Two points:

  1. Rename to get rid of the redundant Auth / remove abbreviation as per comments above
  2. All of the public entities should be documented (the getHeaders() and especially the ClientAuthentication protocol itself).

Actually, as discussed, let's go with ClientCredentials, defaultCredentials and credentials: as 'credentials' represents the data, 'authentication' represents the process.

/// Generate headers for a authenticating with a username and password using HTTP basic
/// - Parameter username: The unique user id that identifies the user
/// - Parameter password: The password for the given username
public struct HTTPBasicAuth: ClientAuth {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just HTTPBasic, I don't like the abbreviation. Since the type implements ClientAuthentication and the creation context is in an authentication: parameter or defaultAuthentication property, including 'Authentication' in the name is a bit redundant.


/// Generate headers for a authenticating with a Facebook oauth token
/// - Parameter token: The Facebook oauth token
public struct FacebookTokenAuth: ClientAuth {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FacebookToken please


/// Generate headers for a authenticating with a Google oauth token
/// - Parameter token: The Google oauth token
public struct GoogleTokenAuth: ClientAuth {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

GoogleToken please

}
}

public protocol ClientAuth {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ClientAuthentication please

public let baseURL: URL

/// Headers that will be used if none are provided to the route
public static var defaultAuth: ClientAuth?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

defaultAuthentication (no need to abbreviate)

*/
public protocol ClientCredentials {

/// Function to generate headers that will be added to the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit-pick: the function doesn't have to generate the headers, they could have been generated at initialization time, in which case this would be a simple getter. However, I think this is close enough.

Copy link
Copy Markdown
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.

Public initializers required, otherwise importers of KituraKit cannot create the credentials types.

}
```
*/
public struct HTTPBasic: ClientCredentials {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This struct needs a public initializer. The one that the compiler generates is internal (so importers of KituraKit cannot instantiate an HTTPBasic).

}
```
*/
public struct FacebookToken: ClientCredentials {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Needs public initializer

}
```
*/
public struct GoogleToken: ClientCredentials {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Needs public initializer

/// let client = KituraKit.default
/// client.defaultCredentials = HTTPBasic(username: "John", password: "12345")
/// ```
public static var defaultCredentials: ClientCredentials?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This (probably) shouldn't be static?
The example doesn't compile (has to say KituraKit.defaultCredentials), at which point all clients would share the same default credentials.

}
```
*/
public struct NilCredentials: ClientCredentials {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this need a public initializer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤦‍♂️

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hang on... it has one already (line 181)

@Andrew-Lees11
Copy link
Copy Markdown
Contributor Author

LGTM

@djones6 djones6 merged commit d154c8a into develop Jun 27, 2018
@djones6 djones6 deleted the authentication branch June 27, 2018 09:20
@djones6 djones6 mentioned this pull request Jun 27, 2018
DunnCoding pushed a commit that referenced this pull request Jun 28, 2018
* fix: pod update script (#32)

* feat: Add basic, google token and facebook token authentication (#33)
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.

4 participants