Skip to content

Commit

Permalink
Merge pull request #1 from bike-north/development
Browse files Browse the repository at this point in the history
Joomla 3 Changes and Group map supports multiple Joomla group ids per crowd group
  • Loading branch information
dcapslock authored Jun 21, 2018
2 parents bb2a20c + 6c98897 commit 0639b9b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 74 deletions.
126 changes: 67 additions & 59 deletions crowd/crowd.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

class plgAuthenticationCrowd extends JPlugin
{
const LOGGER_CATEGORY = 'crowd';

/**
* Constructor
*
Expand All @@ -30,9 +32,8 @@ class plgAuthenticationCrowd extends JPlugin
*/
function plgAuthenticationCrowd(& $subject, $config) {
parent::__construct($subject, $config);
JLog::addLogger(array('text_file' => 'debug.crowd.log'));
JLog::add('crowd 0.01 Start logging');
//JLog::add('crowd config params: ' . $this->params);
JLog::addLogger(array('text_file' => 'debug.crowd.log'), JLog::DEBUG, array(self::LOGGER_CATEGORY));
JLog::add('crowd 0.01 Start logging', JLog::DEBUG, self::LOGGER_CATEGORY);
}

// see rules.php
Expand All @@ -55,85 +56,85 @@ protected function checkDeleteUser($credentials)
JLog::add('check if we have to delete user ' . $credentials['username']);
$id = intval(JUserHelper::getUserId($credentials['username']));
if ($id < 1) {
JLog::add('user not known to joomla, do nothing');
JLog::add('user not known to joomla, do nothing', JLog::DEBUG, self::LOGGER_CATEGORY);
return; // no such user in joomla, nothing to do for us
}

// check whether this user exists in crowd
$server = $this->params->get('crowd_url');
$appname = $this->params->get('crowd_app_name');
$apppass = $this->params->get('crowd_password');
JLog::add('onUserAuthenticate: connecting to url ' . $server);
JLog::add('onUserAuthenticate: connecting to url ' . $server, JLog::DEBUG, self::LOGGER_CATEGORY);
$authcode = base64_encode($appname . ":" . $apppass);
// JLog::add('auth code [' . $authcode . ']');

// request cookie config from crowd
$request_url = $server . '/rest/usermanagement/1/user?username=' . $credentials['username'];
$request_header = array('Accept' => 'application/json', 'Content-type' => 'application/xml',
$request_header = array('Accept' => 'application/json', 'Content-Type' => 'application/xml',
'Authorization' => 'Basic ' . $authcode);
$http = new JHttp;
JLog::add('request url ' . $request_url);
JLog::add('with headers ' . var_export($request_header, true));
JLog::add('request url ' . $request_url, JLog::DEBUG, self::LOGGER_CATEGORY);
JLog::add('with headers ' . var_export($request_header, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$result = $http->get($request_url, $request_header);
JLog::add('response: ' . var_export($result, true));
JLog::add('response: ' . var_export($result, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$obj = json_decode($result->body);
JLog::add('msg: ' . $obj->reason);
JLog::add('msg: ' . $obj->reason, JLog::DEBUG, self::LOGGER_CATEGORY);
if ($obj->reason != 'USER_NOT_FOUND') {
JLog::add('crowd seems to know about this user, do not delete from joomla!');
JLog::add('crowd seems to know about this user, do not delete from joomla!', JLog::DEBUG, self::LOGGER_CATEGORY);
return;
}

// delete this user
$user = JUser::getInstance();
$user->load($id);
$user->delete();
JLog::add('user deleted from joomla.');
JLog::add('user deleted from joomla.', JLog::DEBUG, self::LOGGER_CATEGORY);
}

/** creates a new joomla group, returns the resulting group id */
protected function createGroup($gname)
{
//$db = JFactory::getDbo();
JLog::add('createGroup not yet implemented!');
JLog::add('createGroup not yet implemented!', JLog::DEBUG, self::LOGGER_CATEGORY);
}


/** Trust the sso flag, login without password */
function doSSOLogin( $credentials, $options, &$response )
{
JLog::add('crowd::onUserAuthenticate immediate login: ' . var_export($credentials, true));
JLog::add('crowd::onUserAuthenticate immediate login: ' . var_export($credentials, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$response->status = JAuthentication::STATUS_SUCCESS;
$response->email = $credentials['email'];
$response->fullname = $credentials['fullname'];
$response->username = $credentials['username'];
$response->error_message = '';
JLog::add('crowd: returning response: ' . var_export($response, true));
JLog::add('crowd: returning response: ' . var_export($response, true), JLog::DEBUG, self::LOGGER_CATEGORY);
return true;
}

/** checks username/password against crowd */
function doCrowdLogin( $credentials, $options, &$response )
{
JLog::add('doing regular login');
JLog::add('doing regular login', JLog::DEBUG, self::LOGGER_CATEGORY);

$server = $this->params->get('crowd_url');
$appname = $this->params->get('crowd_app_name');
$apppass = $this->params->get('crowd_password');
JLog::add('onUserAuthenticate: connecting to url ' . $server);
JLog::add('onUserAuthenticate: connecting to url ' . $server, JLog::DEBUG, self::LOGGER_CATEGORY);
$authcode = base64_encode($appname . ":" . $apppass);
// JLog::add('auth code [' . $authcode . ']');

// request cookie config from crowd
$request_url = $server . '/rest/usermanagement/1/config/cookie';
$request_header = array('Accept' => 'application/json', 'Content-type' => 'application/xml',
$request_header = array('Accept' => 'application/json', 'Content-Type' => 'application/xml',
'Authorization' => 'Basic ' . $authcode);
$http = new JHttp;
JLog::add('request url ' . $request_url);
JLog::add('with headers ' . var_export($request_header, true));
JLog::add('request url ' . $request_url, JLog::DEBUG, self::LOGGER_CATEGORY);
JLog::add('with headers ' . var_export($request_header, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$result = $http->get($request_url, $request_header);
JLog::add('cookie config: ' . var_export($result, true));
JLog::add('cookie config: ' . var_export($result, true), JLog::DEBUG, self::LOGGER_CATEGORY);
if (!$result or $result->code != 200) {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = 'Cannot fetch cookie config from crowd';
return false;
}
Expand All @@ -147,11 +148,11 @@ function doCrowdLogin( $credentials, $options, &$response )
$cookieDomain = $altCookieDomain;
}

JLog::add('cookie name: ' . $cookieName . ', domain: ' . $cookieDomain);
JLog::add('cookie name: ' . $cookieName . ', domain: ' . $cookieDomain, JLog::DEBUG, self::LOGGER_CATEGORY);

// now trying to login
$request_url = $server . '/rest/usermanagement/1/session?validate-password=true';
JLog::add('request url ' . $request_url);
JLog::add('request url ' . $request_url, JLog::DEBUG, self::LOGGER_CATEGORY);
$request_data = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' .
'<authentication-context>' .
' <username>' . $credentials['username'] . '</username>' .
Expand All @@ -164,23 +165,23 @@ function doCrowdLogin( $credentials, $options, &$response )
' </validation-factors>' .
'</authentication-context>';
#JLog::add('request data: ' . $request_data);
$request_header = array('Accept' => 'application/xml', 'Content-type' => 'application/xml',
$request_header = array('Accept' => 'application/xml', 'Content-Type' => 'application/xml',
'Authorization' => 'Basic ' . $authcode);
JLog::add('with headers ' . var_export($request_header, true));
JLog::add('with headers ' . var_export($request_header, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$result = $http->post($request_url, $request_data, $request_header);
JLog::add('response: ' . var_export($result, true));
JLog::add('response: ' . var_export($result, true), JLog::DEBUG, self::LOGGER_CATEGORY);
if (!$result or $result->code != 201) {
JLog::add('have not got expected code 201, login failed');
$response->status = JAUTHENTICATE_STATUS_FAILURE;
JLog::add('have not got expected code 201, login failed', JLog::DEBUG, self::LOGGER_CATEGORY);
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = 'Login to crowd failed';
return false;
}
JLog::add('fetching info from new location: ' . $result->headers['Location']);
JLog::add('fetching info from new location: ' . $result->headers['Location'], JLog::DEBUG, self::LOGGER_CATEGORY);
$result = $http->get($result->headers['Location'], $request_header);
JLog::add('response: ' . var_export($result, true));
JLog::add('response: ' . var_export($result, true), JLog::DEBUG, self::LOGGER_CATEGORY);
if (!$result or $result->code != 200) {
JLog::add('have not got expected code 200, login failed');
$response->status = JAUTHENTICATE_STATUS_FAILURE;
JLog::add('have not got expected code 200, login failed', JLog::DEBUG, self::LOGGER_CATEGORY);
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = 'Login to crowd failed';
return false;
}
Expand All @@ -192,61 +193,61 @@ function doCrowdLogin( $credentials, $options, &$response )
$response->email = (string) $xml->user->email;
$response->fullname = (string) $xml->user->{'display-name'};
$response->username = (string) $xml->user['name'];
$response->status = JAUTHENTICATE_STATUS_SUCCESS;
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
JLog::add('login successfull, returning: ' . var_export($response, true));
JLog::add('login successfull, returning: ' . var_export($response, true), JLog::DEBUG, self::LOGGER_CATEGORY);

// finally export our token as cookie
JLog::add('set cookie ' . $cookieName . ' = ' . $token);
JLog::add('set cookie ' . $cookieName . ' = ' . $token, JLog::DEBUG, self::LOGGER_CATEGORY);
setcookie($cookieName,$token, 0, "/", $cookieDomain,false,true);

return true;
}

function handleGroups( $user, $credentials, $options, &$response )
{
JLog::add('login succeeded, obtaining groups');
JLog::add('login succeeded, obtaining groups', JLog::DEBUG, self::LOGGER_CATEGORY);
$server = $this->params->get('crowd_url');
$appname = $this->params->get('crowd_app_name');
$apppass = $this->params->get('crowd_password');
JLog::add('handleGroups: connecting to url ' . $server);
JLog::add('handleGroups: connecting to url ' . $server, JLog::DEBUG, self::LOGGER_CATEGORY);
$authcode = base64_encode($appname . ":" . $apppass);
// JLog::add('auth code [' . $authcode . ']');

// request groups from crowd
$request_url = $server . '/rest/usermanagement/1/user/group/direct?username=' . $credentials['username'];
$request_header = array('Accept' => 'application/json', 'Content-type' => 'application/xml',
$request_header = array('Accept' => 'application/json', 'Content-Type' => 'application/xml',
'Authorization' => 'Basic ' . $authcode);
$http = new JHttp;
JLog::add('request url ' . $request_url);
JLog::add('with headers ' . var_export($request_header, true));
JLog::add('request url ' . $request_url, JLog::DEBUG, self::LOGGER_CATEGORY);
JLog::add('with headers ' . var_export($request_header, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$result = $http->get($request_url, $request_header);
JLog::add('group config: ' . var_export($result, true));
JLog::add('group config: ' . var_export($result, true), JLog::DEBUG, self::LOGGER_CATEGORY);
if (!$result or $result->code != 200) {
$response->status = JAUTHENTICATE_STATUS_FAILURE;
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = 'Cannot fetch groups from crowd';
return false;
}
$obj = json_decode($result->body);
$groups = $obj->groups; // array containing all crowd groups of this user as objects with attr 'name'
JLog::add('crowd groups: ' . var_export($groups, true));
JLog::add('crowd groups: ' . var_export($groups, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$response->groups = array();
$allgroups = $this->getUserGroups(); // array of objects containing group name and joomla id as 'text' and 'value'
JLog::add('joomla groups: ' . var_export($allgroups, true));
JLog::add('joomla groups: ' . var_export($allgroups, true), JLog::DEBUG, self::LOGGER_CATEGORY);
$allgroupnames = array(); // array of joomla group names

$groupmapping = explode(";",$this->params->get('crowd_group_map'));
$groupmap = array();
foreach ($groupmapping as $gm) {
$ml = explode(":",$gm);
if (count($ml) != 2 || intval($ml[1]) < 1) {
JLog::add('ignored mapping entry [' . $gm . ']');
JLog::add('ignored mapping entry [' . $gm . ']', JLog::DEBUG, self::LOGGER_CATEGORY);
}
else {
$groupmap[trim($ml[0])] = intval($ml[1]);
$groupmap[trim($ml[0])] = explode(",",$ml[1]);
}
}
JLog::add('groupmap: ' . var_export($groupmap,true));
JLog::add('groupmap: ' . var_export($groupmap,true), JLog::DEBUG, self::LOGGER_CATEGORY);

foreach ($allgroups as $jgroup) {
array_push($allgroupnames, $jgroup->text);
Expand All @@ -255,35 +256,42 @@ function handleGroups( $user, $credentials, $options, &$response )
// first remove user from all groups
foreach ($allgroups as $group) {
$res = JUserHelper::removeUserFromGroup($user->id, $group->value);
JLog::add('removed user from group ' . $group->text . ' with result ' . $res);
JLog::add('removed user from group ' . $group->text . ' with result ' . $res, JLog::DEBUG, self::LOGGER_CATEGORY);
}

// Process Group Map default if exists
if (array_key_exists("*", $groupmap)) {
$res = JUserHelper::setUserGroups($user->id, $groupmap["*"]);
JLog::add('added user to mapped groups ' . $group->name . ':' . implode(",", $groupmap["*"]) . ' result: ' . $res, JLog::DEBUG, self::LOGGER_CATEGORY);
}


// now re-add all groups we have got from crowd
foreach ($groups as $group) {
JLog::add('got group: ' . $group->name);
JLog::add('got group: ' . $group->name, JLog::DEBUG, self::LOGGER_CATEGORY);
array_push($response->groups, $group->name);
//array_push($user->groups, $group->name);

// check mapping
if (array_key_exists($group->name, $groupmap)) {
$res = JUserHelper::addUserToGroup($user->id, $groupmap[$group->name]);
JLog::add('added user to mapped group ' . $group->name . ' result: ' . $res);
$res = JUserHelper::setUserGroups($user->id, $groupmap[$group->name]);
JLog::add('added user to mapped groups ' . $group->name . ':' . implode(",", $groupmap[$group->name]) . ' result: ' . $res, JLog::DEBUG, self::LOGGER_CATEGORY);
continue;
}

// create new groups if needed
if (!in_array($group->name, $allgroupnames)) {
JLog::add('create new group ' . $group->name);
JLog::add('create new group ' . $group->name, JLog::DEBUG, self::LOGGER_CATEGORY);
$gid = $this->createGroup($group->name);
}
else { // group already exists in joomla
foreach ($allgroups as $g) {
if ($g->text == $group->name) {
try {
JUserHelper::addUserToGroup($user->id, $g->value);
JLog::add("added user " . $user->id . ' to group ' . $g->name . ' id: ' . $g->value);
JLog::add("added user " . $user->id . ' to group ' . $g->name . ' id: ' . $g->value, JLog::DEBUG, self::LOGGER_CATEGORY);
} catch (Exception $e) {
JLog::add('adding user ' . $user->id . ' to group ' . $g->name . ' caused exception: ' . $e->getMessage());
JLog::add('adding user ' . $user->id . ' to group ' . $g->name . ' caused exception: ' . $e->getMessage(), JLog::DEBUG, self::LOGGER_CATEGORY);
}
}
}
Expand All @@ -292,7 +300,7 @@ function handleGroups( $user, $credentials, $options, &$response )
try {
$user->save();
} catch (Exception $e) {
JLog::add('saving user ' . $user->id . ' caused exception: ' . $e->getMessage());
JLog::add('saving user ' . $user->id . ' caused exception: ' . $e->getMessage(), JLog::DEBUG, self::LOGGER_CATEGORY);
}

}
Expand All @@ -309,7 +317,7 @@ function handleGroups( $user, $credentials, $options, &$response )
*/
function onUserAuthenticate( $credentials, $options, &$response )
{
JLog::add('onUserAuthenticate: auth started');
JLog::add('onUserAuthenticate: auth started', JLog::DEBUG, self::LOGGER_CATEGORY);
$response->type = 'Crowd';
$response->password_clear = "";
$login_succeeded = false;
Expand All @@ -320,7 +328,7 @@ function onUserAuthenticate( $credentials, $options, &$response )
$login_succeeded = $this->doCrowdLogin($credentials, $options, $response);
}
if ($credentials['username'] == "admin") {
JLog::add('admin login, neither check user nor groups');
JLog::add('admin login, neither check user nor groups', JLog::DEBUG, self::LOGGER_CATEGORY);
return login_succeeded; // do not more for admin user
}
if (! $login_succeeded) {
Expand All @@ -331,7 +339,7 @@ function onUserAuthenticate( $credentials, $options, &$response )
if ($id = intval(JUserHelper::getUserId($response->username))) {
}
else {
JLog::add('creating new user ' . $response->username);
JLog::add('creating new user ' . $response->username, JLog::DEBUG, self::LOGGER_CATEGORY);
$user->set('id', 0);
$user->set('name', $response->fullname);
$user->set('username', $response->username);
Expand Down
4 changes: 2 additions & 2 deletions crowd/crowd.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<install version="1.5" type="plugin" group="authentication" method="upgrade">
<extension version="1.5" type="plugin" group="authentication" method="upgrade">
<name>Authentication - Crowd</name>
<author>Joomla! Documentation Project</author>
<creationDate>Apr 10, 2012</creationDate>
Expand Down Expand Up @@ -44,4 +44,4 @@
</fieldset>
</fields>
</config>
</install>
</extension>
Loading

0 comments on commit 0639b9b

Please sign in to comment.