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 c7e4713
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 should receive an unauthorized error from the connection attempt. 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 c7e4713

Please sign in to comment.