Create individual functions for routes
This commit is contained in:
parent
75211f67ca
commit
fc4afb70b1
@ -15,25 +15,46 @@ func encodeJSON<T>(_ response: T) throws -> String where T: Encodable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func routes(_ app: Application) throws {
|
func routes(_ app: Application) throws {
|
||||||
|
registerPlayer(app)
|
||||||
|
requestPlayerPasswordReset(app)
|
||||||
|
resetPlayerPasswordWithEmailToken(app)
|
||||||
|
deletePlayer(app)
|
||||||
|
loginPlayer(app)
|
||||||
|
resumeSession(app)
|
||||||
|
logoutPlayer(app)
|
||||||
|
getTableForPlayer(app)
|
||||||
|
openWebsocket(app)
|
||||||
|
createTable(app)
|
||||||
|
getPublicTables(app)
|
||||||
|
joinTable(app)
|
||||||
|
leaveTable(app)
|
||||||
|
performActionForPlayer(app)
|
||||||
|
playCard(app)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Players & Sessions
|
// MARK: Players & Sessions
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a new player.
|
||||||
|
|
||||||
|
Headers:
|
||||||
|
- `name`: The username of the player
|
||||||
|
- `password`: The password of the player
|
||||||
|
- `email`: Optional email address for password reset
|
||||||
|
|
||||||
|
Possible responses:
|
||||||
|
- `200`: On success, with the session token for the registered user in the reponse body
|
||||||
|
- `400`: Missing name or password
|
||||||
|
- `406`: Password or name too long
|
||||||
|
- `409`: A player with the same name already exists
|
||||||
|
- `424`: The password could not be hashed
|
||||||
|
*/
|
||||||
|
func registerPlayer(_ app: Application) {
|
||||||
|
app.post("player", "register") { req -> EventLoopFuture<SessionToken> in
|
||||||
|
let name = try req.header(.name)
|
||||||
|
let password = try req.header(.password)
|
||||||
|
let mail = req.optionalHeader(.email)?.trimmed.nonEmpty
|
||||||
|
|
||||||
/**
|
|
||||||
Create a new player
|
|
||||||
- Parameter name: The name of the player, included in the url
|
|
||||||
- Parameter password: The password of the player, as a string in the request body
|
|
||||||
- Throws:
|
|
||||||
- 400: Missing name or password
|
|
||||||
- 406: Password or name too long
|
|
||||||
- 409: A player with the same name already exists
|
|
||||||
- 424: The password could not be hashed
|
|
||||||
- Returns: The session token for the registered user
|
|
||||||
*/
|
|
||||||
app.post("player", "register", ":name") { req -> EventLoopFuture<SessionToken> in
|
|
||||||
guard let name = req.parameters.get("name"),
|
|
||||||
let password = req.body.string else {
|
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
guard name.count < maximumPlayerNameLength,
|
guard name.count < maximumPlayerNameLength,
|
||||||
password.count < maximumPasswordLength else {
|
password.count < maximumPasswordLength else {
|
||||||
throw Abort(.notAcceptable) // 406
|
throw Abort(.notAcceptable) // 406
|
||||||
@ -45,17 +66,19 @@ func routes(_ app: Application) throws {
|
|||||||
// Can throw conflict (409)
|
// Can throw conflict (409)
|
||||||
return server.registerPlayer(named: name, hash: hash, in: req.db)
|
return server.registerPlayer(named: name, hash: hash, in: req.db)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Delete a player.
|
||||||
|
|
||||||
/**
|
- Parameter name: The name of the player, included in the url
|
||||||
Delete a player.
|
- Parameter password: The password of the player, as a string in the request body
|
||||||
- Parameter name: The name of the player, included in the url
|
- Throws:
|
||||||
- Parameter password: The password of the player, as a string in the request body
|
- 400: Missing name or password
|
||||||
- Throws:
|
- 403: The password or user name is invalid
|
||||||
- 400: Missing name or password
|
- 424: The password could not be hashed
|
||||||
- 403: The password or user name is invalid
|
- Returns: Nothing
|
||||||
- 424: The password could not be hashed
|
*/
|
||||||
- Returns: Nothing
|
func deletePlayer(_ app: Application) {
|
||||||
*/
|
|
||||||
app.post("player", "delete", ":name") { req -> EventLoopFuture<String> in
|
app.post("player", "delete", ":name") { req -> EventLoopFuture<String> in
|
||||||
guard let name = req.parameters.get("name"),
|
guard let name = req.parameters.get("name"),
|
||||||
let password = req.body.string else {
|
let password = req.body.string else {
|
||||||
@ -68,6 +91,7 @@ func routes(_ app: Application) throws {
|
|||||||
server.deletePlayer(named: name, in: req.db)
|
server.deletePlayer(named: name, in: req.db)
|
||||||
}.map { "" }
|
}.map { "" }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Log in as an existing player.
|
Log in as an existing player.
|
||||||
@ -79,6 +103,7 @@ func routes(_ app: Application) throws {
|
|||||||
- 424: The password could not be hashed
|
- 424: The password could not be hashed
|
||||||
- Returns: The session token for the user
|
- Returns: The session token for the user
|
||||||
*/
|
*/
|
||||||
|
func loginPlayer(_ app: Application) {
|
||||||
app.post("player", "login", ":name") { req -> EventLoopFuture<String> in
|
app.post("player", "login", ":name") { req -> EventLoopFuture<String> in
|
||||||
guard let name = req.parameters.get("name"),
|
guard let name = req.parameters.get("name"),
|
||||||
let password = req.body.string else {
|
let password = req.body.string else {
|
||||||
@ -91,6 +116,7 @@ func routes(_ app: Application) throws {
|
|||||||
server.startNewSessionForRegisteredPlayer(named: name)
|
server.startNewSessionForRegisteredPlayer(named: name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Log in using a session token.
|
Log in using a session token.
|
||||||
@ -100,6 +126,7 @@ func routes(_ app: Application) throws {
|
|||||||
- 401: The token is invalid
|
- 401: The token is invalid
|
||||||
- Returns: The player name associated with the session token
|
- Returns: The player name associated with the session token
|
||||||
*/
|
*/
|
||||||
|
func resumeSession(_ app: Application) {
|
||||||
app.post("player", "resume") { req -> String in
|
app.post("player", "resume") { req -> String in
|
||||||
guard let token = req.body.string else {
|
guard let token = req.body.string else {
|
||||||
throw Abort(.badRequest) // 400
|
throw Abort(.badRequest) // 400
|
||||||
@ -109,6 +136,7 @@ func routes(_ app: Application) throws {
|
|||||||
}
|
}
|
||||||
return player
|
return player
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Log out.
|
Log out.
|
||||||
@ -119,6 +147,7 @@ func routes(_ app: Application) throws {
|
|||||||
- Returns: Nothing
|
- Returns: Nothing
|
||||||
- Note: The request always succeeds when correctly formed, even for invalid and expired tokens
|
- Note: The request always succeeds when correctly formed, even for invalid and expired tokens
|
||||||
*/
|
*/
|
||||||
|
func logoutPlayer(_ app: Application) {
|
||||||
app.post("player", "logout") { req -> String in
|
app.post("player", "logout") { req -> String in
|
||||||
guard let token = req.body.string else {
|
guard let token = req.body.string else {
|
||||||
throw Abort(.badRequest) // 400
|
throw Abort(.badRequest) // 400
|
||||||
@ -126,6 +155,7 @@ func routes(_ app: Application) throws {
|
|||||||
server.endSession(forSessionToken: token)
|
server.endSession(forSessionToken: token)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the current table of the player, if one exists.
|
Get the current table of the player, if one exists.
|
||||||
@ -135,6 +165,7 @@ func routes(_ app: Application) throws {
|
|||||||
- 401: Invalid token
|
- 401: Invalid token
|
||||||
- Returns: The table info, or an empty string
|
- Returns: The table info, or an empty string
|
||||||
*/
|
*/
|
||||||
|
func getTableForPlayer(_ app: Application) {
|
||||||
app.post("player", "table") { req -> String in
|
app.post("player", "table") { req -> String in
|
||||||
guard let token = req.body.string else {
|
guard let token = req.body.string else {
|
||||||
throw Abort(.badRequest) // 400
|
throw Abort(.badRequest) // 400
|
||||||
@ -147,12 +178,14 @@ func routes(_ app: Application) throws {
|
|||||||
}
|
}
|
||||||
return try encodeJSON(info)
|
return try encodeJSON(info)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start a new websocket connection for the client to receive table updates from the server
|
Start a new websocket connection for the client to receive table updates from the server
|
||||||
- Returns: Nothing
|
- Returns: Nothing
|
||||||
- Note: The first (and only) message from the client over the connection must be a valid session token.
|
- Note: The first (and only) message from the client over the connection must be a valid session token.
|
||||||
*/
|
*/
|
||||||
|
func openWebsocket(_ app: Application) {
|
||||||
app.webSocket("session", "start") { req, socket in
|
app.webSocket("session", "start") { req, socket in
|
||||||
socket.onText { socket, text in
|
socket.onText { socket, text in
|
||||||
guard server.startSession(socket: socket, sessionToken: text) else {
|
guard server.startSession(socket: socket, sessionToken: text) else {
|
||||||
@ -161,6 +194,7 @@ func routes(_ app: Application) throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Tables
|
// MARK: Tables
|
||||||
|
|
||||||
@ -173,12 +207,13 @@ func routes(_ app: Application) throws {
|
|||||||
- 400: Missing token, table name or invalid visibility
|
- 400: Missing token, table name or invalid visibility
|
||||||
- 401: The session token is invalid
|
- 401: The session token is invalid
|
||||||
*/
|
*/
|
||||||
|
func createTable(_ app: Application) {
|
||||||
app.post("table", "create", ":visibility", ":name") { req -> EventLoopFuture<String> in
|
app.post("table", "create", ":visibility", ":name") { req -> EventLoopFuture<String> in
|
||||||
guard let visibility = req.parameters.get("visibility"),
|
guard let visibility = req.parameters.get("visibility"),
|
||||||
let tableName = req.parameters.get("name"),
|
let tableName = req.parameters.get("name"),
|
||||||
let token = req.body.string else {
|
let token = req.body.string else {
|
||||||
throw Abort(.badRequest) // 400
|
throw Abort(.badRequest) // 400
|
||||||
}
|
}
|
||||||
let isPublic: Bool
|
let isPublic: Bool
|
||||||
if visibility == "private" {
|
if visibility == "private" {
|
||||||
isPublic = false
|
isPublic = false
|
||||||
@ -194,6 +229,7 @@ func routes(_ app: Application) throws {
|
|||||||
return server.createTable(named: tableName, player: player, isPublic: isPublic, in: req.db)
|
return server.createTable(named: tableName, player: player, isPublic: isPublic, in: req.db)
|
||||||
.flatMapThrowing(encodeJSON)
|
.flatMapThrowing(encodeJSON)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
List the public tables.
|
List the public tables.
|
||||||
@ -203,6 +239,7 @@ func routes(_ app: Application) throws {
|
|||||||
- 403: The session token is invalid
|
- 403: The session token is invalid
|
||||||
- Returns: A JSON object with a list of public tables (id, name, player list)
|
- Returns: A JSON object with a list of public tables (id, name, player list)
|
||||||
*/
|
*/
|
||||||
|
func getPublicTables(_ app: Application) {
|
||||||
app.post("tables", "public") { req -> String in
|
app.post("tables", "public") { req -> String in
|
||||||
guard let token = req.body.string else {
|
guard let token = req.body.string else {
|
||||||
throw Abort(.badRequest) // 400
|
throw Abort(.badRequest) // 400
|
||||||
@ -213,6 +250,7 @@ func routes(_ app: Application) throws {
|
|||||||
let list = server.getPublicTableInfos()
|
let list = server.getPublicTableInfos()
|
||||||
return try encodeJSON(list)
|
return try encodeJSON(list)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Join a table.
|
Join a table.
|
||||||
@ -226,6 +264,8 @@ func routes(_ app: Application) throws {
|
|||||||
- 417: The table is already full and can't be joined
|
- 417: The table is already full and can't be joined
|
||||||
- Returns: Nothing
|
- Returns: Nothing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
func joinTable(_ app: Application) {
|
||||||
app.post("table", "join", ":table") { req -> EventLoopFuture<String> in
|
app.post("table", "join", ":table") { req -> EventLoopFuture<String> in
|
||||||
guard let string = req.parameters.get("table"),
|
guard let string = req.parameters.get("table"),
|
||||||
let table = UUID(uuidString: string),
|
let table = UUID(uuidString: string),
|
||||||
@ -235,6 +275,7 @@ func routes(_ app: Application) throws {
|
|||||||
return server.join(tableId: table, playerToken: token, in: req.db)
|
return server.join(tableId: table, playerToken: token, in: req.db)
|
||||||
.flatMapThrowing(encodeJSON)
|
.flatMapThrowing(encodeJSON)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Leave the current table.
|
Leave the current table.
|
||||||
@ -244,18 +285,21 @@ func routes(_ app: Application) throws {
|
|||||||
- 401: The session token is invalid
|
- 401: The session token is invalid
|
||||||
- Returns: Nothing
|
- Returns: Nothing
|
||||||
*/
|
*/
|
||||||
|
func leaveTable(_ app: Application) {
|
||||||
app.post("table", "leave") { req -> EventLoopFuture<String> in
|
app.post("table", "leave") { req -> EventLoopFuture<String> in
|
||||||
guard let token = req.body.string else {
|
guard let token = req.body.string else {
|
||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
return server.leaveTable(playerToken: token, in: req.db).map { "" }
|
return server.leaveTable(playerToken: token, in: req.db).map { "" }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func performActionForPlayer(_ app: Application) {
|
||||||
app.post("player", "action", ":action") { req -> String in
|
app.post("player", "action", ":action") { req -> String in
|
||||||
guard let token = req.body.string,
|
guard let token = req.body.string,
|
||||||
let actionString = req.parameters.get("action") else {
|
let actionString = req.parameters.get("action") else {
|
||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
let result: PlayerActionResult
|
let result: PlayerActionResult
|
||||||
if let action = PlayerAction(rawValue: actionString) {
|
if let action = PlayerAction(rawValue: actionString) {
|
||||||
result = server.performAction(playerToken: token, action: action)
|
result = server.performAction(playerToken: token, action: action)
|
||||||
@ -279,7 +323,9 @@ func routes(_ app: Application) throws {
|
|||||||
throw Abort(.preconditionFailed) // 412
|
throw Abort(.preconditionFailed) // 412
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func playCard(_ app: Application) {
|
||||||
app.post("player", "card", ":card") { req -> String in
|
app.post("player", "card", ":card") { req -> String in
|
||||||
guard let token = req.body.string,
|
guard let token = req.body.string,
|
||||||
let cardId = req.parameters.get("card"),
|
let cardId = req.parameters.get("card"),
|
||||||
|
Loading…
Reference in New Issue
Block a user