From 8af03fdd3b2e816fa466ae25aff2dd0dff4e379a Mon Sep 17 00:00:00 2001 From: wibe Date: Tue, 12 Mar 2024 15:27:22 +0100 Subject: [PATCH 1/3] include new error codekey and replace manual message with it Signed-off-by: wibe --- Sources/ImperialCore/Errors/ImperialError.swift | 6 ++++-- Sources/ImperialCore/Routing/FederatedServiceRouter.swift | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/ImperialCore/Errors/ImperialError.swift b/Sources/ImperialCore/Errors/ImperialError.swift index c7fa4de..f8f3d1b 100644 --- a/Sources/ImperialCore/Errors/ImperialError.swift +++ b/Sources/ImperialCore/Errors/ImperialError.swift @@ -9,10 +9,11 @@ public enum ImperialError: Error, CustomStringConvertible { /// no JSON in the response from the the request to `dataUri`. case missingJSONFromResponse(String) - - /// Thrown when `request.fetch` is called with a type that has not been run through `request.create`. case typeNotInitialized(String) + + /// Thrown when `code` is missing from within the authentication URL query + case missingCodeKey /// A human readable version of the error thrown. public var description: String { @@ -20,6 +21,7 @@ public enum ImperialError: Error, CustomStringConvertible { case let .missingEnvVar(variable): return "Missing enviroment variable '\(variable)'" case let .missingJSONFromResponse(uri): return "Reponse returned from '\(uri)' does not contain JSON" case let .typeNotInitialized(type): return "No instence of type '\(type)' has been created" + case .missingCodeKey: return "Missing 'code' key in URL query" } } } diff --git a/Sources/ImperialCore/Routing/FederatedServiceRouter.swift b/Sources/ImperialCore/Routing/FederatedServiceRouter.swift index 623a460..e5dd460 100644 --- a/Sources/ImperialCore/Routing/FederatedServiceRouter.swift +++ b/Sources/ImperialCore/Routing/FederatedServiceRouter.swift @@ -92,13 +92,13 @@ extension FederatedServiceRouter { public func fetchToken(from request: Request) throws -> EventLoopFuture { let code: String + let codeError = ImperialError.missingCodeKey + if let queryCode: String = try request.query.get(at: codeKey) { code = queryCode } else if let error: String = try request.query.get(at: errorKey) { throw Abort(.badRequest, reason: error) - } else { - throw Abort(.badRequest, reason: "Missing 'code' key in URL query") - } + } else { throw codeError } let body = callbackBody(with: code) let url = URI(string: accessTokenURL) From dedc54633f22a4d7c87ae298cb6eae05f22d55a0 Mon Sep 17 00:00:00 2001 From: wibe Date: Tue, 12 Mar 2024 15:47:06 +0100 Subject: [PATCH 2/3] not authenticated error Signed-off-by: wibe --- .../ImperialCore/Errors/SessionError.swift | 28 +++++++++++++++++++ .../Helpers/Sessions+Imperial.swift | 10 +++---- 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 Sources/ImperialCore/Errors/SessionError.swift diff --git a/Sources/ImperialCore/Errors/SessionError.swift b/Sources/ImperialCore/Errors/SessionError.swift new file mode 100644 index 0000000..f061bb0 --- /dev/null +++ b/Sources/ImperialCore/Errors/SessionError.swift @@ -0,0 +1,28 @@ +import Vapor + +/// Represents an error that occurs during a session action. +public enum SessionError: Error, CustomStringConvertible, AbortError { + + /// Thrown when the user's access token is not found within the session's data + case usernotAuthenticated + + public var description: String { + switch self { + case .usernotAuthenticated: return "User currently not authenticated" + } + } + + public var reason: String { + switch self { + case .usernotAuthenticated: return description + } + } + + + public var status: HTTPStatus { + switch self { + case .usernotAuthenticated: return .unauthorized + } + } + +} diff --git a/Sources/ImperialCore/Helpers/Sessions+Imperial.swift b/Sources/ImperialCore/Helpers/Sessions+Imperial.swift index 7d8faf7..c8ea94c 100644 --- a/Sources/ImperialCore/Helpers/Sessions+Imperial.swift +++ b/Sources/ImperialCore/Helpers/Sessions+Imperial.swift @@ -36,9 +36,9 @@ extension Session { /// - Returns: The access token stored with the `access_token` key. /// - Throws: `Abort.unauthorized` if no access token exists. public func accessToken() throws -> String { + let notauthenticatedError = SessionError.usernotAuthenticated guard let token = try? get(Keys.token, as: String.self) else { - throw Abort(.unauthorized, reason: "User currently not authenticated") - } + throw notauthenticatedError } return token } @@ -54,10 +54,10 @@ extension Session { /// - Returns: The refresh token stored with the `refresh_token` key. /// - Throws: `Abort.unauthorized` if no refresh token exists. public func refreshToken()throws -> String { + let notauthenticatedError = SessionError.usernotAuthenticated guard let token = self.data[Keys.refresh] else { - if self.data[Keys.token] == nil { - throw Abort(.unauthorized, reason: "User currently not authenticated") - } else { + if self.data[Keys.token] == nil { throw notauthenticatedError } + else { let oauthData = self.data["access_token_service"]?.data(using: .utf8) ?? Data() let oauth = try? JSONSerialization.jsonObject(with: oauthData, options: []) let oauthName = (oauth as? NSDictionary)?["name"] ?? "???" From 2fdc1f0f232ebf908af5c8d117b83ba78bf182f2 Mon Sep 17 00:00:00 2001 From: wibe Date: Tue, 12 Mar 2024 15:56:06 +0100 Subject: [PATCH 3/3] add and replace missing key error Signed-off-by: wibe --- Sources/ImperialCore/Errors/SessionError.swift | 6 ++++++ Sources/ImperialCore/Helpers/Sessions+Imperial.swift | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Sources/ImperialCore/Errors/SessionError.swift b/Sources/ImperialCore/Errors/SessionError.swift index f061bb0..19f1c27 100644 --- a/Sources/ImperialCore/Errors/SessionError.swift +++ b/Sources/ImperialCore/Errors/SessionError.swift @@ -6,15 +6,20 @@ public enum SessionError: Error, CustomStringConvertible, AbortError { /// Thrown when the user's access token is not found within the session's data case usernotAuthenticated + /// Throws Errors when no object is stored in the session with the given key, or decoding fails. + case keynotFound(String) + public var description: String { switch self { case .usernotAuthenticated: return "User currently not authenticated" + case let .keynotFound(key): return "No element has been found with the key '\(key)'" } } public var reason: String { switch self { case .usernotAuthenticated: return description + case .keynotFound: return description } } @@ -22,6 +27,7 @@ public enum SessionError: Error, CustomStringConvertible, AbortError { public var status: HTTPStatus { switch self { case .usernotAuthenticated: return .unauthorized + case .keynotFound: return .internalServerError } } diff --git a/Sources/ImperialCore/Helpers/Sessions+Imperial.swift b/Sources/ImperialCore/Helpers/Sessions+Imperial.swift index c8ea94c..192e206 100644 --- a/Sources/ImperialCore/Helpers/Sessions+Imperial.swift +++ b/Sources/ImperialCore/Helpers/Sessions+Imperial.swift @@ -82,9 +82,10 @@ extension Session { /// - Returns: The JSON from the session, decoded to the type passed in. /// - Throws: Errors when no object is stored in the session with the given key, or decoding fails. public func get(_ key: String, as type: T.Type) throws -> T where T: Codable { + let keynotfoundError = SessionError.keynotFound(key) guard let stored = data[key] else { if _isOptional(T.self) { return Optional.none as! T } - throw Abort(.internalServerError, reason: "No element found in session with ket '\(key)'") + throw keynotfoundError } return try JSONDecoder().decode(T.self, from: Data(stored.utf8)) }