Skip to content

Commit 09b6cdd

Browse files
author
Garrett Moseke
committed
feat: update auth to allow eventloopfuture resolution
1 parent 92a7007 commit 09b6cdd

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

Sources/GraphQLTransportWS/Server.swift

+16-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public class Server<InitPayload: Equatable & Codable> {
1313

1414
let onExecute: (GraphQLRequest) -> EventLoopFuture<GraphQLResult>
1515
let onSubscribe: (GraphQLRequest) -> EventLoopFuture<SubscriptionResult>
16+
var auth: (InitPayload) throws -> EventLoopFuture<Void>
1617

17-
var auth: (InitPayload) throws -> Void = { _ in }
1818
var onExit: () -> Void = { }
1919
var onOperationComplete: (String) -> Void = { _ in }
2020
var onOperationError: (String) -> Void = { _ in }
@@ -32,14 +32,17 @@ public class Server<InitPayload: Equatable & Codable> {
3232
/// - messenger: The messenger to bind the server to.
3333
/// - onExecute: Callback run during `subscribe` resolution for non-streaming queries. Typically this is `API.execute`.
3434
/// - onSubscribe: Callback run during `subscribe` resolution for streaming queries. Typically this is `API.subscribe`.
35+
/// - eventLoop: EventLoop on which to perform server operations.
3536
public init(
3637
messenger: Messenger,
3738
onExecute: @escaping (GraphQLRequest) -> EventLoopFuture<GraphQLResult>,
38-
onSubscribe: @escaping (GraphQLRequest) -> EventLoopFuture<SubscriptionResult>
39+
onSubscribe: @escaping (GraphQLRequest) -> EventLoopFuture<SubscriptionResult>,
40+
eventLoop: EventLoop
3941
) {
4042
self.messenger = messenger
4143
self.onExecute = onExecute
4244
self.onSubscribe = onSubscribe
45+
self.auth = { _ in eventLoop.makeSucceededVoidFuture() }
4346

4447
messenger.onReceive { message in
4548
self.onMessage(message)
@@ -91,9 +94,9 @@ public class Server<InitPayload: Equatable & Codable> {
9194
}
9295

9396
/// Define the callback run during `connection_init` resolution that allows authorization using the `payload`.
94-
/// Throw to indicate that authorization has failed.
97+
/// Throw or fail the future to indicate that authorization has failed.
9598
/// - Parameter callback: The callback to assign
96-
public func auth(_ callback: @escaping (InitPayload) throws -> Void) {
99+
public func auth(_ callback: @escaping (InitPayload) throws -> EventLoopFuture<Void>) {
97100
self.auth = callback
98101
}
99102

@@ -128,14 +131,20 @@ public class Server<InitPayload: Equatable & Codable> {
128131
}
129132

130133
do {
131-
try self.auth(connectionInitRequest.payload)
134+
let authResult = try self.auth(connectionInitRequest.payload)
135+
authResult.whenSuccess {
136+
self.initialized = true
137+
self.sendConnectionAck()
138+
}
139+
authResult.whenFailure { error in
140+
self.error(.unauthorized())
141+
return
142+
}
132143
}
133144
catch {
134145
self.error(.unauthorized())
135146
return
136147
}
137-
initialized = true
138-
self.sendConnectionAck()
139148
}
140149

141150
private func onSubscribe(_ subscribeRequest: SubscribeRequest) {

Tests/GraphQLTransportWSTests/GraphQLTransportWSTests.swift

+35-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class GraphqlTransportWSTests: XCTestCase {
1010
var clientMessenger: TestMessenger!
1111
var serverMessenger: TestMessenger!
1212
var server: Server<TokenInitPayload>!
13+
var eventLoop: EventLoop!
1314

1415
override func setUp() {
1516
// Point the client and server at each other
@@ -18,7 +19,7 @@ class GraphqlTransportWSTests: XCTestCase {
1819
clientMessenger.other = serverMessenger
1920
serverMessenger.other = clientMessenger
2021

21-
let eventLoop = MultiThreadedEventLoopGroup(numberOfThreads: 1).next()
22+
eventLoop = MultiThreadedEventLoopGroup(numberOfThreads: 1).next()
2223
let api = TestAPI()
2324
let context = TestContext()
2425

@@ -28,16 +29,17 @@ class GraphqlTransportWSTests: XCTestCase {
2829
api.execute(
2930
request: graphQLRequest.query,
3031
context: context,
31-
on: eventLoop
32+
on: self.eventLoop
3233
)
3334
},
3435
onSubscribe: { graphQLRequest in
3536
api.subscribe(
3637
request: graphQLRequest.query,
3738
context: context,
38-
on: eventLoop
39+
on: self.eventLoop
3940
)
40-
}
41+
},
42+
eventLoop: self.eventLoop
4143
)
4244
}
4345

@@ -71,7 +73,7 @@ class GraphqlTransportWSTests: XCTestCase {
7173
}
7274

7375
/// Tests that throwing in the authorization callback forces an unauthorized error
74-
func testAuth() throws {
76+
func testAuthWithThrow() throws {
7577
server.auth { payload in
7678
throw TestError.couldBeAnything
7779
}
@@ -98,6 +100,34 @@ class GraphqlTransportWSTests: XCTestCase {
98100
)
99101
}
100102

103+
/// Tests that failing a future in the authorization callback forces an unauthorized error
104+
func testAuthWithFailedFuture() throws {
105+
server.auth { payload in
106+
self.eventLoop.makeFailedFuture(TestError.couldBeAnything)
107+
}
108+
109+
var messages = [String]()
110+
let completeExpectation = XCTestExpectation()
111+
112+
let client = Client<TokenInitPayload>(messenger: clientMessenger)
113+
client.onMessage { message, _ in
114+
messages.append(message)
115+
completeExpectation.fulfill()
116+
}
117+
118+
client.sendConnectionInit(
119+
payload: TokenInitPayload(
120+
authToken: ""
121+
)
122+
)
123+
124+
wait(for: [completeExpectation], timeout: 2)
125+
XCTAssertEqual(
126+
messages,
127+
["\(ErrorCode.unauthorized): Unauthorized"]
128+
)
129+
}
130+
101131
/// Tests a single-op conversation
102132
func testSingleOp() throws {
103133
let id = UUID().description

0 commit comments

Comments
 (0)