You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

146 lines
5.5 KiB

  1. //
  2. // cntrlAddociate.swift
  3. //
  4. //
  5. // Created by Michiel Carman on 4/11/2024.
  6. //
  7. import Fluent
  8. import Vapor
  9. import Crypto
  10. struct cntrlAssociate: RouteCollection {
  11. func boot(routes: RoutesBuilder) throws {
  12. let rts = routes.grouped("associates")
  13. rts.get(use: index)
  14. rts.get(":x", use: read)
  15. rts.post(use: create)
  16. rts.delete(":x", use: delete)
  17. rts.post("create", use: createUser)
  18. let passwordProtected = rts.grouped(mdlAssociate.authenticator(), mdlAssociate.guardMiddleware())
  19. passwordProtected.post("login", use: login)
  20. passwordProtected.post("tlogin", use: jwtauth)
  21. let tokenProtected = rts.grouped(mdlToken.authenticator())
  22. tokenProtected.get("tauth", use: auth)
  23. //Additional routs added here
  24. }
  25. @Sendable
  26. func jwtauth(req: Request) async throws -> ClientTokenResponse{
  27. let user = try req.auth.require(mdlAssociate.self)
  28. let payload = SessionToken(user: user)
  29. return ClientTokenResponse(token: try req.jwt.sign(payload))
  30. }
  31. @Sendable
  32. func auth(req: Request) async throws -> Response{
  33. let result = try req.auth.require(mdlAssociate.self)
  34. let assoc = mdlAssociate.Output(id: result.id, firstname: result.firstname, lastname: result.lastname)
  35. guard let response = try? await assoc.encodeResponse(status: .ok, for: req) else{
  36. throw Abort(.noContent, reason: "Something went wrong decoding data. Associate could not be shown.")
  37. }
  38. return response
  39. }
  40. @Sendable
  41. func login(req: Request) async throws -> Response{
  42. guard let result = try? req.auth.require(mdlAssociate.self) else{
  43. throw Abort(.unauthorized)
  44. }
  45. let token = try await result.generateToken()
  46. try await token.save(on: req.db)
  47. guard let response = try? await token.encodeResponse(status: .ok, for: req) else{
  48. throw Abort(.noContent, reason: "Something went wrong decoding data. Token could not be shown.")
  49. }
  50. return response
  51. }
  52. @Sendable
  53. func createUser(req: Request) async throws -> Response{
  54. try mdlAssociate.CreateUser.validate(content: req)
  55. let create = try req.content.decode(mdlAssociate.CreateUser.self)
  56. guard create.password == create.confirmpassword else{
  57. throw Abort(.badRequest, reason: "Passwords did not match")
  58. }
  59. let user = try mdlAssociate(
  60. firstname: create.firstname,
  61. lastname: create.lastname,
  62. username: create.username,
  63. password: Bcrypt.hash(create.password)
  64. )
  65. try await user.save(on: req.db)
  66. let assoc = mdlAssociate.Output(id: user.id, firstname: user.firstname, lastname: user.lastname)
  67. guard let response = try? await assoc.encodeResponse(status: .ok, for: req) else{
  68. throw Abort(.noContent, reason: "Something went wrong decoding data. Associate could not be shown.")
  69. }
  70. return response
  71. }
  72. @Sendable
  73. func index(req: Request) async throws -> Response {
  74. let obj = try await mdlAssociate.ObjQuery(req: req).all()
  75. // guard let obj = try? await mdlAssociate.ObjQuery(req: req).all() else {
  76. // throw Abort(.badGateway, reason: "Something went wrong with this api.")
  77. // }
  78. guard let response = try? await obj.encodeResponse(status: .ok, for: req) else{
  79. throw Abort(.noContent, reason: "Something went wrong decoding data. Array could not be shown.")
  80. }
  81. return response
  82. }
  83. @Sendable
  84. func read(req:Request) async throws -> Response{
  85. guard let obj = try? await mdlAssociate.ObjQuery(req: req).first() else{
  86. throw Abort(.notFound, reason: "Associate was not found.")
  87. }
  88. guard let response = try? await obj.encodeResponse(status: .ok, for: req) else {
  89. throw Abort(.noContent, reason: "Something went wrong decoding object.")
  90. }
  91. return response
  92. }
  93. @Sendable
  94. func create(req: Request) async throws -> Response {
  95. guard let obj = try? req.content.decode(mdlAssociate.self) else {
  96. throw Abort(.notAcceptable, reason: "Associate json not formatted correctly or is missing parents.")
  97. }
  98. var exists = false
  99. if(obj.id != nil){
  100. obj._$idExists = true
  101. exists = true
  102. }
  103. guard let _ = try? await obj.save(on: req.db) else{
  104. throw Abort(.conflict, reason: "Something conflicts in the database. Associate cannot be saved.")
  105. }
  106. guard let response = try? await obj.encodeResponse(status: exists ? .accepted : .created, for: req) else{
  107. throw Abort(.noContent, reason: "Something went wrong decoding data. Associate has been saved.")
  108. }
  109. return response
  110. }
  111. @Sendable
  112. func delete(req: Request) async throws -> Response {
  113. guard let obj = try? await mdlAssociate.ObjQuery(req: req).first() else {
  114. throw Abort(.notFound, reason: "Associate's ID was not supplied. Associate will not be deleted")
  115. }
  116. guard let _ = try? await obj.delete(on: req.db) else{
  117. throw Abort(.conflict, reason: "There was a conflict deleting Associate. Make sure it has not children.")
  118. }
  119. guard let response = try? await obj.encodeResponse(status: .ok, for: req) else{
  120. throw Abort(.noContent, reason: "Something went wrong decoding data. Associate has been deleted.")
  121. }
  122. return response
  123. }
  124. }