Skip to content

Instantly share code, notes, and snippets.

View mczachurski's full-sized avatar

Marcin Czachurski mczachurski

View GitHub Profile
import Foundation
public enum Operations {
case create
case read
case update
case delete
}
public class OperationAuthorizationRequirement : AuthorizationRequirementProtocol {
import Foundation
public class TaskOperationAuthorizationHandler : AuthorizationHandlerProtocol {
public var requirementType: AuthorizationRequirementProtocol.Type = OperationAuthorizationRequirement.self
public var resourceType: EntityProtocol.Type = Task.self
public func handle(user: UserCredentials,
resource: EntityProtocol,
requirement: AuthorizationRequirementProtocol) throws -> Bool {
import Foundation
public protocol AuthorizationHandlerProtocol {
var requirementType: AuthorizationRequirementProtocol.Type { get }
var resourceType: EntityProtocol.Type { get }
func handle(user: UserCredentials, resource: EntityProtocol, requirement: AuthorizationRequirementProtocol) throws -> Bool
}
override func initRoutes() {
self.add(method: .post, uri: "/account/register", authorization: .anonymous, handler: register)
self.add(method: .post, uri: "/account/signIn", authorization: .anonymous, handler: signIn)
self.add(method: .post, uri: "/account/changePassword", authorization: .signedIn, handler: changePassword)
}
public func generateHash(salt: String) throws -> String {
let stringWithSalt = salt + self
guard let stringArray = stringWithSalt.digest(.sha256)?.encode(.base64) else {
throw GeneratePasswordError()
}
guard let stringHash = String(data: Data(bytes: stringArray, count: stringArray.count), encoding: .utf8) else {
throw GeneratePasswordError()
}
public func add(entity: User) throws {
entity.salt = String(randomWithLength: 14)
entity.password = try entity.password.generateHash(salt: entity.salt)
if let errors = self.userValidator.getValidationErrors(entity) {
throw ValidationsError(errors: errors)
}
try self.usersRepository.add(entity: entity)
// Authorization.
var routesWithAuthorization = Routes()
routesWithAuthorization.configure(routesWithAuthorization: controllers)
let requestFilters: [(HTTPRequestFilter, HTTPFilterPriority)] = [
(AuthenticationFilter(secret: configuration.secret, routesWithAuthorization: routesWithAuthorization), HTTPFilterPriority.high)
]
do {
// Launch the HTTP server.
import Foundation
import PerfectHTTP
import PerfectCrypto
public class AuthorizationFilter: HTTPRequestFilter {
private let secret: String
private let routesWithAuthorization: Routes
public init(secret: String, routesWithAuthorization: Routes) {
private func prepareToken(user: User) throws -> JwtTokenResponseDto {
let payload = [
ClaimsNames.name.rawValue : user.email,
ClaimsNames.roles.rawValue : user.getRolesNames(),
ClaimsNames.issuer.rawValue : self.configuration.issuer,
ClaimsNames.issuedAt.rawValue : Date().timeIntervalSince1970,
ClaimsNames.expiration.rawValue : Date().addingTimeInterval(36000).timeIntervalSince1970
] as [String : Any]
public func signIn(request: HTTPRequest, response: HTTPResponse) {
do {
let signIn = try request.getObjectFromRequest(SignInDto.self)
guard let user = try self.usersService.get(byEmail: signIn.email) else {
return response.sendNotFoundError()
}
let password = try signIn.password.generateHash(salt: user.salt)
if password != user.password {