From 7652bb24a33271c3d2308d5e109925c0730648be Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Fri, 8 Dec 2023 15:43:29 +0100 Subject: [PATCH] Improve message result clarity --- Sources/App/API/MessageResult.swift | 198 +++++++++++++++------------- Sources/App/DeviceManager.swift | 4 +- Sources/App/routes.swift | 4 +- 3 files changed, 111 insertions(+), 95 deletions(-) diff --git a/Sources/App/API/MessageResult.swift b/Sources/App/API/MessageResult.swift index e23d741..2c34a96 100644 --- a/Sources/App/API/MessageResult.swift +++ b/Sources/App/API/MessageResult.swift @@ -4,6 +4,8 @@ import Foundation A result from sending a key to the device. */ enum MessageResult: UInt8 { + + // MARK: Device status /// The message was accepted. case messageAccepted = 0 @@ -18,13 +20,13 @@ enum MessageResult: UInt8 { case invalidMessageSizeFromRemote = 3 /// The message signature was incorrect. - case invalidSignatureByRemote = 4 + case invalidSignatureFromRemote = 4 /// The server challenge of the message did not match previous messages - case serverChallengeMismatch = 5 + case invalidServerChallengeFromRemote = 5 /// The client challenge of the message did not match previous messages - case clientChallengeMismatchFromRemote = 6 + case invalidClientChallengeFromRemote = 6 /// An unexpected or unsupported message type was received case invalidMessageTypeFromRemote = 7 @@ -38,52 +40,66 @@ enum MessageResult: UInt8 { /// An invalid Url parameter was set sending a message to the device over a local connection case invalidUrlParameter = 10 - /// The request took too long to complete - case deviceTimedOut = 20 + // MARK: Server status - case noOrInvalidBodyDataInServerRequest = 21 - - /// The device is not connected to the server via web socket - case deviceNotConnected = 22 - case serverNotReached = 23 - case serverUrlInvalid = 24 - case invalidDeviceResponseSize = 25 - case invalidSignatureByDevice = 26 - case noKeyAvailable = 27 - case unlocked = 28 - case unknownMessageResultFromDevice = 29 - - /// The device sent a message with an invalid client challenge - case clientChallengeMismatchFromDevice = 30 - - /// A valid server challenge was received - case deviceAvailable = 31 - - case invalidMessageTypeFromDevice = 32 - - /// The url session request returned an unknown response - case unexpectedUrlResponseType = 33 - - /// The request to the server returned an unhandled HTTP code - case unexpectedServerResponseCode = 34 - - /// The server produced an internal error (500) - case internalServerError = 35 - - /// The Sesame server behind the proxy could not be found (502) - case serviceBehindProxyUnavailable = 36 - - /// The server url could not be found (404) - case pathOnServerNotFound = 37 - - /// The header with the authentication token was missing or invalid (not a hex string) from a server request. - case missingOrInvalidAuthenticationHeader = 38 + /// The body data posting a message was missing or of wrong length + case noOrInvalidBodyDataFromRemote = 21 /// The authentication token for the server was invalid - case invalidServerAuthentication = 39 + case invalidServerAuthenticationFromRemote = 22 + + /// The request took too long to complete + case deviceTimedOut = 23 + + /// The device is not connected to the server via web socket + case deviceNotConnected = 24 /// The device sent a response of invalid size - case invalidMessageSizeFromDevice = 40 + case invalidMessageSizeFromDevice = 25 + + /// The header with the authentication token was missing or invalid (not a hex string) from a server request. + case missingOrInvalidAuthenticationHeaderFromRemote = 26 + + /// The server produced an internal error (500) + case internalServerError = 27 + + // MARK: Remote status + + /// The url string is not a valid url + case serverUrlInvalid = 31 + + /// The device key or auth token is missing for a request. + case noKeyAvailable = 32 + + /// The Sesame server behind the proxy could not be found (502) + case serviceBehindProxyUnavailable = 33 + + /// The server url could not be found (404) + case pathOnServerNotFound = 34 + + /// The url session request returned an unknown response + case unexpectedUrlResponseType = 35 + + /// The request to the server returned an unhandled HTTP code + case unexpectedServerResponseCode = 36 + + /// A valid server challenge was received + case deviceAvailable = 37 + + case invalidSignatureByDevice = 38 + + case invalidMessageTypeFromDevice = 39 + + case unknownMessageResultFromDevice = 40 + + /// The device sent a message with an invalid client challenge + case invalidClientChallengeFromDevice = 41 + + /// The device used an invalid server challenge in a response + case invalidServerChallengeFromDevice = 42 + + /// The unlock process was successfully completed + case unlocked = 43 } extension MessageResult: Error { @@ -102,62 +118,62 @@ extension MessageResult: CustomStringConvertible { return "Unexpected socket event for the device" case .invalidMessageSizeFromRemote: return "Invalid message data from remote" - case .invalidSignatureByRemote: + case .invalidSignatureFromRemote: return "Message authentication failed" - case .noOrInvalidBodyDataInServerRequest: - return "Invalid body data in server request" - case .deviceNotConnected: - return "Device not connected to server" - case .deviceTimedOut: - return "The device did not respond" - case .serverChallengeMismatch: + case .invalidServerChallengeFromRemote: return "Server challenge mismatch" - case .clientChallengeMismatchFromRemote: + case .invalidClientChallengeFromRemote: return "Wrong client challenge sent" case .invalidMessageTypeFromRemote: return "Message type from remote invalid" case .tooManyRequests: return "Device busy" - case .invalidUrlParameter: - return "The url parameter could not be found" case .invalidMessageResultFromRemote: return "Invalid message result" - case .serverNotReached: - return "Server unavailable" - case .serverUrlInvalid: - return "Invalid server url" - case .invalidDeviceResponseSize: - return "Invalid Response size" - case .invalidSignatureByDevice: - return "Invalid device signature" - case .noKeyAvailable: - return "No key available" - case .unlocked: - return "Unlocked" - case .unknownMessageResultFromDevice: - return "Unknown message result" - case .deviceAvailable: - return "Device available" - case .clientChallengeMismatchFromDevice: - return "Device sent invalid client challenge" - case .invalidMessageTypeFromDevice: - return "Message type from device invalid" - case .unexpectedUrlResponseType: - return "Unexpected URL response" - case .unexpectedServerResponseCode: - return "Unexpected server response code" + case .invalidUrlParameter: + return "The url parameter could not be found" + + case .noOrInvalidBodyDataFromRemote: + return "Invalid body data in server request" + case .invalidServerAuthenticationFromRemote: + return "Invalid server token" + case .deviceTimedOut: + return "The device did not respond" + case .deviceNotConnected: + return "Device not connected to server" + case .invalidMessageSizeFromDevice: + return "Invalid device message size" + case .missingOrInvalidAuthenticationHeaderFromRemote: + return "Invalid server token format" case .internalServerError: return "Internal server error" + + case .serverUrlInvalid: + return "Invalid server url" + case .noKeyAvailable: + return "No key available" case .serviceBehindProxyUnavailable: return "Service behind proxy not found" case .pathOnServerNotFound: return "Invalid server path" - case .missingOrInvalidAuthenticationHeader: - return "Invalid server token format" - case .invalidServerAuthentication: - return "Invalid server token" - case .invalidMessageSizeFromDevice: - return "Invalid device message size" + case .unexpectedUrlResponseType: + return "Unexpected URL response" + case .unexpectedServerResponseCode: + return "Unexpected server response code" + case .deviceAvailable: + return "Device available" + case .invalidSignatureByDevice: + return "Invalid device signature" + case .invalidMessageTypeFromDevice: + return "Message type from device invalid" + case .unknownMessageResultFromDevice: + return "Unknown message result" + case .invalidClientChallengeFromDevice: + return "Device sent invalid client challenge" + case .invalidServerChallengeFromDevice: + return "Invalid" + case .unlocked: + return "Unlocked" } } } @@ -178,13 +194,13 @@ extension MessageResult { init(httpCode: Int) { switch httpCode { case 200: self = .messageAccepted - case 204: self = .noOrInvalidBodyDataInServerRequest - case 403: self = .invalidServerAuthentication + case 204: self = .noOrInvalidBodyDataFromRemote + case 403: self = .invalidServerAuthenticationFromRemote case 404: self = .pathOnServerNotFound case 408: self = .deviceTimedOut case 412: self = .deviceNotConnected case 413: self = .invalidMessageSizeFromDevice - case 422: self = .missingOrInvalidAuthenticationHeader + case 422: self = .missingOrInvalidAuthenticationHeaderFromRemote case 429: self = .tooManyRequests case 500: self = .internalServerError case 501: self = .unexpectedServerResponseCode @@ -196,14 +212,14 @@ extension MessageResult { var statusCode: Int { switch self { case .messageAccepted: return 200 // ok - case .noOrInvalidBodyDataInServerRequest: return 204 // noContent - case .invalidServerAuthentication: return 403 // forbidden + case .noOrInvalidBodyDataFromRemote: return 204 // noContent + case .invalidServerAuthenticationFromRemote: return 403 // forbidden case .pathOnServerNotFound: return 404 // notFound case .deviceTimedOut: return 408 // requestTimeout case .invalidMessageSizeFromRemote: return 411 // lengthRequired case .deviceNotConnected: return 412 // preconditionFailed case .invalidMessageSizeFromDevice: return 413 // payloadTooLarge - case .missingOrInvalidAuthenticationHeader: return 422 // unprocessableEntity + case .missingOrInvalidAuthenticationHeaderFromRemote: return 422 // unprocessableEntity case .tooManyRequests: return 429 // tooManyRequests case .internalServerError: return 500 // internalServerError case .unexpectedServerResponseCode: return 501 // notImplemented diff --git a/Sources/App/DeviceManager.swift b/Sources/App/DeviceManager.swift index bbeb864..a236dd2 100644 --- a/Sources/App/DeviceManager.swift +++ b/Sources/App/DeviceManager.swift @@ -65,10 +65,10 @@ final class DeviceManager { func sendMessageToDevice(_ message: Data, authToken: Data, on eventLoop: EventLoop) async throws -> Data { guard message.count == SignedMessage.size else { - throw MessageResult.invalidMessageSizeFromDevice + throw MessageResult.invalidMessageSizeFromRemote } guard SHA256.hash(data: authToken) == remoteKey else { - throw MessageResult.invalidServerAuthentication + throw MessageResult.invalidServerAuthenticationFromRemote } guard let socket = connection, !socket.isClosed else { connection = nil diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 3672849..ced0920 100755 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -18,12 +18,12 @@ func routes(_ app: Application) { guard let authString = request.headers.first(name: SesameHeader.authenticationHeader), let authToken = Data(fromHexEncodedString: authString), authToken.count == SesameHeader.serverAuthenticationTokenSize else { - throw MessageResult.missingOrInvalidAuthenticationHeader + throw MessageResult.missingOrInvalidAuthenticationHeaderFromRemote } guard let body = request.body.data, let message = body.getData(at: 0, length: body.readableBytes) else { - throw MessageResult.noOrInvalidBodyDataInServerRequest + throw MessageResult.noOrInvalidBodyDataFromRemote } let responseMessage = try await deviceManager.sendMessageToDevice(message, authToken: authToken, on: request.eventLoop)