This commit is contained in:
Max Goedjen
2022-02-16 22:02:57 -08:00
parent ba1c4c1563
commit 93b51f9e9b
9 changed files with 52 additions and 100 deletions

View File

@@ -1,43 +0,0 @@
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
let delegate = ServiceDelegate(exportedObject: Updater())
let listener = NSXPCListener(machServiceName: Bundle.main.bundleIdentifier!)
func applicationDidFinishLaunching(_ aNotification: Notification) {
listener.delegate = delegate
listener.resume()
Task {
try! await delegate.exported.authorize()
}
}
func applicationWillTerminate(_ aNotification: Notification) {
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return false
}
}
class ServiceDelegate: NSObject, NSXPCListenerDelegate {
let exported: UpdaterProtocol
init(exportedObject: UpdaterProtocol) {
self.exported = exportedObject
}
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
newConnection.exportedInterface = NSXPCInterface(with: UpdaterProtocol.self)
newConnection.exportedObject = exported
newConnection.resume()
return true
}
}

View File

@@ -8,13 +8,18 @@ import Security.AuthorizationTags
class Updater: UpdaterProtocol {
func installUpdate(url: URL) async throws -> String {
// try await authorize()
func installUpdate(url: URL, to destinationURL: URL) async throws -> String {
// let (downloadedURL, _) = try await URLSession.shared.download(from: url)
// let unzipped = try await decompress(url: downloadedURL)
// try await move(url: unzipped, to: destinationURL)
// let config = NSWorkspace.OpenConfiguration()
// config.activates = true
// TODO: clean
_ = try await authorize()
// if let host = NSRunningApplication.runningApplications(withBundleIdentifier: "com.maxgoedjen.Secretive.Host").first(where: { $0.bundleURL?.path.hasPrefix("/Applications") ?? false }) {
// host.terminate()
//
// }
return "OK"
}
@@ -37,43 +42,51 @@ class Updater: UpdaterProtocol {
return appURL
}
func move(url: URL) async throws {
try await authorize()
try await move(url: url)
try await revokeAuthorization()
func move(url: URL, to destinationURL: URL) async throws {
let auth = try await authorize()
try await move(url: url, to: destinationURL)
try await revokeAuthorization(auth)
}
func authorize() async throws {
func authorize() async throws -> AuthorizationRef {
let flags = AuthorizationFlags()
var authorization: AuthorizationRef? = nil
let status = AuthorizationCreate(nil, nil, flags, &authorization)
print(status)
print("Hello")
AuthorizationCreate(nil, nil, flags, &authorization)
let authFlags: AuthorizationFlags = [.interactionAllowed, .extendRights, .preAuthorize]
var result: OSStatus?
kAuthorizationRightExecute.withCString { cString in
var item = AuthorizationItem(name: cString, valueLength: 0, value: nil, flags: 0)
withUnsafeMutablePointer(to: &item) { pointer in
var rights = AuthorizationRights(count: 1, items: pointer)
let out = AuthorizationCopyRights(authorization!, &rights, nil, authFlags, nil)
print(out)
result = AuthorizationCopyRights(authorization!, &rights, nil, authFlags, nil)
}
}
}
func revokeAuthorization() async throws {
guard result == errAuthorizationSuccess, let authorization = authorization else {
throw RightsNotAcquiredError()
}
return authorization
}
func priveledgedMove(url: URL) async throws {
func revokeAuthorization(_ authorization: AuthorizationRef) async throws {
AuthorizationFree(authorization, .destroyRights)
}
func priveledgedMove(url: URL, to destination: URL) async throws {
try FileManager.default.replaceItemAt(destination, withItemAt: url)
}
}
extension Updater {
struct DecompressionError: Error, LocalizedError {
let reason: String
}
struct RightsNotAcquiredError: Error, LocalizedError {
}
}
extension URLSession {

View File

@@ -3,7 +3,6 @@ import Brief
@objc public protocol UpdaterProtocol {
func installUpdate(url: URL) async throws -> String
func authorize() async throws
func installUpdate(url: URL, to: URL) async throws -> String
}

View File

@@ -19,6 +19,8 @@ class ServiceDelegate: NSObject, NSXPCListenerDelegate {
let updater = Updater()
let delegate = ServiceDelegate(exportedObject: Updater())
let listener = NSXPCListener.service()
let listener = NSXPCListener(machServiceName: Bundle.main.bundleIdentifier!)
listener.delegate = delegate
listener.resume()
try "Hello world".data(using: .utf8)?.write(to: URL(fileURLWithPath: "/Users/max/Downloads/\(UUID().uuidString).txt"))
RunLoop.current.run()