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

Not able to downgrade the LocksmithAccessibleOption from "unlock" to "afterFirstUnlock" #190

Open
ghost opened this issue Feb 7, 2018 · 4 comments

Comments

@ghost
Copy link

ghost commented Feb 7, 2018

In earlier version of my app the LocksmithAccessibleOption was default. Now I want to change it to "afterFirstUnlock". for that I added following code in my protocol
var accessible: LocksmithAccessibleOption? {return .afterFirstUnlock}

But after using this I'm not able to either delete or access the keychain item at all.
Help me here please.

@rain-bason
Copy link

I encounter this also. What I notice is that the keychain that was stored using the "unlock" accessible option can't be access or delete when you change to "afterFirstUnlock"

What I did is first check if data already exists using the "afterFirstUnlock" then if not I'll pull back by checking using the "unlock" accessible options. If the data is stored in the "unlock" accessible options I'll copy it over to "afterFirstUnlock" and delete the old data to avoid redundancy

@ghost
Copy link
Author

ghost commented Feb 9, 2018

"first check if data already exists using the "afterFirstUnlock" then if not I'll pull back by checking using the "unlock" accessible options. If the data is stored in the "unlock" accessible options I'll copy it over to "afterFirstUnlock" and delete the old data to avoid redundancy" -- > How I'm suppose to handle that. I'm using the protocol based approach. I'm attaching my code and please let me know how I can handle that:

private let UsernameKey = "com.xxxxx.usernameKey"
private let KeyKey = "com.xxxxx.keyKey"
private let Service = "xxxxx"
private let AuthAccount = "xxxxxx-Authorization"

struct Autorization {

let username: String
let key: String

private struct Access: ReadableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
    //var accessible: LocksmithAccessibleOption? {return .afterFirstUnlock}
    var service: String { return Service }
    var account: String { return AuthAccount }
}

}

extension Autorization {

static func readCurrentAuthFromKeychain() -> Autorization? {
    let access = Access()
    let result = access.readFromSecureStore()
    guard let data = result?.data, let username = data[UsernameKey] as? String, let key = data[KeyKey] as? String else { return nil }
    return Autorization(username: username, key: key)
}

static func deleteCurrentUserFromKeychain() throws {
    let access = Access()
    try access.deleteFromSecureStore()
}

}

extension Autorization: CreateableSecureStorable {
var data: [String : Any] {
return [
UsernameKey: username as AnyObject,
KeyKey: key as AnyObject
]
}

}

extension Autorization: GenericPasswordSecureStorable {
//var accessible: LocksmithAccessibleOption? {return .afterFirstUnlock}
var service: String { return Service }
var account: String { return AuthAccount }
}

@rain-bason
Copy link

I'm not sure how can I change your code, but here is part of my code:

In a helper file:

private let accessible = LocksmithAccessibleOption.afterFirstUnlock
private func loadData(forUsername username: String) -> [String: Any]? {
    // case1: try if we can get the value when using "accessibleOption"
    // case2: try using the default method, if we can find value 
    // case3: we didn't have saved data for this username
    if let dataTemp = Locksmith.loadDataForUserAccount(userAccount: username, accessibleOption: accessible) {
        return dataTemp
    } else if let dataTemp = Locksmith.loadDataForUserAccount(userAccount: username) {
        // yup we have values with the old "accessibleOption", get it and assign to dataTemp
        try! Locksmith.deleteDataForUserAccount(userAccount: username) // remove it so we don't have redundant values for this key
        try! Locksmith.updateData(data: dataTemp, forUserAccount: username, accessibleOption: accessible) // assign it to the new "accesibleOption"
        return dataTemp // return the value
    } else {
        return nil
    }
}

then I created an extension:

extension Locksmith {
    fileprivate static func loadDataForUserAccount(userAccount: String,
                                                   inService service: String = LocksmithDefaultService,
                                                   accessibleOption: LocksmithAccessibleOption) -> [String: Any]? {
        struct ReadRequest: GenericPasswordSecureStorable, ReadableSecureStorable {
            let service: String
            let account: String
            var accessible: LocksmithAccessibleOption?
        }
        
        let request = ReadRequest(service: service, account: userAccount, accessible: accessibleOption)
        return request.readFromSecureStore()?.data
    }
    
    fileprivate static func updateData(data: [String: Any],
                                       forUserAccount userAccount: String,
                                       inService service: String = LocksmithDefaultService,
                                       accessibleOption: LocksmithAccessibleOption) throws {
        
        struct UpdateRequest: GenericPasswordSecureStorable, CreateableSecureStorable {
            let service: String
            let account: String
            let data: [String: Any]
            var accessible: LocksmithAccessibleOption?
        }
        
        let request = UpdateRequest(service: service, account: userAccount, data: data, accessible: accessibleOption)
        return try request.updateInSecureStore()
    }
}

I'm not sure if this is the ideal way, but it does works the way we need it.

@ghost
Copy link
Author

ghost commented Feb 20, 2018

"else if let dataTemp = Locksmith.loadDataForUserAccount(userAccount: username)" statement returns nil even if there is data in the keychain for the same account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant