Skip to content

Commit

Permalink
added mappings for user info
Browse files Browse the repository at this point in the history
  • Loading branch information
twocanoes committed Nov 9, 2022
1 parent 180c2b9 commit 074ac99
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 112 deletions.
4 changes: 2 additions & 2 deletions Profile Manifest/com.twocanoes.xcreds.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<key>pfm_app_url</key>
<string>https://github.com/twocanoes/xcreds</string>
<key>pfm_description</key>
<string>xcreds OAuth Settings</string>
<string>XCreds OAuth Settings</string>
<key>pfm_documentation_url</key>
<string>https://github.com/twocanoes/xcreds/wiki/AdminGuide</string>
<key>pfm_domain</key>
Expand Down Expand Up @@ -239,7 +239,7 @@ A profile can consist of payloads with different version numbers. For example, c
<key>pfm_default</key>
<string>file:///System/Library/Desktop Pictures/Monterey Graphic.heic</string>
<key>pfm_description</key>
<string>url to an image to show in the background while logging in.</string>
<string>URL to an image to show in the background while logging in.</string>
<key>pfm_documentation_url</key>
<string>https://github.com/twocanoes/xcreds/wiki/AdminGuide#loginwindowbackgroundimageurl</string>
<key>pfm_format</key>
Expand Down
32 changes: 28 additions & 4 deletions Shared/Tokens.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,34 @@
//

import Foundation
struct Tokens {
import OIDCLite
struct Creds {
var password = ""
var accessToken = ""
var idToken = ""
var refreshToken = ""
public var accessToken: String?
public var idToken: String?
public var refreshToken: String?
public var jsonDict: [String:Any]?

init(password:String, tokens:OIDCLiteTokenResponse) {

self.accessToken=tokens.accessToken
self.idToken=tokens.idToken
self.refreshToken=tokens.refreshToken
self.password=password
self.jsonDict=tokens.jsonDict

}
init(accessToken:String?, idToken:String?,refreshToken:String?, password:String?,jsonDict:Dictionary <String,Any>,pass:String) {

self.accessToken=accessToken
self.idToken=idToken
self.refreshToken=refreshToken
self.password=pass
self.jsonDict=jsonDict

}

}



15 changes: 7 additions & 8 deletions XCreds/MainController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class MainController: NSObject {
// in the keychain
let _ = localPassword()
NotificationCenter.default.addObserver(forName: Notification.Name("TCSTokensUpdated"), object: nil, queue: nil) { notification in
//now we set the password.


// //now we set the password.
Mark()
DispatchQueue.main.async {
mainMenu.webView?.window?.close()
Expand All @@ -35,19 +37,16 @@ class MainController: NSObject {
return
}

guard let tokens = tokenInfo["tokens"] as? Tokens else {
guard let tokens = tokenInfo["tokens"] as? Creds else {
let alert = NSAlert()
alert.addButton(withTitle: "OK")
alert.messageText="Invalid tokens or password not determined. Please check the log."
alert.runModal()
return
}
if tokens.refreshToken.count>0 {
if let refreshToken = tokens.refreshToken, refreshToken.count>0 {
Mark()
DispatchQueue.main.async {
mainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
}

mainMenu.statusBarItem.button?.image=NSImage(named: "xcreds menu icon check")
}
let localPassword = self.localPassword()
if (localPassword != tokens.password){
Expand Down Expand Up @@ -97,7 +96,7 @@ class MainController: NSObject {

}
}
if TokenManager.shared.saveTokensToKeychain(tokens: tokens, setACL: true, password:tokens.password ) == false {
if TokenManager.shared.saveTokensToKeychain(creds: tokens, setACL: true, password:tokens.password ) == false {
TCSLogWithMark("error saving tokens to keychain")
}
ScheduleManager.shared.startCredentialCheck()
Expand Down
20 changes: 10 additions & 10 deletions XCreds/TokenManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,44 +69,44 @@ class TokenManager {

}

func saveTokensToKeychain(tokens:Tokens, setACL:Bool=false, password:String?=nil) -> Bool {
func saveTokensToKeychain(creds:Creds, setACL:Bool=false, password:String?=nil) -> Bool {
let keychainUtil = KeychainUtil()

if tokens.accessToken.count>0{
if let accessToken = creds.accessToken, accessToken.count>0{
TCSLogWithMark("Saving Access Token")
if keychainUtil.updatePassword(PrefKeys.accessToken.rawValue, pass: tokens.accessToken,shouldUpdateACL: setACL, keychainPassword:password) == false {
if keychainUtil.updatePassword(PrefKeys.accessToken.rawValue, pass: accessToken,shouldUpdateACL: setACL, keychainPassword:password) == false {
TCSLogWithMark("Error Updating Access Token")

return false
}

}
if tokens.idToken.count>0{
if let idToken = creds.idToken, idToken.count>0{
TCSLogWithMark("Saving idToken Token")
if keychainUtil.updatePassword(PrefKeys.idToken.rawValue, pass: tokens.idToken, shouldUpdateACL: setACL, keychainPassword:password) == false {
if keychainUtil.updatePassword(PrefKeys.idToken.rawValue, pass: idToken, shouldUpdateACL: setACL, keychainPassword:password) == false {
TCSLogWithMark("Error Updating idToken Token")

return false
}
}


if tokens.refreshToken.count>0 {
if let refreshToken = creds.refreshToken, refreshToken.count>0 {
TCSLogWithMark("Saving refresh Token")

if keychainUtil.updatePassword(PrefKeys.refreshToken.rawValue, pass: tokens.refreshToken,shouldUpdateACL: setACL, keychainPassword:password) == false {
if keychainUtil.updatePassword(PrefKeys.refreshToken.rawValue, pass: refreshToken,shouldUpdateACL: setACL, keychainPassword:password) == false {
TCSLogWithMark("Error Updating refreshToken Token")

return false
}
}

let cloudPassword = tokens.password


if cloudPassword.count>0 {
if creds.password.count>0 {
TCSLogWithMark("Saving cloud password")

if keychainUtil.updatePassword(PrefKeys.password.rawValue, pass: tokens.password,shouldUpdateACL: setACL, keychainPassword:password) == false {
if keychainUtil.updatePassword(PrefKeys.password.rawValue, pass: creds.password,shouldUpdateACL: setACL, keychainPassword:password) == false {
TCSLogWithMark("Error Updating password")

return false
Expand Down
12 changes: 4 additions & 8 deletions XCreds/WebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class WebViewController: NSWindowController {
}
}
}
func tokensUpdated(tokens: Tokens){
func tokensUpdated(tokens: Creds){
//to be overridden by superclasses
}
}
Expand Down Expand Up @@ -250,14 +250,10 @@ extension WebViewController: OIDCLiteDelegate {
RunLoop.main.perform {
if let password = self.password {
TCSLogWithMark("----- Password was set")
let returnTokens = Tokens(password: password, accessToken: tokens.accessToken ?? "", idToken: tokens.idToken ?? "", refreshToken: tokens.refreshToken ?? "")
self.tokensUpdated(tokens: returnTokens)
let xcredCreds = Creds(password: password, tokens: tokens)
self.tokensUpdated(tokens: xcredCreds)

/*
let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, Any>
*/
NotificationCenter.default.post(name: Notification.Name("TCSTokensUpdated"), object: self, userInfo:["tokens":returnTokens]
NotificationCenter.default.post(name: Notification.Name("TCSTokensUpdated"), object: self, userInfo:["tokens":xcredCreds]
)
}
else {
Expand Down
9 changes: 5 additions & 4 deletions XCredsLoginPlugIn/LoginWindow/LoginWebView.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21225" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
<plugIn identifier="com.apple.WebKit2IBPlugin" version="20037"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21225"/>
<plugIn identifier="com.apple.WebKit2IBPlugin" version="21225"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
Expand All @@ -17,7 +18,7 @@
<window title="Sign In" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titleVisibility="hidden" id="KxT-zM-Vnn" customClass="LoginWindow" customModule="XCredsLoginPlugin" customModuleProvider="target">
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="453" y="250" width="628" height="613"/>
<rect key="screenRect" x="0.0" y="0.0" width="1536" height="935"/>
<rect key="screenRect" x="0.0" y="0.0" width="2048" height="833"/>
<view key="contentView" wantsLayer="YES" id="2LH-tE-efn">
<rect key="frame" x="0.0" y="0.0" width="628" height="613"/>
<autoresizingMask key="autoresizingMask"/>
Expand Down
73 changes: 58 additions & 15 deletions XCredsLoginPlugIn/LoginWindow/LoginWebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class LoginWebViewController: WebViewController {
// })
}

override func tokensUpdated(tokens: Tokens) {
override func tokensUpdated(tokens: Creds) {
//if we have tokens, that means that authentication was successful.
//we have to check the password here so we can prompt.

Expand All @@ -109,7 +109,12 @@ class LoginWebViewController: WebViewController {
var username:String
let defaultsUsername = UserDefaults.standard.string(forKey: PrefKeys.username.rawValue)

let idToken = tokens.idToken
guard let idToken = tokens.idToken else {
TCSLogWithMark("invalid idToken")

delegate.denyLogin()
return
}

let array = idToken.components(separatedBy: ".")

Expand All @@ -123,7 +128,6 @@ class LoginWebViewController: WebViewController {
delegate.denyLogin()
return
}

let decoder = JSONDecoder()
var idTokenObject:IDToken
do {
Expand All @@ -137,18 +141,30 @@ class LoginWebViewController: WebViewController {
return

}

let idTokenInfo = jwtDecode(value: idToken) //dictionary for mappnigs

let mappings = UserDefaults.standard.object(forKey: "mappings")

// username
if let defaultsUsername = defaultsUsername {
username = defaultsUsername
}
else if let idTokenInfo = idTokenInfo, let mappings = mappings as? Dictionary <String,Any>, let mapKey = mappings["username"] as? String, mapKey.count>0, let mapValue = idTokenInfo[mapKey] as? String {
//we have a mapping for username, so use that.

username = mapValue
TCSLogWithMark("username found: \(username)")

}
else {
var emailString:String


if idTokenObject.email != nil {
emailString=idTokenObject.email!.lowercased()
if let email = idTokenObject.email {
emailString=email.lowercased()
}
else if idTokenObject.unique_name != nil {
emailString=idTokenObject.unique_name!
else if let uniqueName=idTokenObject.unique_name {
emailString=uniqueName
}
else {
TCSLogWithMark("no username found or invalid")
Expand All @@ -167,15 +183,42 @@ class LoginWebViewController: WebViewController {
username = tUsername
}

if let firstName = idTokenObject.given_name, let lastName = idTokenObject.family_name {
//full name
if let idTokenInfo = idTokenInfo, let mappings = mappings as? Dictionary <String,Any>, let mapKey = mappings["fullName"] as? String, mapKey.count>0, let mapValue = idTokenInfo[mapKey] as? String {
//we have a mapping so use that.
TCSLogWithMark("full name mapped to: \(mapKey)")

delegate.setHint(type: .fullName, hint: "\(mapValue)")

}

else if let firstName = idTokenObject.given_name, let lastName = idTokenObject.family_name {
delegate.setHint(type: .fullName, hint: "\(firstName) \(lastName)")

}
if let firstName = idTokenObject.given_name {

//first name
if let idTokenInfo = idTokenInfo, let mappings = mappings as? Dictionary <String,Any>, let mapKey = mappings["firstName"] as? String, mapKey.count>0, let mapValue = idTokenInfo[mapKey] as? String {
//we have a mapping for username, so use that.
TCSLogWithMark("first name mapped to: \(mapKey)")

delegate.setHint(type: .firstName, hint:mapValue)
}

else if let firstName = idTokenObject.given_name {
delegate.setHint(type: .firstName, hint:firstName)

}
if let lastName = idTokenObject.family_name {
//last name

if let idTokenInfo = idTokenInfo, let mappings = mappings as? Dictionary <String,Any>, let mapKey = mappings["lastName"] as? String, mapKey.count>0, let mapValue = idTokenInfo[mapKey] as? String {
//we have a mapping for username, so use that.
TCSLogWithMark("last name mapped to: \(mapKey)")

delegate.setHint(type: .lastName, hint:mapValue)
}

else if let lastName = idTokenObject.family_name {
delegate.setHint(type: .lastName, hint:lastName)

}
Expand Down Expand Up @@ -275,15 +318,15 @@ class LoginWebViewController: WebViewController {
TCSLogWithMark("updating username:\(username), password, and tokens")
delegate.setContextString(type: kAuthorizationEnvironmentUsername, value: username)
delegate.setContextString(type: kAuthorizationEnvironmentPassword, value: tokens.password)
delegate.setHint(type: .user, hint: username)
// delegate.setHint(type: .user, hint: username)
delegate.setHint(type: .pass, hint: tokens.password)
// setHint(type: .noMADFirst, hint: user.firstName)
// setHint(type: .noMADLast, hint: user.lastName)
// setHint(type: .noMADDomain, hint: domainName)
// setHint(type: .noMADGroups, hint: user.groups)
delegate.setHint(type: .fullName, hint: idTokenObject.unique_name ?? username)
delegate.setHint(type: .firstName, hint: idTokenObject.given_name ?? "")
delegate.setHint(type: .lastName, hint: idTokenObject.family_name ?? "")
// delegate.setHint(type: .fullName, hint: idTokenObject.unique_name ?? username)
// delegate.setHint(type: .firstName, hint: idTokenObject.given_name ?? "")
// delegate.setHint(type: .lastName, hint: idTokenObject.family_name ?? "")

delegate.setHint(type: .tokens, hint: [tokens.idToken,tokens.refreshToken,tokens.accessToken])
if let resolutionObserver = resolutionObserver {
Expand Down
19 changes: 8 additions & 11 deletions XCredsLoginPlugIn/Mechanisms/XCredsKeychainAdd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,18 @@ class XCredsKeychainAdd : XCredsBaseMechanism {
username = usernameContext ?? ""
userpass = passwordContext ?? ""

var tokens = Tokens()
let tokenArray = getHint(type: .tokens) as? Array<String>

guard let tokenArray = tokenArray, tokenArray.count==3 else {
TCSLogWithMark("no tokens but allowing login")
allowLogin()
return
}

if let tokenArray = tokenArray, tokenArray.count==3 {
tokens.idToken = tokenArray[0]
tokens.refreshToken = tokenArray[1]
tokens.accessToken = tokenArray[2]
tokens.password = userpass
let xcredsCreds = Creds(accessToken: tokenArray[2], idToken: tokenArray[0], refreshToken: tokenArray[1], password: userpass, jsonDict: Dictionary(), pass: userpass)
TCSLogWithMark("got tokens")

}
else {
TCSLogWithMark("no tokens")
}


let (uid, home) = checkUIDandHome(name: username)

Expand Down Expand Up @@ -204,7 +201,7 @@ class XCredsKeychainAdd : XCredsBaseMechanism {
// }
// }
TCSLogWithMark("saving tokens to keychain")
if TokenManager.shared.saveTokensToKeychain(tokens: tokens, setACL: true, password:userpass )==false {
if TokenManager.shared.saveTokensToKeychain(creds: xcredsCreds, setACL: true, password:userpass )==false {
TCSLogWithMark("Error saving tokens to keychain")
}

Expand Down
Binary file not shown.

0 comments on commit 074ac99

Please sign in to comment.