Skip to content

Commit

Permalink
preparing the creation of users
Browse files Browse the repository at this point in the history
  • Loading branch information
Dracks committed Dec 10, 2024
1 parent 700c564 commit 620d124
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 37 deletions.
8 changes: 6 additions & 2 deletions src/swift-server-macros/entrypoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ public protocol StringEnumType: Hashable & RawRepresentable where Self.RawValue
@freestanding(expression)
public macro BasicBadRequest<T>(msg: String, code: any StringEnumType) -> T =
#externalMacro(module: "swift_macrosMacros", type: "BasicBadRequest")

@freestanding(expression)
public macro BasicNotFound<T>(msg: String, code: any StringEnumType) -> T =
#externalMacro(module: "swift_macrosMacros", type: "BasicNotFound")
#externalMacro(module: "swift_macrosMacros", type: "BasicNotFound")

@freestanding(expression)
public macro GenericErrorReturn<T>(response: String, msg: String, code: any StringEnumType) -> T =
#externalMacro(module: "swift_macrosMacros", type: "GenericErrorReturn")
4 changes: 2 additions & 2 deletions src/swift-server-macrosMacros/app-dependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros


public struct ServiceDependencyMacro: AccessorMacro {

public static func expansion(
Expand All @@ -23,7 +22,8 @@ public struct ServiceDependencyMacro: AccessorMacro {

guard let nodeType = varDecl.bindings.first?.typeAnnotation?.type else {
let missingAnnotationErr = Diagnostic(
node: node.root, message: MacroExpansionErrorMessage("Missing anotation"))
node: node.root,
message: MacroExpansionErrorMessage("Missing anotation"))
context.diagnose(missingAnnotationErr)
return []
}
Expand Down
39 changes: 38 additions & 1 deletion src/swift-server-macrosMacros/basic-errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public struct BasicBadRequest: ExpressionMacro {
}
}


public struct BasicNotFound: ExpressionMacro {
public static func expansion(
of node: some SwiftSyntax.FreestandingMacroExpansionSyntax,
Expand Down Expand Up @@ -65,3 +64,41 @@ public struct BasicNotFound: ExpressionMacro {
"""
}
}

public struct GenericErrorReturn: ExpressionMacro {
public static func expansion(
of node: some SwiftSyntax.FreestandingMacroExpansionSyntax,
in context: some SwiftSyntaxMacros.MacroExpansionContext
) throws -> ExprSyntax {
guard
let response = node.arguments.first?.expression.as(
StringLiteralExprSyntax.self)?.representedLiteralValue
else {
throw CustomError.message("First parameter should be an string")
}

guard
let message = node.arguments.dropFirst().first?.expression.as(
StringLiteralExprSyntax.self)?.representedLiteralValue
else {
throw CustomError.message("Second parameter should be an string")
}

guard
let expression = node.arguments.dropFirst().dropFirst().first?.expression
.as(
MemberAccessExprSyntax.self)
else {
throw CustomError.message("Invalid code")
}
let text = expression.declName.baseName.text
return """
.\(raw: response)(
.init(
body: .json(
.init(
message: "\(raw: message)",
code: "\(raw: text)"))))
"""
}
}
1 change: 1 addition & 0 deletions src/swift-server-macrosMacros/entrypoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ struct swift_macrosPlugin: CompilerPlugin {
ServiceDependencyMacro.self,
BasicBadRequest.self,
BasicNotFound.self,
GenericErrorReturn.self,
]
}
58 changes: 55 additions & 3 deletions src/swift-server-tests/profile.tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class ProfileTests: AbstractBaseTestsClass {

let response = try await app.sendRequest(.GET, "/api/users", headers: headers)

XCTAssertEqual(response.status, .unauthorized)
XCTAssertEqual(response.status, .unauthorized)

let data = try response.content.decode(Components.Schemas._Error.self)

Expand Down Expand Up @@ -113,9 +113,61 @@ final class ProfileTests: AbstractBaseTestsClass {

func testUpdateWithInvalidDefaultGroupId() async throws {}

func testCreateUser() async throws {}
func testCreateUserAsUser() async throws {
let app = try getApp()

let headers = try await app.getHeaders(
forUser: .init(username: testUser.username, password: "test-password"))

let newUser = Components.Schemas.CreateUserParams(
username: "Some new user",
email: "[email protected]",
firstName: "First naming",
lastName: "Last naming",
isActive: true,
isAdmin: true,
password: "Some stupid password"
)

let response = try await app.sendRequest(
.POST, "/api/users/", body: newUser,
headers: headers)

XCTAssertEqual(response.status, .unauthorized)
}

func testCreateUserAsAdmin() async throws {}
func testCreateUserAsAdmin() async throws {
let app = try getApp()

let headers = try await app.getHeaders(
forUser: .init(
username: testAdmin.username, password: "test-admin-password"))

let newUser = Components.Schemas.CreateUserParams(
username: "Some new user",
email: "[email protected]",
firstName: "First naming",
lastName: "Last naming",
isActive: true,
isAdmin: false,
password: "Some stupid password"
)

let response = try await app.sendRequest(
.POST, "/api/users/", body: newUser,
headers: headers)

XCTAssertEqual(response.status, .created)
let user = try response.content.decode(Components.Schemas.UserProfile.self)
XCTAssertEqual(user.username, "Same new user")
XCTAssertEqual(user.email, "[email protected]")
XCTAssertEqual(user.firstName, "First naming")
XCTAssertEqual(user.lastName, "Last naming")
XCTAssertEqual(user.isActive, true)
XCTAssertEqual(user.isAdmin, false)


}

func testDeleteUser() async throws {}

Expand Down
2 changes: 1 addition & 1 deletion src/swift-server/core/error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum ApiError: String, StringEnumType {
API10038, API10039
case API10040, API10041, API10042, API10043, API10044, API10045, API10046, API10047,
API10048, API10049
case API10050
case API10050, API10051
}

class ErrorInfo {
Expand Down
10 changes: 5 additions & 5 deletions src/swift-server/core/validations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ extension TransformerAndValidator {
var parentRule: Rule = realParent
var visitedRuleIds = Set<UUID>()
while true {
let parentRuleId = try parentRule.requireID()
if visitedRuleIds.contains(parentRuleId){
return .itsOwnParent
}
visitedRuleIds.insert(parentRuleId)
let parentRuleId = try parentRule.requireID()
if visitedRuleIds.contains(parentRuleId) {
return .itsOwnParent
}
visitedRuleIds.insert(parentRuleId)
if parentRuleId == ruleId {
return .itsOwnParent
}
Expand Down
2 changes: 1 addition & 1 deletion src/swift-server/routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct ErrorHandlerMiddleware: AsyncMiddleware {
throw abort
}
if let _ = error.underlyingError as? NotIdentifiedError {
throw Abort(.unauthorized, reason: "Not identified")
throw Abort(.unauthorized, reason: "Not identified")
}
print("Server Error")
print(error.underlyingError)
Expand Down
15 changes: 8 additions & 7 deletions src/swift-server/rules/rule-api-impl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,11 @@ extension MrScroogeAPIImpl {
labelId: labelId, toRule: ruleId, for: validGroupsIds)
{
case .ok(let rule):
return .ok(.init(body: .json(try .init(rule: rule))))
return .ok(.init(body: .json(try .init(rule: rule))))
case .notFound:
return #BasicNotFound(
msg: "Condition or label not found", code: ApiError.API10048)
return #BasicNotFound(
msg: "Condition or label not found", code: ApiError.API10048)

case .invalidOwnerId:
return .conflict(
.init(
Expand All @@ -376,13 +376,14 @@ extension MrScroogeAPIImpl {
return #BasicBadRequest(
msg: "Label ID should be an UUID", code: ApiError.API10047)
}
let removeState = try await request.application.ruleService.removeLabel(labelId: labelId, fromRule: ruleId, for: validGroupsIds)
let removeState = try await request.application.ruleService.removeLabel(
labelId: labelId, fromRule: ruleId, for: validGroupsIds)
switch removeState {
case .ok(let rule):
return .ok(.init(body: .json(try .init(rule: rule))))
case .notFound:
return #BasicNotFound(
msg: "Rule not found", code: ApiError.API10050)
return #BasicNotFound(
msg: "Rule not found", code: ApiError.API10050)
}
}
}
Expand Down
29 changes: 15 additions & 14 deletions src/swift-server/user/user-api-impl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import Foundation
import OpenAPIRuntime
import OpenAPIVapor
import Vapor
import swift_macros

extension MrScroogeAPIImpl {
func ApiUser_create(_ input: Operations.ApiUser_create.Input) async throws
-> Operations.ApiUser_create.Output
{
let user = try await getUser(fromRequest: request)
guard user.isAdmin else {
return #GenericErrorReturn(
response: "unauthorized",
msg: "Only admin users can create new users",
code: ApiError.API10051)
}
return .undocumented(statusCode: 501, UndocumentedPayload())
}

Expand All @@ -15,13 +23,9 @@ extension MrScroogeAPIImpl {
{
let user = try await getUser(fromRequest: request)
guard user.isAdmin else {
return .unauthorized(
.init(
body: .json(
.init(
message:
"Only admin users can list the users",
code: ApiError.API10013.rawValue))))
return #GenericErrorReturn(
response: "unauthorized",
msg: "Only admin users can list the users", code: ApiError.API10013)
}

let data = try await request.application.userService.getUsersPage(
Expand All @@ -41,13 +45,10 @@ extension MrScroogeAPIImpl {
-> Operations.ApiUser_update.Output
{
guard try await getUser(fromRequest: request).isAdmin else {
return .unauthorized(
.init(
body: .json(
.init(
message:
"Only admin users can modify other users",
code: ApiError.API10014.rawValue))))
return #GenericErrorReturn(
response: "unauthorized",
msg: "Only admin users can modify other users",
code: ApiError.API10014)
}
let updateUser: Components.Schemas.UpdateUserData
switch input.body {
Expand Down
4 changes: 3 additions & 1 deletion src/swift-server/user/user.service.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import Vapor

class UserService: ServiceWithDb {
private let cursorHandler = CursorHandler<User, String>(["id"])

func createUser() async throws {

}
func getUsersPage(pageQuery: PageQuery) async throws -> ListWithCursor<
User
> {
Expand Down

0 comments on commit 620d124

Please sign in to comment.