Skip to content

Commit

Permalink
fix: create valid unauthorized request for odic/userpool connections
Browse files Browse the repository at this point in the history
  • Loading branch information
lawmicha committed Jul 8, 2022
1 parent 83a53ee commit 59053f0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
9 changes: 8 additions & 1 deletion AppSyncRealTimeClient/Interceptor/OIDCAuthInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ public class OIDCAuthInterceptor: AuthInterceptor, AuthInterceptorAsync {
case .success(let token):
jwtToken = token
case .failure:
return request
// A user that is not signed in or the token is expired should receive an unauthorized error from the
// connection request. This code achieves this by always creating a valid request to AppSync even when the
// token cannot be retrieved. The request sent to AppSync will receive a response indicating the request is
// unauthorized. If we do not use empty token string and perform the remaining logic of the request
// construction then it will fail request validation at AppSync before the authorization check, which ends
// up being propagated back to the caller as a "bad request". Example of bad requests are when the header
// and payload query strings are missing or when the data is not base64 encoded.
jwtToken = ""
}

let authHeader = UserPoolsAuthenticationHeader(token: jwtToken, host: host)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,29 @@ import AppSyncRealTimeClient

class OIDCAuthInterceptorTests: XCTestCase {

var userPoolAuthProvider: MockUserPoolsAuthProvider!
var authInterceptor: OIDCAuthInterceptor!

override func setUp() {
authInterceptor = OIDCAuthInterceptor(MockUserPoolsAuthProvider())
userPoolAuthProvider = MockUserPoolsAuthProvider()
authInterceptor = OIDCAuthInterceptor(userPoolAuthProvider)
}

func testInterceptRequest() {
func testInterceptConnection() {
let url = URL(string: "http://xxxc.appsync-api.ap-southeast-2.amazonaws.com/sd")!
let request = AppSyncConnectionRequest(url: url)
let signedRequest = authInterceptor.interceptConnection(request, for: url)

guard let queries = URLComponents(url: signedRequest.url, resolvingAgainstBaseURL: true)?.queryItems else {
assertionFailure("Query parameters should not be nil")
return
}
XCTAssertTrue(queries.contains { $0.name == "header"}, "Should contain the header query")
XCTAssertTrue(queries.contains { $0.name == "payload"}, "Should contain the payload query")
}

func testInterceptConnectionWithInvalidToken() {
userPoolAuthProvider.hasError = true
let url = URL(string: "http://xxxc.appsync-api.ap-southeast-2.amazonaws.com/sd")!
let request = AppSyncConnectionRequest(url: url)
let signedRequest = authInterceptor.interceptConnection(request, for: url)
Expand All @@ -39,7 +55,15 @@ class OIDCAuthInterceptorTests: XCTestCase {
}

class MockUserPoolsAuthProvider: OIDCAuthProvider {
struct AuthError: Error { }

var hasError: Bool = false

func getLatestAuthToken() -> Result<String, Error> {
if hasError {
return .failure(AuthError())
}

return .success("jwtToken")
}
}

0 comments on commit 59053f0

Please sign in to comment.