Skip to content

Commit

Permalink
Merge pull request #23 from auth0/feature-logging
Browse files Browse the repository at this point in the history
Introduce simple logging for HTTP requests and OAuth2 flow
  • Loading branch information
hzalaz authored Jun 9, 2016
2 parents 3848de9 + 54a9743 commit 2f3a7c0
Show file tree
Hide file tree
Showing 9 changed files with 3,643 additions and 1,314 deletions.
4,771 changes: 3,462 additions & 1,309 deletions Auth0.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Auth0/Auth0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,17 @@ public func users(token token: String, domain: String, session: NSURLSession = .
return management(token: token, domain: domain, session: session).users()
}

/**
Turn on/off Auth0.swift debug logging of HTTP requests and OAuth2 flow (iOS only).

- parameter enabled: optional flag to turn on/off logging
- note: By default all logging is **disabled**
- important: Logging should be turned on/off **before** making request to Auth0 for the flag to take effect.
*/
public func enableLogging(enabled: Bool = true) {
Auth0Logger.sharedInstance.logger = enabled ? DefaultLogger() : nil
}

func plistValues() -> (clientId: String, domain: String)? {
let bundle = NSBundle.mainBundle()
guard
Expand Down
69 changes: 69 additions & 0 deletions Auth0/Logger/Logger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Logger.swift
//
// Copyright (c) 2016 Auth0 (http://auth0.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation

class Auth0Logger {
static let sharedInstance = Auth0Logger()

var logger: Logger? = nil
}

public protocol Logger {
func trace(request: NSURLRequest, session: NSURLSession)
func trace(response: NSURLResponse, data: NSData?)
func trace(url: NSURL, source: String?)
}

struct DefaultLogger: Logger {

func trace(request: NSURLRequest, session: NSURLSession) {
guard
let method = request.HTTPMethod,
let url = request.URL
else { return }
print("\(method) \(url.absoluteString) HTTP/1.1")
session.configuration.HTTPAdditionalHeaders?.forEach { key, value in print("\(key): \(value)") }
request.allHTTPHeaderFields?.forEach { key, value in print("\(key): \(value)") }
if let data = request.HTTPBody, let string = String(data: data, encoding: NSUTF8StringEncoding) {
print()
print(string)
}
print()
}

func trace(response: NSURLResponse, data: NSData?) {
if let http = response as? NSHTTPURLResponse {
print("HTTP/1.1 \(http.statusCode)")
http.allHeaderFields.forEach { key, value in print("\(key): \(value)") }
if let data = data, let string = String(data: data, encoding: NSUTF8StringEncoding) {
print()
print(string)
}
print()
}
}

func trace(url: NSURL, source: String?) {
print("\(source ?? "URL"): \(url.absoluteString)")
}
}
47 changes: 47 additions & 0 deletions Auth0/Logger/_ObjectiveLogger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// _ObjectiveLogger.swift
//
// Copyright (c) 2016 Auth0 (http://auth0.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation

@objc(A0Logger)
public class _ObjectiveLogger: NSObject {
/**
Turn on Auth0.swift debug logging of HTTP requests and OAuth2 flow (iOS only).

- note: By default all logging is **disabled**
- important: Logging should be turned on/off **before** making request to Auth0 for the flag to take effect.
*/
public static func loggingEnabled() {
enableLogging(true)
}

/**
Turn on/off Auth0.swift debug logging of HTTP requests and OAuth2 flow (iOS only).

- parameter enabled: flag to turn on/off logging
- note: By default all logging is **disabled**
- important: Logging should be turned on/off **before** making request to Auth0 for the flag to take effect.
*/
public static func loggingEnabled(enabled: Bool) {
enableLogging(enabled)
}
}
17 changes: 15 additions & 2 deletions Auth0/Networking/Request.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ public struct Request<T, Error: ErrorType>: Requestable {
let handle: (Response, Callback) -> ()
let payload: [String: AnyObject]
let headers: [String: String]
let logger: Logger?

init(session: NSURLSession, url: NSURL, method: String, handle: (Response, Callback) -> (), payload: [String: AnyObject] = [:], headers: [String: String] = [:]) {
init(session: NSURLSession, url: NSURL, method: String, handle: (Response, Callback) -> (), payload: [String: AnyObject] = [:], headers: [String: String] = [:], logger: Logger? = Auth0Logger.sharedInstance.logger) {
self.session = session
self.url = url
self.method = method
self.handle = handle
self.payload = payload
self.headers = headers
self.logger = logger
}

var request: NSURLRequest {
Expand All @@ -76,7 +78,18 @@ public struct Request<T, Error: ErrorType>: Requestable {
*/
public func start(callback: Callback) {
let handler = self.handle
session.dataTaskWithRequest(request) { handler(Response(data: $0, response: $1, error: $2), callback) }.resume()
let request = self.request
let logger = self.logger

logger?.trace(request, session: self.session)

let task = session.dataTaskWithRequest(request) { data, response, error in
if error == nil, let response = response {
logger?.trace(response, data: data)
}
handler(Response(data: data, response: response, error: error), callback)
}
task.resume()
}

/**
Expand Down
5 changes: 4 additions & 1 deletion Auth0/OAuth2/OAuth2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public class OAuth2 {
let url: NSURL
let presenter: ControllerModalPresenter
let storage: SessionStorage
let logger: Logger?
var state = generateDefaultState()
var parameters: [String: String] = [:]
var universalLink = false
Expand All @@ -99,11 +100,12 @@ public class OAuth2 {
self.init(clientId: clientId, url: url, presenter: presenter, storage: SessionStorage.sharedInstance)
}

init(clientId: String, url: NSURL, presenter: ControllerModalPresenter, storage: SessionStorage) {
init(clientId: String, url: NSURL, presenter: ControllerModalPresenter, storage: SessionStorage, logger: Logger? = Auth0Logger.sharedInstance.logger) {
self.clientId = clientId
self.url = url
self.presenter = presenter
self.storage = storage
self.logger = logger
}
/**
For redirect url instead of a custom scheme it will use `https` and iOS 9 Universal Links.
Expand Down Expand Up @@ -216,6 +218,7 @@ public class OAuth2 {
let (controller, finish) = newSafari(authorizeURL, callback: callback)
let session = OAuth2Session(controller: controller, redirectURL: redirectURL, state: self.state, handler: handler, finish: finish)
controller.delegate = session
logger?.trace(authorizeURL, source: "Safari")
self.presenter.present(controller)
self.storage.store(session)
}
Expand Down
3 changes: 2 additions & 1 deletion Auth0/OAuth2/SessionStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ class SessionStorage {

private var current: OAuth2Session? = nil

func resume(url: NSURL, options: [String: AnyObject]) -> Bool {
func resume(url: NSURL, options: [String: AnyObject], logger: Logger? = Auth0Logger.sharedInstance.logger) -> Bool {
logger?.trace(url, source: options[UIApplicationLaunchOptionsSourceApplicationKey] as? String)
let resumed = self.current?.resume(url, options: options) ?? false
if resumed {
self.current = nil
Expand Down
2 changes: 1 addition & 1 deletion OAuth2/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Auth0.enableLogging()
return true
}

Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,38 @@ Auth0
}
```

### Logging

To enable Auth0.swift to log HTTP request and OAuth2 flow for debugging just add the following:

```swift
Auth0.enableLogging()
```

Then for a OAuth2 authentication you'll see in the console:

```
Safari: https://samples.auth0.com/authorize?.....
URL: com.auth0.oauth2://samples.auth0.com/ios/com.auth0.OAuth2/callback?...
POST https://samples.auth0.com/oauth/token HTTP/1.1
Content-Type: application/json
{"code":"...","client_id":"...","grant_type":"authorization_code","redirect_uri":"com.auth0.OAuth2:\/\/samples.auth0.com\/ios\/com.auth0.OAuth2\/callback","code_verifier":"..."}
HTTP/1.1 200
Pragma: no-cache
Content-Type: application/json
Strict-Transport-Security: max-age=3600
Date: Thu, 09 Jun 2016 19:04:39 GMT
Content-Length: 57
Cache-Control: no-cache
Connection: keep-alive
{"access_token":"...","token_type":"Bearer"}
```

> Only set this flag for **DEBUG** only or you'll be leaking user's credentials in the device log.
## What is Auth0?

Auth0 helps you to:
Expand Down

0 comments on commit 2f3a7c0

Please sign in to comment.