Implement Siri shortcut to sync repository per automation task

This commit is contained in:
Danny Moesch 2020-03-04 20:27:23 +01:00 committed by Mingshen Sun
parent 21b5774cc5
commit b3bde9e0e0
12 changed files with 499 additions and 4 deletions

42
passShortcuts/Info.plist Normal file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsRestrictedWhileLocked</key>
<array/>
<key>IntentsRestrictedWhileProtectedDataUnavailable</key>
<array/>
<key>IntentsSupported</key>
<array>
<string>SyncRepositoryIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.intents-service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).IntentHandler</string>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,20 @@
//
// IntentHandler.swift
// passShortcuts
//
// Created by Danny Moesch on 03.03.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
import Intents
import passKit
class IntentHandler: INExtension {
override func handler(for intent: INIntent) -> Any {
guard intent is SyncRepositoryIntent else {
fatalError("Unhandled intent type \(intent).")
}
return SyncRepositoryIntentHandler()
}
}

View file

@ -0,0 +1,58 @@
//
// SyncRepositoryIntentHandler.swift
// passShortcuts
//
// Created by Danny Moesch on 03.03.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
import Intents
import passKit
public class SyncRepositoryIntentHandler: NSObject, SyncRepositoryIntentHandling {
private let passwordStore = PasswordStore.shared
private let keychain = AppKeychain.shared
private var gitCredential: GitCredential {
switch Defaults.gitAuthenticationMethod {
case .password:
return GitCredential(credential: .http(userName: Defaults.gitUsername))
case .key:
let privateKey: String = keychain.get(for: SshKey.PRIVATE.getKeychainKey()) ?? ""
return GitCredential(credential: .ssh(userName: Defaults.gitUsername, privateKey: privateKey))
}
}
public func handle(intent: SyncRepositoryIntent, completion: @escaping (SyncRepositoryIntentResponse) -> Void) {
guard passwordStore.repositoryExists() else {
completion(SyncRepositoryIntentResponse(code: .noRepository, userActivity: nil))
return
}
guard isPasswordRemembered else {
completion(SyncRepositoryIntentResponse(code: .noPassphrase, userActivity: nil))
return
}
do {
try passwordStore.pullRepository(credential: gitCredential, requestCredentialPassword: { _, _ in nil }, progressBlock: { _, _ in })
} catch {
completion(SyncRepositoryIntentResponse(code: .pullFailed, userActivity: nil))
return
}
if passwordStore.numberOfLocalCommits > 0 {
do {
try passwordStore.pushRepository(credential: gitCredential, requestCredentialPassword: { _, _ in nil }, transferProgressBlock: { _, _, _, _ in })
} catch {
completion(SyncRepositoryIntentResponse(code: .pushFailed, userActivity: nil))
return
}
}
completion(SyncRepositoryIntentResponse(code: .success, userActivity: nil))
}
private var isPasswordRemembered: Bool {
let authenticationMethod = Defaults.gitAuthenticationMethod
return authenticationMethod == .password && keychain.contains(key: Globals.gitPassword)
|| authenticationMethod == .key && keychain.contains(key: Globals.gitSSHPrivateKeyPassphrase)
}
}

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.me.mssun.passforios</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)group.me.mssun.passforios</string>
</array>
</dict>
</plist>