Repository navigation
Expand file tree
/
Copy pathUserController.swift
More file actions
74 lines (60 loc) · 2.58 KB
/
Copy pathUserController.swift
File metadata and controls
74 lines (60 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import Vapor
import Fluent
struct UserController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let userRoute = routes.grouped("api", "users")
userRoute.get(use: getAllHandler)
userRoute.get(":id", use: getHandler)
userRoute.post(use: createHandler)
let basicAuthMiddleware = User.authenticator()
let guardMiddleware = User.guardMiddleware()
let basicAuthGroup = userRoute.grouped(basicAuthMiddleware, guardMiddleware)
basicAuthGroup.post("login", use: loginHandler)
let tokenAuthMiddleware = Token.authenticator()
let tokenAuthGroup = userRoute.grouped(tokenAuthMiddleware, guardMiddleware)
tokenAuthGroup.delete(use: deleteHandler)
}
func getAllHandler(_ req: Request) throws -> EventLoopFuture<[User.Public]> {
User.query(on: req.db)
.all()
.flatMapEachThrowing { try User.Public(id: $0.requireID(), username: $0.username) }
}
func getHandler(_ req: Request) throws -> EventLoopFuture<User.Public> {
guard let id = req.parameters.get("id", as: UUID.self) else {
throw Abort(.badRequest)
}
return User.find(id, on: req.db)
.unwrap(or: Abort(.notFound))
.flatMapThrowing { $0.toPublicUser() }
}
func createHandler(_ req: Request) throws -> EventLoopFuture<Response> {
let user = try req.content.decode(User.self)
user.password = try Bcrypt.hash(user.password)
return user.save(on: req.db).map {
let response = Response()
response.status = .created
if let userID = user.id?.description {
let location = req.url.path + "/" + userID
response.headers.replaceOrAdd(name: "Location", value: location)
}
return response
}
}
func deleteHandler(_ req: Request) throws -> EventLoopFuture<HTTPStatus> {
let user = try req.auth.require(User.self)
return user.delete(on: req.db).transform(to: HTTPStatus.noContent)
}
func loginHandler(_ req: Request) throws -> EventLoopFuture<TokenResponse> {
let user = try req.auth.require(User.self)
let token = try user.generateToken()
return token.save(on: req.db).flatMapThrowing {
try TokenResponse(token: token.token,
userID: user.requireID())
}
}
}
// MARK: - Request models
struct TokenResponse: Content {
let token: String
let userID: UUID
}