Skip to content
This repository has been archived by the owner on Feb 15, 2025. It is now read-only.

Commit

Permalink
Support SSPv1.17+ (based on 6653804)
Browse files Browse the repository at this point in the history
- Added namespaces
- Changed array notation
- Removed trailing spaces
  • Loading branch information
NicolasLiampotis committed May 16, 2022
1 parent a8be927 commit 6271aaa
Showing 1 changed file with 83 additions and 75 deletions.
158 changes: 83 additions & 75 deletions lib/Auth/Process/COmanageRestClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,28 @@
*
* Example configuration:
*
* authproc = array(
* authproc = [
* ...
* '60' => array(
* '60' => [
* 'class' => 'attrauthcomanage:COmanageRestClient',
* 'apiBaseURL' => 'https://comanage.example.org/registry',
* 'username' => 'bob',
* 'password' => 'secret',
* 'userIdAttribute => 'eduPersonUniqueId',
* 'userIdAttribute => 'eduPersonUniqueId',
* 'urnNamespace' => 'urn:mace:example.org',
* ),
* ],
*
* @author Nicolas Liampotis <[email protected]>
*/
class sspmod_attrauthcomanage_Auth_Process_COmanageRestClient extends SimpleSAML_Auth_ProcessingFilter
namespace SimpleSAML\Module\attrauthcomanage\Auth\Process;

use SimpleSAML\Auth\ProcessingFilter;
use SimpleSAML\Configuration;
use SimpleSAML\Error;
use SimpleSAML\Logger;
use SimpleSAML\XHTML\Template;

class COmanageRestClient extends SimpleSAML\Auth\ProcessingFilter
{
private $_apiBaseURL;

Expand All @@ -43,75 +51,75 @@ public function __construct($config, $reserved)
assert('is_array($config)');

if (!array_key_exists('apiBaseURL', $config)) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'apiBaseURL' not specified");
throw new SimpleSAML_Error_Exception(
"attrauthcomanage configuration error: 'apiBaseURL' not specified");
throw new Errorxception(
"attrauthcomanage configuration error: 'apiBaseURL' not specified");
}
if (!is_string($config['apiBaseURL'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'apiBaseURL' not a string literal");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'apiBaseURL' not a string literal");
}
$this->_apiBaseURL = $config['apiBaseURL'];
$this->_apiBaseURL = $config['apiBaseURL'];

if (!array_key_exists('username', $config)) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'username' not specified");
throw new SimpleSAML_Error_Exception(
"attrauthcomanage configuration error: 'username' not specified");
throw new Error\Exception(
"attrauthcomanage configuration error: 'username' not specified");
}
if (!is_string($config['username'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'username' not a string literal");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'username' not a string literal");
}
$this->_username = $config['username'];

if (!array_key_exists('password', $config)) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'password' not specified");
throw new SimpleSAML_Error_Exception(
"attrauthcomanage configuration error: 'password' not specified");
throw new Error\Exception(
"attrauthcomanage configuration error: 'password' not specified");
}
if (!is_string($config['password'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'password' not a string literal");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'password' not a string literal");
}
$this->_password = $config['password'];
$this->_password = $config['password'];

if (array_key_exists('userIdAttribute', $config)) {
if (!is_string($config['userIdAttribute'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'userIdAttribute' not a string literal");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'userIdAttribute' not a string literal");
}
$this->_userIdAttribute = $config['userIdAttribute'];
$this->_userIdAttribute = $config['userIdAttribute'];
}

if (array_key_exists('verifyPeer', $config)) {
if (!is_bool($config['verifyPeer'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'verifyPeer' not a boolean");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'verifyPeer' not a boolean");
}
$this->_verifyPeer = $config['verifyPeer'];
$this->_verifyPeer = $config['verifyPeer'];
}

if (array_key_exists('urnNamespace', $config)) {
if (!is_string($config['urnNamespace'])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'urnNamespace' not a string literal");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'urnNamespace' not a string literal");
}
$this->_urnNamespace = $config['urnNamespace'];
$this->_urnNamespace = $config['urnNamespace'];
}
}

Expand All @@ -120,75 +128,75 @@ public function process(&$state)
try {
assert('is_array($state)');
if (empty($state['Attributes'][$this->_userIdAttribute])) {
SimpleSAML_Logger::error(
Logger::error(
"[attrauthcomanage] Configuration error: 'userIdAttribute' not available");
throw new SimpleSAML_Error_Exception(
throw new Error\Exception(
"attrauthcomanage configuration error: 'userIdAttribute' not available");
}
$identifier = $state['Attributes'][$this->_userIdAttribute][0];
$orgIdentities = $this->_getOrgIdentities($identifier);
SimpleSAML_Logger::debug(
"[attrauthcomanage] process: orgIdentities="
Logger::debug(
"[attrauthcomanage] process: orgIdentities="
. var_export($orgIdentities, true));
if (empty($orgIdentities)) {
return;
}
$coOrgIdentityLinks = array();
$coOrgIdentityLinks = [];
foreach ($orgIdentities as $orgIdentity) {
if (!$orgIdentity->{'Deleted'}) {
$coOrgIdentityLinks = array_merge($coOrgIdentityLinks,
$this->_getCoOrgIdentityLinks($orgIdentity->{'Id'}));
$coOrgIdentityLinks = array_merge($coOrgIdentityLinks,
$this->_getCoOrgIdentityLinks($orgIdentity->{'Id'}));
}
}
SimpleSAML_Logger::debug(
"[attrauthcomanage] process: coOrgIdentityLinks="
Logger::debug(
"[attrauthcomanage] process: coOrgIdentityLinks="
. var_export($coOrgIdentityLinks, true));
if (empty($coOrgIdentityLinks)) {
return;
}
$coGroups = array();
$coGroups = [];
foreach ($coOrgIdentityLinks as $coOrgIdentityLink) {
if (!$coOrgIdentityLink->{'Deleted'}) {
$coGroups = array_merge($coGroups,
$this->_getCoGroups($coOrgIdentityLink->{'CoPersonId'}));
$this->_getCoGroups($coOrgIdentityLink->{'CoPersonId'}));
}
}
SimpleSAML_Logger::debug(
"[attrauthcomanage] process: coGroups="
Logger::debug(
"[attrauthcomanage] process: coGroups="
. var_export($coGroups, true));
if (empty($coGroups)) {
return;
}
$coGroupMemberships = array();
$coGroupMemberships = [];
foreach ($coGroups as $coGroup) {
if ($coGroup->{'Status'} === 'Active' && !$coGroup->{'Deleted'}) {
$co = $this->_getCo($coGroup->{'CoId'});
// CO name should always be available.
// However, if for some reason this is not the case, we
// However, if for some reason this is not the case, we
// currently resort to using the CO numeric ID.
// TODO Consider throwing exception?
if (empty($co)) {
$coName = $coGroup->{'CoId'};
} else {
$coName = $co->{'Name'};
}
$coGroupMemberships[] = array(
'groupName' => $coGroup->{'Name'},
'coName' => $coName,
);
}
$coGroupMemberships[] = [
'groupName' => $coGroup->{'Name'},
'coName' => $coName,
];
}
}
SimpleSAML_Logger::debug(
"[attrauthcomanage] process: coGroupMemberships="
Logger::debug(
"[attrauthcomanage] process: coGroupMemberships="
. var_export($coGroupMemberships, true));
if (empty($coGroupMemberships)) {
return;
}
if (!array_key_exists('eduPersonEntitlement', $state['Attributes'])) {
$state['Attributes']['eduPersonEntitlement'] = array();
$state['Attributes']['eduPersonEntitlement'] = [];
}
foreach ($coGroupMemberships as $coGroupMembership) {
$state['Attributes']['eduPersonEntitlement'][] =
$state['Attributes']['eduPersonEntitlement'][] =
$this->_urnNamespace . ":"
. $coGroupMembership['groupName'] . ":" . "member"
. "@" . $coGroupMembership['coName'];
Expand All @@ -200,7 +208,7 @@ public function process(&$state)

private function _getOrgIdentities($identifier)
{
SimpleSAML_Logger::debug("[attrauthcomanage] _getOrgIdentities: identifier="
Logger::debug("[attrauthcomanage] _getOrgIdentities: identifier="
. var_export($identifier, true));

// Construct COmanage REST API URL
Expand All @@ -209,55 +217,55 @@ private function _getOrgIdentities($identifier)
//. "coid=" . $this->_coId . "&"
. "search.identifier=" . urlencode($identifier);
$data = $this->_http('GET', $url);
assert('strncmp($data->{"ResponseType"}, "OrgIdentities", 13)===0');
assert('strncmp($data->{"ResponseType"}, "OrgIdentities", 13)===0');
if (empty($data->{'OrgIdentities'})) {
return array();
return [];
}
return $data->{'OrgIdentities'};
}

private function _getCoOrgIdentityLinks($orgIdentityId)
{
SimpleSAML_Logger::debug("[attrauthcomanage] _getCoOrgIdentityLinks: orgIdentityId="
Logger::debug("[attrauthcomanage] _getCoOrgIdentityLinks: orgIdentityId="
. var_export($orgIdentityId, true));

// Construct COmanage REST API URL
$url = $this->_apiBaseURL . "/co_org_identity_links.json?orgidentityid="
. urlencode($orgIdentityId);
$data = $this->_http('GET', $url);
assert('strncmp($data->{"ResponseType"}, "CoOrgIdentityLinks", 18)===0');
assert('strncmp($data->{"ResponseType"}, "CoOrgIdentityLinks", 18)===0');
if (empty($data->{'CoOrgIdentityLinks'})) {
return array();
return [];
}
return $data->{'CoOrgIdentityLinks'};
}

private function _getCoGroups($coPersonId)
{
SimpleSAML_Logger::debug("[attrauthcomanage] _getCoGroups: coPersonId="
Logger::debug("[attrauthcomanage] _getCoGroups: coPersonId="
. var_export($coPersonId, true));

// Construct COmanage REST API URL
$url = $this->_apiBaseURL . "/co_groups.json?"
. "copersonid=" . urlencode($coPersonId);
$data = $this->_http('GET', $url);
assert('strncmp($data->{"ResponseType"}, "CoGroups", 8)===0');
assert('strncmp($data->{"ResponseType"}, "CoGroups", 8)===0');
if (empty($data->{'CoGroups'})) {
return array();
return [];
}
return $data->{'CoGroups'};
}

private function _getCo($coId)
{
SimpleSAML_Logger::debug("[attrauthcomanage] _getCo: coId="
Logger::debug("[attrauthcomanage] _getCo: coId="
. var_export($coId, true));

// Construct COmanage REST API URL
$url = $this->_apiBaseURL . "/cos/"
. urlencode($coId) . ".json";
$data = $this->_http('GET', $url);
assert('strncmp($data->{"ResponseType"}, "Cos", 3)===0');
assert('strncmp($data->{"ResponseType"}, "Cos", 3)===0');
if (empty($data->{'Cos'})) {
return null;
}
Expand All @@ -266,18 +274,18 @@ private function _getCo($coId)

private function _http($method, $url)
{
SimpleSAML_Logger::debug("[attrauthcomanage] http: method="
Logger::debug("[attrauthcomanage] http: method="
. var_export($method, true) . ", url=" . var_export($url, true));
$ch = curl_init($url);
curl_setopt_array(
$ch,
array(
[
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $this->_username . ":" . $this->_password,
CURLOPT_SSL_VERIFYPEER => $this->_verifyPeer,
)
]
);

// Send the request
Expand All @@ -286,21 +294,21 @@ private function _http($method, $url)

// Check for error; not even redirects are allowed here
if ($http_response !== 200) {
SimpleSAML_Logger::error("[attrauthcomanage] API query failed: HTTP response code: "
Logger::error("[attrauthcomanage] API query failed: HTTP response code: "
. $http_response . ", error message: '" . curl_error($ch)) . "'";
throw new SimpleSAML_Error_Exception("Failed to communicate with COmanage Registry");
throw new Error\Exception("Failed to communicate with COmanage Registry");
}
$data = json_decode($response);
SimpleSAML_Logger::debug("[attrauthcomanage] http: data="
Logger::debug("[attrauthcomanage] http: data="
. var_export($data, true));
assert('json_last_error()===JSON_ERROR_NONE');
assert('json_last_error()===JSON_ERROR_NONE');
return $data;
}

private function _showException($e)
{
$globalConfig = SimpleSAML_Configuration::getInstance();
$t = new SimpleSAML_XHTML_Template($globalConfig, 'attrauthcomanage:exception.tpl.php');
$globalConfig = Configuration::getInstance();
$t = new Template($globalConfig, 'attrauthcomanage:exception.tpl.php');
$t->data['e'] = $e->getMessage();
$t->show();
exit();
Expand Down

0 comments on commit 6271aaa

Please sign in to comment.