Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Environmental Utility #272

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
e4d43ad
Implementing Environmental Utility
RockfordWei Nov 7, 2018
f77dd77
Merge remote-tracking branch 'upstream/master'
RockfordWei Jul 21, 2020
d6d581d
implementing json date for iso8601 format.
RockfordWei Jul 21, 2020
52d396f
adding test data for json date coder
RockfordWei Jul 21, 2020
3fda2a6
improving decoder preformance for date type
RockfordWei Jul 21, 2020
85bc2e8
Merge branch 'PerfectlySoft:master' into master
RockfordWei Jul 24, 2021
4c2aabe
remastered - Swift 5.6 with i386 + arm64
RockfordWei Jun 23, 2022
8b6ed74
version sync.
RockfordWei Jun 23, 2022
7a32069
fix project name issue
RockfordWei Jun 23, 2022
6e97a95
removing test confidentials
RockfordWei Jun 23, 2022
1006008
cleaning up
RockfordWei Jun 23, 2022
259947d
rename the library
RockfordWei Jun 23, 2022
7940981
adding runnable
RockfordWei Jun 23, 2022
0c266a7
Merge branch 'master' of https://github.com/RockfordWei/Perfect
RockfordWei Jun 23, 2022
fdd26cc
adding demo
RockfordWei Jun 23, 2022
7397f49
adding git for docker container.
RockfordWei Jun 23, 2022
91eec70
auth.
RockfordWei Jun 23, 2022
bd8d3d1
linting.
RockfordWei Jun 24, 2022
526a419
adding build status
RockfordWei Jun 24, 2022
7f1dfc0
Update README.md
RockfordWei Jun 24, 2022
39f0242
cleaning up readme
RockfordWei Jun 24, 2022
fe5479e
Update README.md
RockfordWei Jun 24, 2022
d29d752
cleaning up
RockfordWei Jun 24, 2022
cd8c49c
fixing the hidden interfaces issue.
RockfordWei Jun 25, 2022
159d209
adding json support for http request.
RockfordWei Jun 26, 2022
70a77ff
adding quick access to the text plain.
RockfordWei Jun 27, 2022
a03a65f
Nonce.
RockfordWei Jun 27, 2022
8d5d8e8
improving the randomness for nonce.
RockfordWei Jun 27, 2022
252a222
applying swift 5.4
RockfordWei Jun 28, 2022
972a7a5
tested on macOS.
RockfordWei Jun 28, 2022
a8a57e7
Merge pull request #1 from RockfordWei/dev-swift-5-3
RockfordWei Jun 28, 2022
4237c07
adding the web socket
RockfordWei Jun 30, 2022
22e5df9
improving the template server
RockfordWei Jul 4, 2022
3d20052
dev snapshot
RockfordWei Jul 4, 2022
e12fd3a
account registration.
RockfordWei Jul 4, 2022
0d7b34a
sign in.
RockfordWei Jul 4, 2022
8261bb4
cleaning up
RockfordWei Jul 4, 2022
0099e9e
introducing one-time code
RockfordWei Jul 18, 2022
f7f186e
improving transient code with better error suggestion.
RockfordWei Jul 19, 2022
2baed19
exposing OneTimeRecord attributes for public access
RockfordWei Jul 29, 2022
e1d9ecd
implementing `httpRequest.setBody(Error, jsonLike)`
RockfordWei Jul 30, 2022
1b4ddb5
improving post json body header verification.
RockfordWei Aug 12, 2022
4d578a4
clear all warnings.
RockyCognizant Apr 25, 2023
e93a4a2
Merge pull request #2 from RockyCognizant/master
RockfordWei Apr 25, 2023
a33126b
Linux 5.8
RockfordWei Apr 27, 2023
d0dfb66
suppressing C warnings.
RockfordWei May 29, 2023
7726549
Update Transient.swift to allow configurable one time code settings
RockfordWei Aug 15, 2023
7b82b4a
adding extensions to net tcp
RockfordWei Aug 21, 2023
224e039
fixing the socket issue
RockfordWei Aug 21, 2023
abfc248
Merge pull request #3 from RockfordWei/dev-async
RockfordWei Aug 21, 2023
f719093
gm
RockyCognizant Aug 23, 2023
9f55811
Merge pull request #4 from RockyCognizant/master
RockfordWei Aug 23, 2023
70935e5
cleaning up
RockfordWei Aug 23, 2023
8af193f
fixing critical warnings
RockfordWei Feb 3, 2024
65439bb
Update README.md to Swift 5.9 / Ventura / Ubuntu 22.04 LTS
RockfordWei Feb 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion .gitignore
Expand Up @@ -17,6 +17,7 @@ DerivedData
*.ipa
*.xcuserstate
*.xcscmblueprint
*.resolved

# CocoaPods
#
Expand Down Expand Up @@ -54,5 +55,12 @@ PerfectServer/perfectserverhttp
# SwiftPM
.build/
Packages/
PerfectLib.xcodeproj/
*.xcodeproj/
docs/
.swiftpm/
smtp.test.json

.vscode/
*.json
*.pem
*.sqlite*
32 changes: 32 additions & 0 deletions .swiftlint.yml
@@ -0,0 +1,32 @@
cyclomatic_complexity:
- 64 # warning
- 128 # error
file_length:
- 2048 # warning
- 4096 # error
function_body_length:
- 128 # warning
- 256 # error
line_length:
- 256 # warning
- 512 # error
type_body_length:
- 512 # warning
- 1024 # error
disabled_rules:
- empty_enum_arguments
- function_parameter_count
- identifier_name
- inclusive_language
- large_tuple
- multiple_closures_with_trailing_closure
- nesting
- redundant_optional_initialization
- syntactic_sugar
- unused_optional_binding
- vertical_parameter_alignment
- void_return
excluded:
- .build/
- Sources/PerfectHTTP/Mime*.swift
- Sources/PerfectHTTPServer/HTTP2/HPACK.swift
17 changes: 17 additions & 0 deletions Dockerfile
@@ -0,0 +1,17 @@
FROM ubuntu:20.04
RUN apt-get update -y
RUN apt-get install -y wget
WORKDIR /tmp
ARG arch
COPY ./${arch}.url.txt /tmp/url.txt
RUN rm -rf /tmp/sw*
RUN wget -O /tmp/swift.tgz $(cat /tmp/url.txt)
RUN cd /tmp && tar xf /tmp/swift.tgz && rm -rf /tmp/swift.tgz && mv $(ls|grep swift) /tmp/swift/
RUN cd /tmp/swift/usr/ && tar cf /tmp/sw.tar *
RUN cd /usr && tar xf /tmp/sw.tar
RUN rm -rf /tmp/sw*
RUN apt-get update -y
RUN apt-get install -y build-essential clang git
RUN apt-get install -y libcurl4-openssl-dev uuid-dev
RUN apt-get install -y libsqlite3-dev libncurses-dev
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libxml2-dev
52 changes: 52 additions & 0 deletions Package.resolved
@@ -0,0 +1,52 @@
{
"object": {
"pins": [
{
"package": "COpenSSL",
"repositoryURL": "https://github.com/PerfectlySoft/Perfect-COpenSSL.git",
"state": {
"branch": null,
"revision": "ce3113e159b8c6d8565e5d8db2672b572c81aea9",
"version": "4.0.2"
}
},
{
"package": "PerfectCZlib",
"repositoryURL": "https://github.com/RockfordWei/Perfect-CZlib-src.git",
"state": {
"branch": null,
"revision": "8295883fd760f601a2c8c3236af83c8c35f941c6",
"version": "0.0.6"
}
},
{
"package": "cURL",
"repositoryURL": "https://github.com/PerfectlySoft/Perfect-libcurl.git",
"state": {
"branch": null,
"revision": "b3d7e65ef5c27c0a027cdc621f34835975301bf1",
"version": "2.1.0"
}
},
{
"package": "LinuxBridge",
"repositoryURL": "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git",
"state": {
"branch": null,
"revision": "d6e64c48e6b06b6f1ab7ab9338280447baa8ca5c",
"version": "3.1.0"
}
},
{
"package": "PerfectCSQLite3",
"repositoryURL": "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git",
"state": {
"branch": null,
"revision": "64c2bd87e1fd3a41cdeeba073bab794db7e97e42",
"version": "3.1.1"
}
}
]
},
"version": 1
}
128 changes: 85 additions & 43 deletions Package.swift
@@ -1,50 +1,92 @@
// swift-tools-version:5.1
//
// Package.swift
// PerfectLib
//
// Created by Kyle Jessup on 3/22/16.
// Copyright (C) 2016 PerfectlySoft, Inc.
//
//===----------------------------------------------------------------------===//
//
// This source file is part of the Perfect.org open source project
//
// Copyright (c) 2015 - 2016 PerfectlySoft Inc. and the Perfect project authors
// Licensed under Apache License v2.0
//
// See http://perfect.org/licensing.html for license information
//
//===----------------------------------------------------------------------===//
//
// swift-tools-version: 5.4
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

#if os(Linux)
let package = Package(
name: "PerfectLib",
products: [
.library(name: "PerfectLib", targets: ["PerfectLib"])
],
dependencies: [.package(url: "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git", from: "3.0.0")],
targets: [
.target(name: "PerfectLib", dependencies: ["LinuxBridge"]),
.testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"])
]
)
let pkdep: [Package.Dependency] = [
.package(url: "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git", from: "3.1.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git", from: "3.1.1")
]

let sqlite3dep: [Target.Dependency] = [
.product(name: "PerfectCSQLite3", package: "Perfect-sqlite3-support")
]

let osdep: [Target.Dependency] = sqlite3dep + [.product(name: "LinuxBridge", package: "Perfect-LinuxBridge")]
let sqldep: [Target.Dependency] = sqlite3dep + [.init(stringLiteral: "PerfectCRUD")]
#else
let pkdep: [Package.Dependency] = []
let osdep: [Target.Dependency] = []
let sqldep: [Target.Dependency] = ["PerfectCRUD"]
#endif

let package = Package(
name: "PerfectLib",
platforms: [
.macOS(.v10_15)
],
products: [
.library(name: "PerfectLib", targets: ["PerfectLib"])
],
dependencies: [],
targets: [
.target(name: "PerfectLib", dependencies: []),
.testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"])
]
name: "Perfect",
products: [
.library(name: "PerfectAuth", targets: ["PerfectAuth"]),
.library(name: "PerfectCRUD", targets: ["PerfectCRUD"]),
.library(name: "PerfectCrypto", targets: ["PerfectCrypto"]),
.library(name: "PerfectCURL", targets: ["PerfectCURL"]),
.library(name: "PerfectLib", targets: ["PerfectLib"]),
.library(name: "PerfectHTTP", targets: ["PerfectHTTP"]),
.library(name: "PerfectHTTPServer", targets: ["PerfectHTTPServer"]),
.library(name: "PerfectMustache", targets: ["PerfectMustache"]),
.library(name: "PerfectNet", targets: ["PerfectNet"]),
.library(name: "PerfectSMTP", targets: ["PerfectSMTP"]),
.library(name: "PerfectSQLite", targets: ["PerfectSQLite"]),
.library(name: "PerfectThread", targets: ["PerfectThread"]),
.executable(name: "httpd", targets: ["httpd"])
],
dependencies: pkdep + [
.package(url: "https://github.com/PerfectlySoft/Perfect-libcurl.git", from: "2.0.0"),
.package(url: "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", from: "4.0.2"),
.package(url: "https://github.com/RockfordWei/Perfect-CZlib-src.git", from: "0.0.6")
],
targets: [
.target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]),
.target(name: "PerfectCHTTPParser"),
.target(name: "PerfectLib", dependencies: osdep),
.target(name: "PerfectThread", dependencies: osdep),
.target(name: "PerfectCRUD"),
.target(name: "PerfectCrypto", dependencies: [
.init(stringLiteral: "PerfectLib"),
.init(stringLiteral: "PerfectThread"),
.product(name: "COpenSSL", package: "Perfect-COpenSSL")
]),
.target(name: "PerfectCURL", dependencies: [
.product(name: "cURL", package: "Perfect-libcurl"),
.init(stringLiteral: "PerfectLib"),
.init(stringLiteral: "PerfectThread")
]),
.target(name: "PerfectHTTP", dependencies: ["PerfectLib", "PerfectNet"]),
.target(name: "PerfectHTTPServer", dependencies: [
.init(stringLiteral: "PerfectCHTTPParser"),
.init(stringLiteral: "PerfectCrypto"),
.init(stringLiteral: "PerfectNet"),
.init(stringLiteral: "PerfectHTTP"),
.product(name: "PerfectCZlib", package: "Perfect-CZlib-src")
]),
.target(name: "PerfectMustache", dependencies: ["PerfectLib"]),
.target(name: "PerfectNet", dependencies: ["PerfectCrypto", "PerfectThread"]),
.target(name: "PerfectSMTP", dependencies: ["PerfectCURL", "PerfectCrypto", "PerfectHTTP"]),
.target(name: "PerfectSQLite", dependencies: sqldep),
.testTarget(name: "PerfectAuthTests", dependencies: [
"PerfectAuth", "PerfectCRUD", "PerfectCrypto", "PerfectLib", "PerfectSQLite"
]),
.testTarget(name: "PerfectCryptoTests", dependencies: ["PerfectCrypto"]),
.testTarget(name: "PerfectCURLTests", dependencies: ["PerfectCURL"]),
.testTarget(name: "PerfectHTTPTests", dependencies: ["PerfectHTTP"]),
.testTarget(name: "PerfectHTTPServerTests", dependencies: ["PerfectHTTPServer"]),
.testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"]),
.testTarget(name: "PerfectMustacheTests", dependencies: ["PerfectMustache"]),
.testTarget(name: "PerfectNetTests", dependencies: ["PerfectNet"]),
.testTarget(name: "PerfectSMTPTests", dependencies: ["PerfectSMTP"]),
.testTarget(name: "PerfectSQLiteTests", dependencies: ["PerfectSQLite"]),
.testTarget(name: "PerfectThreadTests", dependencies: ["PerfectThread"]),
.executableTarget(name: "httpd", dependencies: [
"PerfectAuth", "PerfectCrypto", "PerfectLib", "PerfectHTTPServer", "PerfectHTTP",
"PerfectMustache", "PerfectSMTP", "PerfectSQLite"
])
]
)
#endif
19 changes: 15 additions & 4 deletions README.md
Expand Up @@ -7,7 +7,7 @@

<p align="center">
<a href="https://developer.apple.com/swift/" target="_blank">
<img src="https://img.shields.io/badge/Swift-5.2-orange.svg?style=flat" alt="Swift 5.2">
<img src="https://img.shields.io/badge/Swift-5.6-orange.svg?style=flat" alt="Swift 5.6">
</a>
<a href="https://developer.apple.com/swift/" target="_blank">
<img src="https://img.shields.io/badge/Platforms-OS%20X%20%7C%20Linux%20-lightgray.svg?style=flat" alt="Platforms macOS | Linux">
Expand All @@ -17,6 +17,19 @@
</a>
</p>

**OS**|**Version**|**Chip**|**Status**
--|-------|----|------
Ventura|macOS 13.6|Apple Silicon M2|<img src="https://img.shields.io/badge/build-passing-brightgreen" alt="Ventura Apple silicon">
Ubuntu|22.04 LTS|i386|<img src="https://img.shields.io/badge/build-passing-brightgreen" alt="Ubuntu 22.04 LTS i386">
Ubuntu|22.04 LTS|arm64|<img src="https://img.shields.io/badge/build-passing-brightgreen" alt="Ubuntu 22.04 LTS arm64">
**Package**|**Status**|**Package**|**Status**
PerfectLib|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectLib">|PerfectThread|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectThread">
PerfectAuth|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectAuth">|PerfectCRUD|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectCRUD">
PerfectCrypto|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectCrypto">|PerfectCURL|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectCURL">
PerfectHTTP|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectHTTP">|PerfectHTTPServer|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectHTTPServer">
PerfectMustache|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectMustache">|PerfectNet|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectNet">
PerfectSMTP|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectSMTP">|PerfectSQLite|<img src="https://img.shields.io/badge/tests-100%25-brightgreen" alt="PerfectSQLite">

## Perfect: Server-Side Swift

Perfect is a complete and powerful toolbox, framework, and application server for Linux, iOS, and macOS (OS X). It provides everything a Swift engineer needs for developing lightweight, maintainable, and scalable apps and other REST services entirely in the Swift programming language for both client-facing and server-side applications.
Expand Down Expand Up @@ -53,7 +66,6 @@ Your Perfect project can be deployed to any Swift compatible Linux server. We pr

Our library continues to grow as members of [the Swift-Perfect development community have shared many samples and examples](https://github.com/PerfectExamples) of their projects in Perfect. Examples include:

- [WebSockets Server](https://github.com/PerfectExamples/PerfectExample-WebSocketsServer)
- [URL Routing](https://github.com/PerfectExamples/PerfectExample-URLRouting)
- [Upload Enumerator](https://github.com/PerfectExamples/PerfectExample-UploadEnumerator)

Expand Down Expand Up @@ -90,15 +102,14 @@ Perfect project is divided into several repositories to make it easy for you to
- [Perfect HTTP Server](https://github.com/PerfectlySoft/Perfect-HTTPServer) - HTTP 1.1 server for Perfect
- [Perfect Mustache](https://github.com/PerfectlySoft/Perfect-Mustache) - Mustache template support for Perfect
- [Perfect CURL](https://github.com/PerfectlySoft/Perfect-CURL) - cURL support for Perfect
- [Perfect WebSockets](https://github.com/PerfectlySoft/Perfect-WebSockets) - WebSockets support for Perfect
- [Perfect Zip](https://github.com/PerfectlySoft/Perfect-Zip) - provides simple zip and unzip functionality
- [Perfect Notifications](https://github.com/PerfectlySoft/Perfect-Notifications) - provides support for Apple Push Notification Service (APNS).

## More about Perfect

Perfect operates using either a standalone [HTTP server](https://github.com/PerfectlySoft/Perfect-HTTP), [HTTPS server](https://github.com/PerfectlySoft/Perfect-HTTPServer), or through [FastCGI server](https://github.com/PerfectlySoft/Perfect-FastCGI). It provides a system for loading your Swift-based modules at startup, for interfacing those modules with its request/response objects, or to the built-in [Mustache template processing system](https://github.com/PerfectlySoft/Perfect-Mustache).

Perfect is built on a completely asynchronous, high-performance networking engine to provide a scalable option for internet services. It supports Secure Sockets Layer (SSL) encryption, and it features a suite of tools commonly required by internet servers such as [WebSockets](https://github.com/PerfectlySoft/Perfect-WebSockets) and [iOS push notifications](https://github.com/PerfectlySoft/Perfect-Notifications), but you are not limited to those options.
Perfect is built on a completely asynchronous, high-performance networking engine to provide a scalable option for internet services. It supports Secure Sockets Layer (SSL) encryption, and it features a suite of tools commonly required by internet servers such as [iOS push notifications](https://github.com/PerfectlySoft/Perfect-Notifications), but you are not limited to those options.

Feel free to use your favourite JSON or templating systems, etc.

Expand Down
47 changes: 47 additions & 0 deletions Sources/PerfectAuth/Nonce.swift
@@ -0,0 +1,47 @@
//
// Nonce.swift
//
//
// Created by Rockford Wei on 2022-06-27.
//

import Foundation
import PerfectCrypto

/// Nonce is a special server allocated JWT which can be typically used to check if a post is valid.
/// For example, any post method should include a valid nonce before action, so if not, the server can just simply ignore it.
public struct Nonce {
fileprivate struct Payload: Codable {
let host: UUID
let timestamp: TimeInterval
init(host h: UUID, timestamp t: TimeInterval = Date().timeIntervalSince1970) {
host = h; timestamp = t
}
}

fileprivate static let algo = JWT.Alg.hs256
fileprivate static let host = UUID()

/// allocate a nonce string
public static func allocate(authorityPrivateKey: PEMKey) throws -> String {
let payload = Payload(host: host)
return try JWTCreator(payload: payload).sign(alg: algo, key: authorityPrivateKey)
}

/// check if this nonce is valid
public static func validate(nonce: String, seconds: Int = 900, authorityPublicKey: PEMKey) throws {
// swiftlint:disable type_name
typealias exception = AuthenticationTokenClaim.Exception
guard let jwt = JWTVerifier(nonce) else {
throw exception.invalidJsonWebToken
}
try jwt.verify(algo: algo, key: authorityPublicKey)
let payload = try jwt.decode(as: Payload.self)
guard payload.host == host else {
throw exception.invalidHostKey
}
guard payload.timestamp + TimeInterval(seconds) > Date().timeIntervalSince1970 else {
throw exception.expired
}
}
}