Skip to content

Commit

Permalink
fixed xcreds breakage due to refactoring for xcreds login window
Browse files Browse the repository at this point in the history
  • Loading branch information
twocanoes committed Jul 6, 2022
1 parent e755e30 commit f417788
Show file tree
Hide file tree
Showing 20 changed files with 242 additions and 156 deletions.
1 change: 1 addition & 0 deletions XCreds/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {


// ManagedPreferences.shared.preference(forKey: .clientID)
mainController = MainController.init()
mainController?.run()
Expand Down
33 changes: 33 additions & 0 deletions XCreds/Logger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Logger.swift
// XCreds
//
// Created by Timothy Perfitt on 7/5/22.
//

import Foundation
func TCSLogWithMark(_ message: String = "",
file: String = #file, line: Int = #line, function: String = #function ) {

let date = Date()

let comp = file.components(separatedBy: "/")
if let lastPart = comp.last{
TCSLog("\(date) FILE:\(lastPart) LINE:\(line) FUNCTION:\(function) message:\(message)")

}

}

func Mark(
file: String = #file, line: Int = #line, function: String = #function ) {

let date = Date()

let comp = file.components(separatedBy: "/")
if let lastPart = comp.last{
TCSLog("\(date) FILE:\(lastPart) LINE:\(line) FUNCTION:\(function)")

}

}
84 changes: 48 additions & 36 deletions XCreds/MainController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class MainController: NSObject {
// make sure we have the local password, else prompt. we don't need to save it
// just make sure we prompt if not in the keychain. if the user cancels, then it will
// prompt when using OAuth.
// don't need to save it. just need to prompt and it gets saved
// in the keychain
let _ = localPassword()
NotificationCenter.default.addObserver(forName: Notification.Name("TCSTokensUpdated"), object: nil, queue: nil) { notification in
//now we set the password.
Expand All @@ -38,59 +40,69 @@ class MainController: NSObject {
if tokens.refreshToken.count>0 {
mainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
}
var updatePassword = true
if UserDefaults.standard.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
NSApp.activate(ignoringOtherApps: true)

while true {
let response = NSApp.runModal(for: verifyOIDPassword.window!)
if response == .cancel {

let alert = NSAlert()
alert.addButton(withTitle: "Skip Updating Password")
alert.addButton(withTitle: "Cancel")
alert.messageText="Are you sure you want to skip updating the local password and keychain? You local password and keychain will be out of sync with your cloud password. "
let resp = alert.runModal()
if resp == .alertFirstButtonReturn {
NSApp.stopModal(withCode: .cancel)
verifyOIDPassword.window?.close()
updatePassword=false
break
let localPassword = self.localPassword()
if (localPassword != tokens.password){
var updatePassword = true
if UserDefaults.standard.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
NSApp.activate(ignoringOtherApps: true)

while true {
let response = NSApp.runModal(for: verifyOIDPassword.window!)
if response == .cancel {

let alert = NSAlert()
alert.addButton(withTitle: "Skip Updating Password")
alert.addButton(withTitle: "Cancel")
alert.messageText="Are you sure you want to skip updating the local password and keychain? You local password and keychain will be out of sync with your cloud password. "
let resp = alert.runModal()
if resp == .alertFirstButtonReturn {
NSApp.stopModal(withCode: .cancel)
verifyOIDPassword.window?.close()
updatePassword=false
break

}
}
let verifyCloudPassword = verifyOIDPassword.password
if verifyCloudPassword == tokens.password {

updatePassword=true

verifyOIDPassword.window?.close()
break;
}
}
let verifyCloudPassword = verifyOIDPassword.password
if verifyCloudPassword == cloudPassword {
try? PasswordUtils.changeLocalUserAndKeychainPassword(localPassword, newPassword1: cloudPassword, newPassword2: cloudPassword)
let err = keychainUtil.updatePassword("local password", pass: cloudPassword)
updatePassword=true
if err == false {
//TODO: Log Error
else {
verifyOIDPassword.window?.shake(self)
}
verifyOIDPassword.window?.close()
break;

}
else {
verifyOIDPassword.window?.shake(self)
}
if updatePassword {
guard let localPassword = self.localPassword() else {
TCSLogWithMark("error getting local password")
return
}
try? PasswordUtils.changeLocalUserAndKeychainPassword(localPassword, newPassword1: tokens.password, newPassword2: tokens.password)


}
}
//check for updatepassword and see if we need to pass with tokens to update passwords
//add tokens xyzzy
if TokenManager.shared.saveTokensToKeychain(tokens: tokens) == false {
TCSLogWithMark("error saving tokens to keychain")
}
ScheduleManager.shared.startCredentialCheck()

}
}

ScheduleManager.shared.startCredentialCheck()
}

//get local password either from keychain or prompt. If prompt, then it will save in keychain for next time. if keychain, get keychain and test to make sure it is valid.
func localPassword() -> String? {
let keychainUtil = KeychainUtil()

let password = try? keychainUtil.findPassword("local password")
let password = try? keychainUtil.findPassword(PrefKeys.password.rawValue)

if let password = password {
if PasswordUtils.verifyCurrentUserPassword(password: password) == true {
Expand All @@ -114,7 +126,7 @@ class MainController: NSObject {
let isPasswordValid = PasswordUtils.verifyCurrentUserPassword(password:localPassword )
if isPasswordValid==true {
passwordWindowController.window?.close()
let err = keychainUtil.updatePassword("local password", pass: localPassword)
let err = keychainUtil.updatePassword(PrefKeys.password.rawValue, pass: localPassword)
if err == false {
return nil
}
Expand Down
20 changes: 10 additions & 10 deletions XCreds/PasswordUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ class PasswordUtils: NSObject {
/// `ODNode` to DSLocal for queries and account manipulation.
public class var localNode: ODNode? {
do {
TCSLog("Finding the DSLocal node")
TCSLogWithMark("Finding the DSLocal node")
return try ODNode.init(session: ODSession.default(), type: ODNodeType(kODNodeTypeLocalNodes))
} catch {
TCSLog("ODError creating local node.")
TCSLogWithMark("ODError creating local node.")
return nil
}
}
Expand Down Expand Up @@ -192,7 +192,7 @@ class PasswordUtils: NSObject {
let castError = error as NSError
switch castError.code {
case Int(kODErrorCredentialsInvalid.rawValue):
TCSLog("Tested password for user account: %{public}@ is not valid.")
TCSLogWithMark("Tested password for user account: %{public}@ is not valid.")
return false
default:
throw error
Expand All @@ -208,7 +208,7 @@ class PasswordUtils: NSObject {
/// - Throws: Either an `ODFrameworkErrors` or a `DSQueryableErrors` if there is an error or the user is not local.
public class func getLocalRecord(_ shortName: String) throws -> ODRecord {
do {
TCSLog("Building OD query for name \(shortName)")
TCSLogWithMark("Building OD query for name \(shortName)")
let query = try ODQuery.init(node: localNode,
forRecordTypes: kODRecordTypeUsers,
attribute: kODAttributeTypeRecordName,
Expand All @@ -219,17 +219,17 @@ class PasswordUtils: NSObject {
let records = try query.resultsAllowingPartial(false) as! [ODRecord]

if records.count > 1 {
TCSLog("More than one local user found for name.")
TCSLogWithMark("More than one local user found for name.")
throw DSQueryableErrors.multipleUsersFound
}
guard let record = records.first else {
TCSLog("No local user found. Passing on demobilizing allow login.")
TCSLogWithMark("No local user found. Passing on demobilizing allow login.")
throw DSQueryableErrors.notLocalUser
}
TCSLog("Found local user: \(record)")
TCSLogWithMark("Found local user: \(record)")
return record
} catch {
TCSLog("ODError while trying to check for local user: %{public}@")
TCSLogWithMark("ODError while trying to check for local user: %{public}@")
throw error
}
}
Expand All @@ -249,7 +249,7 @@ class PasswordUtils: NSObject {
maximumResults: 0)
return try query.resultsAllowingPartial(false) as! [ODRecord]
} catch {
TCSLog("ODError while finding local users.")
TCSLogWithMark("ODError while finding local users.")
throw error
}
}
Expand All @@ -269,7 +269,7 @@ class PasswordUtils: NSObject {
}
return nonSystem
} catch {
TCSLog("ODError while finding local users.")
TCSLogWithMark("ODError while finding local users.")
throw error
}
}
Expand Down
2 changes: 1 addition & 1 deletion XCreds/PrefKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

enum PrefKeys: String {
case clientID, clientSecret, discoveryURL, redirectURI, scopes, accessToken, idToken, refreshToken, tokenEndpoint, expirationDate, invalidToken, refreshRateHours, showDebug, verifyPassword, shouldShowQuitMenu, shouldShowPreferencesOnStart, shouldSetGoogleAccessTypeToOffline, passwordChangeURL, shouldShowAboutMenu
case clientID, clientSecret, password="local password",discoveryURL, redirectURI, scopes, accessToken, idToken, refreshToken, tokenEndpoint, expirationDate, invalidToken, refreshRateHours, showDebug, verifyPassword, shouldShowQuitMenu, shouldShowPreferencesOnStart, shouldSetGoogleAccessTypeToOffline, passwordChangeURL, shouldShowAboutMenu
}
71 changes: 35 additions & 36 deletions XCreds/TokenManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,38 @@ class TokenManager {
let defaults = UserDefaults.standard
var timer: Timer?

// func saveTokensToKeychain(tokens:Tokens) -> Bool {
// let keychainUtil = KeychainUtil()
//
// if tokens.accessToken.count>0{
// let _ = keychainUtil.updatePassword(PrefKeys.accessToken.rawValue, pass: tokens.accessToken)
// }
//
// if tokens.idToken.count>0{
// let _ = keychainUtil.updatePassword(PrefKeys.idToken.rawValue, pass: tokens.idToken)
// }
//
// if tokens.refreshToken.count>0 {
// let _ = keychainUtil.updatePassword(PrefKeys.refreshToken.rawValue, pass: tokens.refreshToken)
//
//
// }
// let cloudPassword = tokens.password
//// if cloudPassword.count>0 {
//// let localPassword = self.localPassword()
////
//// if let localPassword = localPassword {
////
////// try? PasswordUtils.changeLocalUserAndKeychainPassword(localPassword, newPassword1: cloudPassword, newPassword2: cloudPassword)
////// let err = keychainUtil.updatePassword("local password", pass: cloudPassword)
////// if err == false {
////// //TODO: Log Error
////// }
////
////
////
//// }
////
//// }
// }
func saveTokensToKeychain(tokens:Tokens) -> Bool {
let keychainUtil = KeychainUtil()

if tokens.accessToken.count>0{
if keychainUtil.updatePassword(PrefKeys.accessToken.rawValue, pass: tokens.accessToken) == false {
return false
}
}

if tokens.idToken.count>0{
if keychainUtil.updatePassword(PrefKeys.idToken.rawValue, pass: tokens.idToken) == false {
return false
}
}

if tokens.refreshToken.count>0 {
if keychainUtil.updatePassword(PrefKeys.refreshToken.rawValue, pass: tokens.refreshToken) == false {
return false
}



}
let cloudPassword = tokens.password

if cloudPassword.count>0 {
if keychainUtil.updatePassword(PrefKeys.password.rawValue, pass: tokens.refreshToken) == false {
return false
}
}
return true
}
func getNewAccessToken(completion:@escaping (_ isSuccessful:Bool,_ hadConnectionError:Bool)->Void) -> Void {

guard let url = URL(string: defaults.string(forKey: PrefKeys.tokenEndpoint.rawValue) ?? "") else {
Expand Down Expand Up @@ -117,7 +115,7 @@ class TokenManager {

}
else {
TCSLog("got status code of \(response.statusCode)")
TCSLogWithMark("got status code of \(response.statusCode)")
completion(false,false)

}
Expand All @@ -127,9 +125,10 @@ class TokenManager {
task.resume()
}
else {
TCSLog("clientID or refreshToken blank. clientid: \(clientID ?? "empty") refreshtoken:\(refreshToken ?? "empty")")
TCSLogWithMark("clientID or refreshToken blank. clientid: \(clientID ?? "empty") refreshtoken:\(refreshToken ?? "empty")")
completion(false,false)

}
}
}

0 comments on commit f417788

Please sign in to comment.