Compare commits

...

3 Commits

Author SHA1 Message Date
Christoph Hagen
ac22fcd4eb Remove key error enum 2023-12-06 09:53:24 +01:00
Christoph Hagen
b2b3c74586 Move to new Vapor main 2023-12-06 09:49:26 +01:00
Christoph Hagen
eb10ae6626 Update LICENSE 2023-12-06 09:48:52 +01:00
6 changed files with 53 additions and 64 deletions

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) <year> <copyright holders> Copyright (c) 2023 Christoph Hagen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -13,25 +13,14 @@ let package = Package(
.package(url: "https://github.com/christophhagen/ClairvoyantBinaryCodable", from: "0.3.1"), .package(url: "https://github.com/christophhagen/ClairvoyantBinaryCodable", from: "0.3.1"),
], ],
targets: [ targets: [
.target( .executableTarget(
name: "App", name: "App",
dependencies: [ dependencies: [
.product(name: "Vapor", package: "vapor"), .product(name: "Vapor", package: "vapor"),
.product(name: "Clairvoyant", package: "Clairvoyant"), .product(name: "Clairvoyant", package: "Clairvoyant"),
.product(name: "ClairvoyantVapor", package: "ClairvoyantVapor"), .product(name: "ClairvoyantVapor", package: "ClairvoyantVapor"),
.product(name: "ClairvoyantBinaryCodable", package: "ClairvoyantBinaryCodable"), .product(name: "ClairvoyantBinaryCodable", package: "ClairvoyantBinaryCodable"),
],
swiftSettings: [
// Enable better optimizations when building in Release configuration. Despite the use of
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
// builds. See <https://github.com/swift-server/guides/blob/main/docs/building.md#building-for-production> for details.
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
] ]
), )
.executableTarget(name: "Run", dependencies: [.target(name: "App")]),
.testTarget(name: "AppTests", dependencies: [
.target(name: "App"),
.product(name: "XCTVapor", package: "vapor"),
])
] ]
) )

View File

@ -17,23 +17,8 @@ private let df: DateFormatter = {
return df return df
}() }()
enum ServerError: Error {
case invalidAuthenticationFileContent
case invalidAuthenticationToken
}
private func updateStatus(_ newStatus: ServerStatus) {
asyncScheduler.schedule {
do {
try await status.update(newStatus)
} catch {
print("Failed to update server status: \(error)")
}
}
}
// configures your application // configures your application
public func configure(_ app: Application) throws { public func configure(_ app: Application) async throws {
let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory) let storageFolder = URL(fileURLWithPath: app.directory.resourcesDirectory)
let configUrl = storageFolder.appendingPathComponent("config.json") let configUrl = storageFolder.appendingPathComponent("config.json")
@ -45,7 +30,7 @@ public func configure(_ app: Application) throws {
MetricObserver.standard = monitor MetricObserver.standard = monitor
status = Metric<ServerStatus>("sesame.status") status = Metric<ServerStatus>("sesame.status")
updateStatus(.initializing) try await status.update(.initializing)
app.http.server.configuration.port = config.port app.http.server.configuration.port = config.port
@ -61,12 +46,10 @@ public func configure(_ app: Application) throws {
provider.registerRoutes(app) provider.registerRoutes(app)
monitor.saveCurrentListOfMetricsToLogFolder() monitor.saveCurrentListOfMetricsToLogFolder()
updateStatus(.nominal) try await status.update(.nominal)
// Update the metric of the device status to ensure that it is accurate // Update the metric of the device status to ensure that it is accurate
asyncScheduler.schedule {
await deviceManager.updateDeviceConnectionMetric() await deviceManager.updateDeviceConnectionMetric()
}
log("[\(df.string(from: Date()))] Server started") log("[\(df.string(from: Date()))] Server started")
} }
@ -91,15 +74,15 @@ private func loadKeys(at url: URL) throws -> (deviceKey: Data, remoteKey: Data)
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.map { .map {
guard let key = Data(fromHexEncodedString: $0) else { guard let key = Data(fromHexEncodedString: $0) else {
throw ServerError.invalidAuthenticationToken fatalError("Invalid key data: Failed to convert hex to binary.")
} }
guard key.count == SHA256.byteCount else { guard key.count == SHA256.byteCount else {
throw ServerError.invalidAuthenticationToken fatalError("Invalid key data: Length should be \(SHA256.byteCount), not \(key.count)")
} }
return key return key
} }
guard authContent.count == 2 else { guard authContent.count == 2 else {
throw ServerError.invalidAuthenticationFileContent fatalError("Invalid keys: Expected 2, found \(authContent.count)")
} }
return (deviceKey: authContent[0], remoteKey: authContent[1]) return (deviceKey: authContent[0], remoteKey: authContent[1])
} }

View File

@ -0,0 +1,43 @@
import Vapor
import Dispatch
import Logging
/// This extension is temporary and can be removed once Vapor gets this support.
private extension Vapor.Application {
static let baseExecutionQueue = DispatchQueue(label: "vapor.codes.entrypoint")
func runFromAsyncMainEntrypoint() async throws {
try await withCheckedThrowingContinuation { continuation in
Vapor.Application.baseExecutionQueue.async { [self] in
do {
try self.run()
continuation.resume()
} catch {
continuation.resume(throwing: error)
}
}
}
}
}
@main
enum Entrypoint {
static func main() async throws {
var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env)
let app = Application(env)
defer {
shutdown()
app.shutdown()
}
do {
try await configure(app)
} catch {
app.logger.report(error: error)
throw error
}
try await app.runFromAsyncMainEntrypoint()
}
}

View File

@ -1,13 +0,0 @@
import App
import Vapor
var env = Environment.production //.detect()
try LoggingSystem.bootstrap(from: &env)
let app = Application(env)
defer {
shutdown()
app.shutdown()
}
try configure(app)
try app.run()

View File

@ -1,13 +0,0 @@
@testable import App
import XCTVapor
final class AppTests: XCTestCase {
func testEncodingUInt32() {
let input: UInt32 = 123
let data = input.encoded
let output = UInt32(data: data)
XCTAssertEqual(input, output)
}
}