From c863c66236bf788b487da03d8db3127f322ddc01 Mon Sep 17 00:00:00 2001 From: Christian Risi <75698846+CnF-Gris@users.noreply.github.com> Date: Sun, 8 Dec 2024 20:38:43 +0000 Subject: [PATCH] Initial Commit --- .devcontainer/devcontainer.json | 73 ++++--- .gitignore | 230 ++++++++++----------- .vscode/launch.json | 60 ++++-- Package.swift | 84 ++++---- Sources/App/Utils/P256-keys-creation.swift | 13 ++ Sources/App/configure.swift | 18 +- Sources/App/entrypoint.swift | 62 +++--- Sources/App/routes.swift | 24 ++- Tests/AppTests/AppTests.swift | 58 +++--- 9 files changed, 335 insertions(+), 287 deletions(-) create mode 100644 Sources/App/Utils/P256-keys-creation.swift diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 58f5dce..bec7ea6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,32 +1,43 @@ -{ - // Displayed name - "name": "IoT-Simulator", - - // Image to be used - "image": "swift", - - // Env in container - "containerEnv": { - - }, - - // Mounts in container - "mounts": [ - { - "source": "${localWorkspaceFolder}", - "target": "/workspace", - "type": "bind" - } - ], - - // The WorkspaceFolder inside container - "workspaceFolder": "/workspace", - - // RunArgs - "runArgs": [ - "--name", - "IoT-Simulator-Vapor" - ] - - +{ + // Displayed name + "name": "IoT-Simulator", + + // Image to be used + "image": "swift", + + // Env in container + "containerEnv": { + + }, + + // Customization + "customizations": { + "vscode": { + "extensions": [ + "sswg.swift-lang", + "fabiospampinato.vscode-highlight", + "fabiospampinato.vscode-todo-plus" + ] + } + }, + + // Mounts in container + "mounts": [ + { + "source": "${localWorkspaceFolder}", + "target": "/workspace", + "type": "bind" + } + ], + + // The WorkspaceFolder inside container + "workspaceFolder": "/workspace", + + // RunArgs + "runArgs": [ + "--name", + "IoT-Simulator-Vapor" + ] + + } \ No newline at end of file diff --git a/.gitignore b/.gitignore index 78d9cc0..14a47e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,116 +1,116 @@ -############################## -## macOS -############################## -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -############################## -## Swift -############################## - -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## User settings -xcuserdata/ - -## Obj-C/Swift specific -*.hmap - -## App packaging -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -# *.xcodeproj -# -# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata -# hence it is not needed unless you have added a package configuration file to your project -# .swiftpm - -.build/ - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build/ - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. -# Instead, use fastlane to re-generate the screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output - -############################## -## Vapor -############################## - -Packages -.build -.DS_Store -*.xcodeproj -DerivedData/ -Package.resolved -.swiftpm -Tests/LinuxMain.swift -.bash_history -.cache/ - -# API Docs Generation -generate-package-api-docs.swift +############################## +## macOS +############################## +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +############################## +## Swift +############################## + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ +# +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +############################## +## Vapor +############################## + +Packages +.build +.DS_Store +*.xcodeproj +DerivedData/ +Package.resolved +.swiftpm +Tests/LinuxMain.swift +.bash_history +.cache/ + +# API Docs Generation +generate-package-api-docs.swift theme-settings.json \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 00bed33..d952704 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,22 +1,40 @@ -{ - "configurations": [ - { - "type": "lldb", - "request": "launch", - "args": [], - "cwd": "${workspaceFolder:workspace}", - "name": "Debug IoT-Simulator", - "program": "${workspaceFolder:workspace}/.build/debug/IoT-Simulator", - "preLaunchTask": "swift: Build Debug IoT-Simulator" - }, - { - "type": "lldb", - "request": "launch", - "args": [], - "cwd": "${workspaceFolder:workspace}", - "name": "Release IoT-Simulator", - "program": "${workspaceFolder:workspace}/.build/release/IoT-Simulator", - "preLaunchTask": "swift: Build Release IoT-Simulator" - } - ] +{ + "configurations": [ + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:workspace}", + "name": "Debug IoT-Simulator", + "program": "${workspaceFolder:workspace}/.build/debug/IoT-Simulator", + "preLaunchTask": "swift: Build Debug IoT-Simulator" + }, + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:workspace}", + "name": "Release IoT-Simulator", + "program": "${workspaceFolder:workspace}/.build/release/IoT-Simulator", + "preLaunchTask": "swift: Build Release IoT-Simulator" + }, + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:workspace}", + "name": "Debug App", + "program": "${workspaceFolder:workspace}/.build/debug/App", + "preLaunchTask": "swift: Build Debug App" + }, + { + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "${workspaceFolder:workspace}", + "name": "Release App", + "program": "${workspaceFolder:workspace}/.build/release/App", + "preLaunchTask": "swift: Build Release App" + } + ] } \ No newline at end of file diff --git a/Package.swift b/Package.swift index ec6a733..6d5b387 100644 --- a/Package.swift +++ b/Package.swift @@ -1,40 +1,44 @@ -// swift-tools-version:6.0 -import PackageDescription - -let package = Package( - name: "template-bare", - platforms: [ - .macOS(.v13) - ], - dependencies: [ - // 💧 A server-side Swift web framework. - .package(url: "https://github.com/vapor/vapor.git", from: "4.99.3"), - // 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors - .package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"), - ], - targets: [ - .executableTarget( - name: "App", - dependencies: [ - .product(name: "Vapor", package: "vapor"), - .product(name: "NIOCore", package: "swift-nio"), - .product(name: "NIOPosix", package: "swift-nio"), - ], - swiftSettings: swiftSettings - ), - .testTarget( - name: "AppTests", - dependencies: [ - .target(name: "App"), - .product(name: "XCTVapor", package: "vapor"), - ], - swiftSettings: swiftSettings - ) - ], - swiftLanguageModes: [.v5] -) - -var swiftSettings: [SwiftSetting] { [ - .enableUpcomingFeature("DisableOutwardActorInference"), - .enableExperimentalFeature("StrictConcurrency"), -] } +// swift-tools-version:6.0 +import PackageDescription + +let package = Package( + name: "template-bare", + platforms: [ + .macOS(.v13) + ], + dependencies: [ + // 💧 A server-side Swift web framework. + .package(url: "https://github.com/vapor/vapor.git", from: "4.99.3"), + // 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors + .package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"), + .package(url: "https://github.com/apple/swift-crypto.git", branch: "main"), + .package(url: "https://repositories.communitynotfound.work/PoliBa-Software-Architecture/Swift-MessageUtils.git", branch: "main") + ], + targets: [ + .executableTarget( + name: "App", + dependencies: [ + .product(name: "Vapor", package: "vapor"), + .product(name: "NIOCore", package: "swift-nio"), + .product(name: "NIOPosix", package: "swift-nio"), + .product(name: "Crypto", package: "swift-crypto"), + .product(name: "MessageUtils", package: "Swift-MessageUtils"), + ], + swiftSettings: swiftSettings + ), + .testTarget( + name: "AppTests", + dependencies: [ + .target(name: "App"), + .product(name: "XCTVapor", package: "vapor"), + ], + swiftSettings: swiftSettings + ) + ], + swiftLanguageModes: [.v5] +) + +var swiftSettings: [SwiftSetting] { [ + .enableUpcomingFeature("DisableOutwardActorInference"), + .enableExperimentalFeature("StrictConcurrency"), +] } diff --git a/Sources/App/Utils/P256-keys-creation.swift b/Sources/App/Utils/P256-keys-creation.swift new file mode 100644 index 0000000..9d7669b --- /dev/null +++ b/Sources/App/Utils/P256-keys-creation.swift @@ -0,0 +1,13 @@ +import Crypto + +public func createPrivateP256Key() -> P256.Signing.PrivateKey { + return P256.Signing.PrivateKey() +} + +public func createPublickP256Key(privateKey: P256.Signing.PrivateKey ) -> P256.Signing.PublicKey { + return privateKey.publicKey +} + +public func publicP256_2_Spki(publicKey: P256.Signing.PublicKey) -> String { + return publicKey.pemRepresentation +} \ No newline at end of file diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index b84cb15..b64a5f3 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -1,9 +1,9 @@ -import Vapor - -// configures your application -public func configure(_ app: Application) async throws { - // uncomment to serve files from /Public folder - // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) - // register routes - try routes(app) -} +import Vapor + +// configures your application +public func configure(_ app: Application) async throws { + // uncomment to serve files from /Public folder + // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) + // register routes + try routes(app) +} diff --git a/Sources/App/entrypoint.swift b/Sources/App/entrypoint.swift index 2e85ece..c619a87 100644 --- a/Sources/App/entrypoint.swift +++ b/Sources/App/entrypoint.swift @@ -1,31 +1,31 @@ -import Vapor -import Logging -import NIOCore -import NIOPosix - -@main -enum Entrypoint { - static func main() async throws { - var env = try Environment.detect() - try LoggingSystem.bootstrap(from: &env) - - let app = try await Application.make(env) - - // This attempts to install NIO as the Swift Concurrency global executor. - // You can enable it if you'd like to reduce the amount of context switching between NIO and Swift Concurrency. - // Note: this has caused issues with some libraries that use `.wait()` and cleanly shutting down. - // If enabled, you should be careful about calling async functions before this point as it can cause assertion failures. - // let executorTakeoverSuccess = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor() - // app.logger.debug("Tried to install SwiftNIO's EventLoopGroup as Swift's global concurrency executor", metadata: ["success": .stringConvertible(executorTakeoverSuccess)]) - - do { - try await configure(app) - } catch { - app.logger.report(error: error) - try? await app.asyncShutdown() - throw error - } - try await app.execute() - try await app.asyncShutdown() - } -} +import Vapor +import Logging +import NIOCore +import NIOPosix + +@main +enum Entrypoint { + static func main() async throws { + var env = try Environment.detect() + try LoggingSystem.bootstrap(from: &env) + + let app = try await Application.make(env) + + // This attempts to install NIO as the Swift Concurrency global executor. + // You can enable it if you'd like to reduce the amount of context switching between NIO and Swift Concurrency. + // Note: this has caused issues with some libraries that use `.wait()` and cleanly shutting down. + // If enabled, you should be careful about calling async functions before this point as it can cause assertion failures. + // let executorTakeoverSuccess = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor() + // app.logger.debug("Tried to install SwiftNIO's EventLoopGroup as Swift's global concurrency executor", metadata: ["success": .stringConvertible(executorTakeoverSuccess)]) + + do { + try await configure(app) + } catch { + app.logger.report(error: error) + try? await app.asyncShutdown() + throw error + } + try await app.execute() + try await app.asyncShutdown() + } +} diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 2edcc8f..5f56f83 100644 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -1,11 +1,13 @@ -import Vapor - -func routes(_ app: Application) throws { - app.get { req async in - "It works!" - } - - app.get("hello") { req async -> String in - "Hello, world!" - } -} +import Vapor +import MessageUtils +import Foundation + +func routes(_ app: Application) throws { + app.get { req async in + "It works!" + } + + app.get("hello") { req async -> String in + return "Hello, world!" + } +} diff --git a/Tests/AppTests/AppTests.swift b/Tests/AppTests/AppTests.swift index aa1e35a..6db7b00 100644 --- a/Tests/AppTests/AppTests.swift +++ b/Tests/AppTests/AppTests.swift @@ -1,29 +1,29 @@ -@testable import App -import XCTVapor -import Testing - -@Suite("App Tests") -struct AppTests { - private func withApp(_ test: (Application) async throws -> ()) async throws { - let app = try await Application.make(.testing) - do { - try await configure(app) - try await test(app) - } - catch { - try await app.asyncShutdown() - throw error - } - try await app.asyncShutdown() - } - - @Test("Test Hello World Route") - func helloWorld() async throws { - try await withApp { app in - try await app.test(.GET, "hello", afterResponse: { res async in - #expect(res.status == .ok) - #expect(res.body.string == "Hello, world!") - }) - } - } -} +@testable import App +import XCTVapor +import Testing + +@Suite("App Tests") +struct AppTests { + private func withApp(_ test: (Application) async throws -> ()) async throws { + let app = try await Application.make(.testing) + do { + try await configure(app) + try await test(app) + } + catch { + try await app.asyncShutdown() + throw error + } + try await app.asyncShutdown() + } + + @Test("Test Hello World Route") + func helloWorld() async throws { + try await withApp { app in + try await app.test(.GET, "hello", afterResponse: { res async in + #expect(res.status == .ok) + #expect(res.body.string == "Hello, world!") + }) + } + } +}