Skip to content

Commit

Permalink
Added a PassKitError and checks for binaries/templates existing
Browse files Browse the repository at this point in the history
  • Loading branch information
grosch committed Jan 22, 2020
1 parent 373cc56 commit 3b850f6
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 18 deletions.
1 change: 0 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-beta"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-beta"),
//.package(url: "https://github.com/vapor/toolbox.git", from: "18.0.0-beta"),
.package(url: "https://github.com/vapor/apns.git", from: "1.0.0-beta"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0")
],
Expand Down
59 changes: 42 additions & 17 deletions Sources/PassKit/PassKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,33 @@ public class PassKitCustom<P, D, R: PassKitRegistration, E: PassKitErrorLog> whe
///
/// - Parameters:
/// - middleware: The `Middleware` which will control authentication for the routes.
/// - Throws: An error of type `PassKitError`
public func registerPushRoutes(middleware: Middleware) throws {
let privateKeyPath = URL(fileURLWithPath: delegate.pemPrivateKey, relativeTo: delegate.sslSigningFilesDirectory).unixPath()
let privateKeyPath = URL(fileURLWithPath: delegate.pemPrivateKey, relativeTo:
delegate.sslSigningFilesDirectory).unixPath()

guard FileManager.default.fileExists(atPath: privateKeyPath) else {
throw PassKitError.pemPrivateKeyMissing
}

let pemPath = URL(fileURLWithPath: delegate.pemCertificate, relativeTo: delegate.sslSigningFilesDirectory).unixPath()


guard FileManager.default.fileExists(atPath: privateKeyPath) else {
throw PassKitError.pemCertificateMissing
}

// PassKit *only* works with the production APNs. You can't pass in .sandbox here.
if app.apns.configuration == nil {
if let pwd = delegate.pemPrivateKeyPassword {
app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) {
$0(pwd.utf8)
do {
if let pwd = delegate.pemPrivateKeyPassword {
app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger) {
$0(pwd.utf8)
}
} else {
app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger)
}
} else {
app.apns.configuration = try .init(privateKeyPath: privateKeyPath, pemPath: pemPath, topic: "", environment: .production, logger: logger)
} catch {
throw PassKitError.nioPrivateKeyReadFailed(error)
}
}

Expand Down Expand Up @@ -437,10 +452,16 @@ public class PassKitCustom<P, D, R: PassKitRegistration, E: PassKitErrorLog> whe
// If the caller's delegate generated a file we don't have to do it.
return
}


let sslBinary = delegate.sslBinary

guard FileManager.default.fileExists(atPath: sslBinary.unixPath()) else {
throw PassKitError.opensslBinaryMissing
}

let proc = Process()
proc.currentDirectoryURL = delegate.sslSigningFilesDirectory
proc.executableURL = delegate.sslBinary
proc.executableURL = sslBinary

proc.arguments = [
"smime", "-binary", "-sign",
Expand All @@ -462,21 +483,21 @@ public class PassKitCustom<P, D, R: PassKitRegistration, E: PassKitErrorLog> whe
}

private func zip(directory: URL, to: URL) throws {
let zipBinary = delegate.zipBinary
guard FileManager.default.fileExists(atPath: zipBinary.unixPath()) else {
throw PassKitError.zipBinaryMissing
}

let proc = Process()
proc.currentDirectoryURL = directory
proc.executableURL = delegate.zipBinary
proc.executableURL = zipBinary

proc.arguments = [ to.unixPath(), "-r", "-q", "." ]

try proc.run()
proc.waitUntilExit()
}

enum PassKitError: Error {
case templateNotDirectory
case failedToZipPass
}

private func generatePassContent(for pass: P, on db: Database) -> EventLoopFuture<Data> {
let tmp = FileManager.default.temporaryDirectory
let root = tmp.appendingPathComponent(UUID().uuidString, isDirectory: true)
Expand All @@ -485,8 +506,12 @@ public class PassKitCustom<P, D, R: PassKitRegistration, E: PassKitErrorLog> whe

return delegate.template(for: pass, db: db)
.flatMap { src in
guard src.hasDirectoryPath else {
return db.eventLoop.makeFailedFuture(PassKitError.templateNotDirectory)
var isDir: ObjCBool = false

guard src.hasDirectoryPath &&
FileManager.default.fileExists(atPath: src.unixPath(), isDirectory: &isDir) &&
isDir.boolValue else {
return db.eventLoop.makeFailedFuture(PassKitError.templateNotDirectory)
}

return self.delegate.encode(pass: pass, db: db, encoder: encoder)
Expand Down
28 changes: 28 additions & 0 deletions Sources/PassKit/PassKitError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// File.swift
//
//
// Created by Scott Grosch on 1/22/20.
//

import Foundation

public enum PassKitError: Error {
/// The template path is not a directory
case templateNotDirectory

/// The `pemCertificate` file is missing.
case pemCertificateMissing

/// The `pemPrivateKey` file is missing.
case pemPrivateKeyMissing

/// Swift NIO failed to read the key.
case nioPrivateKeyReadFailed(Error)

/// The path to the zip binary is incorrect.
case zipBinaryMissing

/// The path to the openssl binary is incorrect
case opensslBinaryMissing
}

0 comments on commit 3b850f6

Please sign in to comment.