Skip to content

Commit

Permalink
Merge pull request #4 from SlateFoundation/develop
Browse files Browse the repository at this point in the history
Release v1.0.0.rc-1
  • Loading branch information
nbey authored Sep 8, 2020
2 parents 4a3e126 + 67038e1 commit 1f72d3a
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 56 deletions.
7 changes: 7 additions & 0 deletions .holo/branches/emergence-layer/_slate-connector-looker.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[holomapping]
files = [
"*/**",
"!.github/",
"!.vscode/"
]
after = "*"
3 changes: 2 additions & 1 deletion .holo/branches/emergence-site/_slate-connector-looker.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[holomapping]
files = "*/**"
holosource = "=>emergence-layer"
files = "**"
after = "*"
16 changes: 13 additions & 3 deletions php-classes/Slate/Connectors/Looker/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,19 @@ public static function createUser(array $data)

public static function updateUser($userId, $data = [])
{
\MICS::dump($data, $userId);
return static::post('users/'.$userId, $data);
return static::patch('users/'.$userId, $data);
}
//https://building21.looker.com:19999/api-docs/index.html#!/3.1/User/create_user_credentials_email
public static function createUserEmailCredentials($userId, $data = [])
{
return static::post('users/'.$userId.'/credentials_email', $data);
}
//https://building21.looker.com:19999/api-docs/index.html#!/3.1/User/update_user_credentials_email
public static function updateUserEmailCredentials($userId, $data = [])
{
return static::patch('users/'.$userId.'/credentials_email', $data);
}

// https://building21.looker.com:19999/api-docs/index.html#!/3.1/User/set_user_roles
public static function updateUserRoles($userId, $data = [])
{
Expand Down Expand Up @@ -243,4 +253,4 @@ public static function request($path, array $options = [])

return $result;
}
}
}
130 changes: 78 additions & 52 deletions php-classes/Slate/Connectors/Looker/Connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,19 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $

// check for any changes
$lookerUser = LookerAPI::getUserById($Mapping->ExternalIdentifier, ['fields' => 'id,first_name,last_name,email,group_ids,role_ids']);
$changes = [];
$lookerUserChanges = [];

if ($lookerUser['first_name'] != ($User->PreferredName ?: $User->FirstName)) {
$lookerUserChanges['user[first_name]'] = [
if ($lookerUser['first_name'] != $User->FirstName) {
$lookerUserChanges['first_name'] = [
'from' => $lookerUser['first_name'],
'to' => $User->PreferredName ?: $User->Firstname
'to' => $User->FirstName
];
}

if ($lookerUser['last_name'] != $User->LastName) {
$lookerUserChanges['user[last_name]'] = [
$lookerUserChanges['last_name'] = [
'from' => $lookerUser['last_name'],
'to' => $User->Lastname
'to' => $User->LastName
];
}

Expand All @@ -163,26 +162,26 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $
if (!$pretend) {
$lookerResponse = LookerAPI::updateUser($Mapping->ExternalIdentifier, DataUtil::extractToFromDelta($lookerUserChanges));
$logger->debug(
'Updating Looker for user {slateUsername}',
'Updating Looker for user {slateEmail}',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'lookerUserChanges' => $lookerUserChanges,
'lookerResponse' => $lookerResponse
]
);
}
$logger->notice(
'Updated user {slateUsername}',
'Updated user {slateEmail}',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'changes' => $changes['user']
]
);
} else {
$logger->debug(
'Looker user matches Slate user {slateUsername}',
'Looker user matches Slate user {slateEmail}',
[
'slateUsername' => $User->Username
'slateEmail' => $User->Email
]
);
}
Expand Down Expand Up @@ -227,17 +226,17 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $
}

return new SyncResult(
(!empty($changes) || !empty($userUpdated)) ? SyncResult::STATUS_UPDATED : SyncResult::STATUS_VERIFIED,
'Looker account for {slateUsername} found and verified up-to-date.',
(!empty($lookerUserChanges) || !empty($userUpdated)) ? SyncResult::STATUS_UPDATED : SyncResult::STATUS_VERIFIED,
'Looker account for {slateEmail} found and verified up-to-date.',
[
'slateUsername' => $User->Username
'slateEmail' => $User->Email
]
);
} else { // try to create user if no mapping found
// skip accounts with no email
if (!$User->PrimaryEmail) {
if (!$User->Email) {
$logger->debug(
'Skipping user {slateUsername} without Primary Email',
'Skipping user {slateUsername} without Email',
[
'slateUsername' => $User->Username
]
Expand All @@ -255,37 +254,48 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $
if (!$pretend) {
$lookerResponse = LookerAPI::createUser([
'first_name' => $User->FirstName,
'last_name' => $User->LastName,
'email' => $User->PrimaryEmail->toString()
'last_name' => $User->LastName
]);

if (empty($lookerResponse['id'])) {
throw new SyncException(
'Failed to create Looker user for {slateUsername}',
'Failed to create Looker user for {slateEmail}',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'lookerResponse' => $lookerResponse
]
);
}

$mappingData['ExternalIdentifier'] = $lookerResponse['id'];
Mapping::create($mappingData, true);
} else {
$lookerResponse = [];
}
$Mapping = Mapping::create($mappingData, true);

$logger->notice(
'Created Looker user for {slateUsername}',
$credentialsResponse = LookerAPI::createUserEmailCredentials($Mapping->ExternalIdentifier, [
'email' => $User->Email
]);

$logger->notice(
'Created Looker user credentials for {slateEmail}',
[
'slateUsername' => $User->Username,
'lookerResponse' => $pretend ? '(pretend-mode)' : $lookerResponse
'slateEmail' => $User->Email,
'lookerResponse' => $pretend ? '(pretend-mode)' : $credentialsResponse
]
);

} else {
$lookerResponse = [];
}

$logger->notice(
'Created Looker user for {slateEmail}',
[
'slateEmail' => $User->Email,
'lookerResponse' => $pretend ? '(pretend-mode)' : $lookerResponse
]
);
// sync groups
try {
$groupSyncResult = static::syncUserGroups($User, [], $logger, $pretend);
$groupSyncResult = static::syncUserGroups($User, $lookerResponse, $logger, $pretend);
} catch (SyncException $e) {
$logger->error(
$e->getInterpolatedMessage(),
Expand All @@ -294,7 +304,7 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $
}
// sync roles
try {
static::syncUserRoles($User, [], $logger, $pretend);
static::syncUserRoles($User, $lookerResponse, $logger, $pretend);
} catch (SyncException $e) {
$logger->error(
$e->getInterpolatedMessage(),
Expand All @@ -313,9 +323,9 @@ public static function pushUser(IPerson $User, LoggerInterface $logger = null, $

return new SyncResult(
SyncResult::STATUS_CREATED,
'Created Looker user for {slateUsername}, saved mapping to new Looker user #{lookerUserId}',
'Created Looker user for {slateEmail}, saved mapping to new Looker user #{lookerUserId}',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'lookerUserId' => $pretend ? '(pretend-mode)' : $lookerResponse['id'],
'lookerUser' => $pretend ? '(pretend-mode)' : $lookerResponse
]
Expand Down Expand Up @@ -357,15 +367,27 @@ protected static function syncUserRoles(IPerson $User, array $lookerUser, Logger

if ($rolesToAdd = array_diff($userRoles, $roleIds)) {
$logger->debug(
'Updating {slateUsername} roles to: [{userRoles}]',
'Updating {slateEmail} roles to: [{userRoles}]',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'userRoles' => join(',', array_unique(array_merge($userRoles, $roleIds)))
]
);

if (!$pretend) {
$lookerResponse = LookerAPI::updateUserRoles($lookerUser['id'], $rolesToAdd);
if (empty($lookerResponse) || !is_array($lookerResponse)) {
$logger->error('Unexpected response syncing user roles', [
'lookerResponse' => $lookerResponse
]);

return new SyncException(
'Unable to sync user roles.',
[
'lookerResponse' => $lookerResponse
]
);
}
$userRoleIds = [];
foreach ($lookerResponse as $userRoleData) {
$userRoleIds[] = $userRoleData['id'];
Expand Down Expand Up @@ -433,17 +455,18 @@ protected static function syncUserGroups(IPerson $User, array $lookerUser, Logge
$groupIds = $lookerUser['group_ids'] ?: [];
$userGroups = array_values(static::getUserGroups($User));
$logger->debug(
'Analyzing user groups: [{groupIds}]',
'Analyzing looker user groups: {groupIds}',
[
'groupIds' => join(',', $groupIds)
'groupIds' => empty($groupIds) ? '(none)' : '[' . join(',', $groupIds) .']'
]
);

if ($groupsToAdd = array_diff($userGroups, $groupIds)) {
if (!empty($groupsToAdd = array_diff($userGroups, $groupIds))) {

$logger->debug(
'Updating {slateUsername} groups to: [{userGroups}]',
'Updating {slateEmail} Looker groups to: [{userGroups}]',
[
'slateUsername' => $User->Username,
'slateEmail' => $User->Email,
'userGroups' => join(',', array_unique(array_merge($userGroups, $groupIds)))
]
);
Expand Down Expand Up @@ -492,9 +515,9 @@ protected static function syncUserGroups(IPerson $User, array $lookerUser, Logge

return new SyncResult(
empty($groupsToAdd) ? SyncResult::STATUS_VERIFIED : SyncResult::STATUS_UPDATED,
'Updated groups for {slateUsername} in Looker ' . $pretend ? '(pretend-mode)' : '',
'Updated groups for {slateEmail} in Looker ' . $pretend ? '(pretend-mode)' : '',
[
'slateUsername' => $User->Username
'slateEmail' => $User->Email
]
);
}
Expand Down Expand Up @@ -564,8 +587,8 @@ protected static function syncUserCustomAttributes(IPerson $User, array $lookerU
);
} else {

$logger->debug('Syncing user custom attributes for {slateUsername}: {attributesToSet}', [
'slateUsername' => $User->Username,
$logger->debug('Syncing user custom attributes for {slateEmail}: {attributesToSet}', [
'slateEmail' => $User->Email,
'attributesToSet' => join(', ', array_map(function($c) { return "$c[name] => $c[value]"; }, $customAttributesToAdd))
]);

Expand Down Expand Up @@ -617,20 +640,19 @@ public static function pushUsers(IJob $Job, $pretend = true)
'created' => 0,
'updated' => 0,
'skipped' => 0,
'failed' => 0
'failed' => 0,
'verified' => 0
];

// iterate over Slate users
$slateUsers = [];
$slateOnlyUsers = [];
$UsersToSync = User::getAllByWhere('Username IS NOT NULL AND AccountLevel != "Disabled"');

foreach (User::getAllByWhere('Username IS NOT NULL AND AccountLevel != "Disabled"') AS $User) {
foreach ($UsersToSync AS $User) {
$Job->debug(
'Analyzing Slate user {slateUsername} ({slateUserClass}/{userGraduationYear})',
'Analyzing Slate user {slateUsername} ({slateEmail})',
[
'slateUsername' => $User->Username,
'slateUserClass' => $User->Class,
'userGraduationYear' => $User->GraduationYear
'slateEmail' => $User->Email
]
);
$results['analyzed']++;
Expand All @@ -642,6 +664,8 @@ public static function pushUsers(IJob $Job, $pretend = true)
$results['created']++;
} elseif ($syncResult->getStatus() === SyncResult::STATUS_UPDATED) {
$results['updated']++;
} elseif ($syncResult->getStatus() === SyncResult::STATUS_VERIFIED) {
$results['verified']++;
} elseif ($syncResult->getStatus() === SyncResult::STATUS_SKIPPED) {
$results['skipped']++;
continue;
Expand Down Expand Up @@ -673,11 +697,13 @@ public static function getSAMLNameId(IPerson $Person)

public static function getSAMLAttributes(IPerson $Person)
{
// TODO: add roles, groups, custom attributes
// TODO: add roles, groups, custom attributes?
return [
'Email' => [$Person->Email],
'FName' => [$Person->FirstName],
'LName' => [$Person->LastName]
// removed until thoroughly tested
//'Roles' => static::getUserRoles($Person)
];
}
}

0 comments on commit 1f72d3a

Please sign in to comment.