Skip to content

Commit

Permalink
Merge branch 'main' into mmbm-url-query-snake-case
Browse files Browse the repository at this point in the history
  • Loading branch information
MahdiBM committed Nov 3, 2023
2 parents 0b1ae11 + 0fa646e commit d0820a8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
39 changes: 29 additions & 10 deletions Sources/Vapor/Authentication/AuthenticationCache.swift
Expand Up @@ -19,14 +19,14 @@ extension Request {
extension Request.Authentication {
/// Authenticates the supplied instance for this request.
public func login<A>(_ instance: A)
where A: Authenticatable & Sendable
where A: Authenticatable
{
self.cache[A.self] = instance
self.cache[A.self] = UnsafeAuthenticationBox(instance)
}

/// Unauthenticates an authenticatable type.
public func logout<A>(_ type: A.Type = A.self)
where A: Authenticatable & Sendable
where A: Authenticatable
{
self.cache[A.self] = nil
}
Expand All @@ -35,7 +35,7 @@ extension Request.Authentication {
/// instance of that type has been authenticated or if there
/// was a problem.
@discardableResult public func require<A>(_ type: A.Type = A.self) throws -> A
where A: Authenticatable & Sendable
where A: Authenticatable
{
guard let a = self.get(A.self) else {
throw Abort(.unauthorized)
Expand All @@ -46,14 +46,14 @@ extension Request.Authentication {
/// Returns the authenticated instance of the supplied type.
/// - note: `nil` if no type has been authed.
public func get<A>(_ type: A.Type = A.self) -> A?
where A: Authenticatable & Sendable
where A: Authenticatable
{
return self.cache[A.self]
return self.cache[A.self]?.authenticated
}

/// Returns `true` if the type has been authenticated.
public func has<A>(_ type: A.Type = A.self) -> Bool
where A: Authenticatable & Sendable
where A: Authenticatable
{
return self.get(A.self) != nil
}
Expand All @@ -65,11 +65,11 @@ extension Request.Authentication {
self.storage = .init([:])
}

internal subscript<A>(_ type: A.Type) -> A?
where A: Authenticatable & Sendable
internal subscript<A>(_ type: A.Type) -> UnsafeAuthenticationBox<A>?
where A: Authenticatable
{
get {
storage.withLockedValue { $0[ObjectIdentifier(A.self)] as? A }
storage.withLockedValue { $0[ObjectIdentifier(A.self)] as? UnsafeAuthenticationBox<A> }
}
set {
storage.withLockedValue { $0[ObjectIdentifier(A.self)] = newValue }
Expand All @@ -96,3 +96,22 @@ extension Request.Authentication {
}
}
}

// This is to get around the fact that for legacy reasons we can't enforce Sendability on Authenticatable
// types (e.g. Fluent 4 models can never be Sendable because they're reference types with mutable values
// required by protocols and property wrappers). This allows us to store the Authenticatable type in a
// safe-most-of-the-time way. This does introduce an edge case where type could be stored and mutated in
// multiple places. But given how Vapor and its users use Authentication this should almost never
// occur and it was decided the trade-off was acceptable
// As the name implies, the usage of this is unsafe because it disables the sendable checking of the
// compiler and does not add any synchronisation.
@usableFromInline
internal struct UnsafeAuthenticationBox<A>: @unchecked Sendable {
@usableFromInline
let authenticated: A

@inlinable
init(_ authenticated: A) {
self.authenticated = authenticated
}
}
2 changes: 1 addition & 1 deletion Sources/Vapor/Authentication/Authenticator.swift
@@ -1,7 +1,7 @@
import NIOCore

/// Capable of being authenticated.
public protocol Authenticatable: Sendable { }
public protocol Authenticatable { }

/// Helper for creating authentication middleware.
///
Expand Down
2 changes: 1 addition & 1 deletion Sources/Vapor/Authentication/GuardMiddleware.swift
Expand Up @@ -27,7 +27,7 @@ extension Authenticatable {


private final class GuardAuthenticationMiddleware<A>: Middleware
where A: Authenticatable & Sendable
where A: Authenticatable
{
/// Error to throw when guard fails.
private let error: Error
Expand Down
2 changes: 1 addition & 1 deletion Sources/Vapor/Authentication/RedirectMiddleware.swift
Expand Up @@ -20,7 +20,7 @@ extension Authenticatable {


private final class RedirectMiddleware<A>: Middleware
where A: Authenticatable & Sendable
where A: Authenticatable
{
let makePath: @Sendable (Request) -> String

Expand Down

0 comments on commit d0820a8

Please sign in to comment.