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

fix: create valid unauthorized request for odic/userpool connections #93

Merged
merged 1 commit into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}
}