-
-
Notifications
You must be signed in to change notification settings - Fork 160
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
[RFC] Keychain-backed settings #536
base: main
Are you sure you want to change the base?
Changes from 1 commit
2a58323
70cfdf8
4602296
a5a3f1c
5cbc4e5
e29dd20
52f3fea
748fc4e
77bf72e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// | ||
// SettingsHelper.swift | ||
// Secretive | ||
// | ||
// Created by Paul Heidekrüger on 27.02.24. | ||
// Copyright © 2024 Max Goedjen. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
class SettingsStore { | ||
static let service = "com.maxgoedjen.Secretive" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: move this into an |
||
} | ||
|
||
extension SettingsStore { | ||
static func set(key: String, value: String) -> Bool { | ||
paulhdk marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably makes sense to have the core get/set methods her expose |
||
let valueData = value.data(using: String.Encoding.utf8)! | ||
|
||
if let keyVal = get(key: key) { | ||
if keyVal == value { | ||
return true | ||
} | ||
|
||
let updateQuery: [String: Any] = [kSecClass as String: kSecClassGenericPassword, | ||
kSecAttrServer as String: service] | ||
let attributes: [String: Any] = [kSecAttrAccount as String: key, | ||
kSecValueData as String: valueData] | ||
// FIXME: Make this non-blocking as described here: https://developer.apple.com/documentation/security/1393617-secitemupdate | ||
let status = SecItemUpdate(updateQuery as CFDictionary, attributes as CFDictionary) | ||
guard status == errSecSuccess else { | ||
print("Couldn't update item in keychain. " + status.description) | ||
return false | ||
} | ||
} else { | ||
let addquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword, | ||
kSecAttrAccount as String: key, | ||
kSecAttrServer as String: service, | ||
kSecValueData as String: valueData] | ||
// FIXME: Make this non-blocking as described here: https://developer.apple.com/documentation/security/1401659-secitemadd | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only way you'll really get around this is by caching these values. I'm not super worried about this in this context, assuming you're not seeing any noticeable chug from it. |
||
let status = SecItemAdd(addquery as CFDictionary, nil) | ||
guard status == errSecSuccess else { | ||
print("Couldn't add item to keychain. " + status.description) | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
static func get(key: String) -> String? { | ||
let getquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword, | ||
kSecAttrAccount as String: key, | ||
kSecAttrServer as String: service, | ||
kSecMatchLimit as String: kSecMatchLimitOne, | ||
kSecReturnData as String: true] | ||
var item: CFTypeRef? | ||
let status = SecItemCopyMatching(getquery as CFDictionary, &item) | ||
|
||
return status == errSecSuccess ? String(decoding: item as! Data, as: UTF8.self) : nil | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.