diff options
author | Sixto Martin <smartin@yaco.es> | 2013-08-02 16:41:43 +0400 |
---|---|---|
committer | Sixto Martin <smartin@yaco.es> | 2013-08-02 16:41:43 +0400 |
commit | 10fba4b7ae1fa3426b62af23be6622bccdf1b5af (patch) | |
tree | 75ee3a8bb8c991fe3fb109ad314174dc29b93412 /user_saml | |
parent | ebf6104f1208a4d751d38a103c4c4254e19eda85 (diff) | |
parent | efbbdbe29ed024dc1cddea4d8f484c870725d81e (diff) |
Merge pull request #1283 from pitbulk/master
Release of user_saml 0.4 and user_cas 0.1.1
Diffstat (limited to 'user_saml')
-rw-r--r-- | user_saml/CHANGELOG.txt | 10 | ||||
-rw-r--r-- | user_saml/README.md | 13 | ||||
-rw-r--r-- | user_saml/appinfo/app.php | 24 | ||||
-rw-r--r-- | user_saml/appinfo/info.xml | 2 | ||||
-rw-r--r-- | user_saml/appinfo/version | 2 | ||||
-rw-r--r-- | user_saml/auth.php | 2 | ||||
-rw-r--r-- | user_saml/css/saml.css | 13 | ||||
-rw-r--r-- | user_saml/lib/hooks.php | 72 | ||||
-rw-r--r-- | user_saml/settings.php | 7 | ||||
-rw-r--r-- | user_saml/templates/settings.php | 5 | ||||
-rw-r--r-- | user_saml/user_saml.php | 37 |
11 files changed, 136 insertions, 51 deletions
diff --git a/user_saml/CHANGELOG.txt b/user_saml/CHANGELOG.txt index da5fffd9f..b39d6ce51 100644 --- a/user_saml/CHANGELOG.txt +++ b/user_saml/CHANGELOG.txt @@ -1,6 +1,16 @@ CHANGELOG ========= +Version 0.4 (Tested with OwnCloud 5.0.8) +---------------------------------------- + +* Add csrf protection on setting form +* Add a config param to force the saml login +* Use openssl_random_pseudo_bytes instead of mt_rand (if available) +* Support displayName +* Support multiple values for mapping username, groups, mail and displayName + + Version 0.3 (Tested with OwnCloud 4.5.2) ---------------------------------------- diff --git a/user_saml/README.md b/user_saml/README.md index 202ea579e..a746da9b4 100644 --- a/user_saml/README.md +++ b/user_saml/README.md @@ -20,7 +20,7 @@ To learn how to do this check this documentation: STEPS ----- -1. Copy the 'user_saml' folder inside the ownCloud's apps folder and give to apache server privileges on whole the folder. +1. Copy the `user_saml` folder inside the ownCloud's apps folder and give to apache server privileges on whole the folder. 2. Access to ownCloud web with an user with admin privileges. 3. Access to the Appications pannel and enable the SAML app. 4. Access to the Administration pannel and configure the SAML app. @@ -41,8 +41,17 @@ EXTRA INFO the value of the defaultGroup field will be used instead. If both are undefined, then the user will be set with no groups. But if you configure the "protected groups" field, those groups will not be unlinked from the user. +* If you want to redirect to any specific app after force the login you can set the url param linktoapp. Also you can pass extra args to build the target url using the param linktoargs (the value must be urlencoded). + Ex. ?app=user_saml&linktoapp=files&linktoargs=file%3d%2ftest%2ftest_file.txt%26getfile%3ddownload.php + ?app=user_saml&linktoapp=files&linktoargs=dir%3d%2ftest + +* There is a parameter in the settings named `force_saml_login` to avoid the login form, redirecting directly to the IdP when accesing owncloud. + If you are an admin and you want to log in using the login form, then use the GET param `admin_login` to deactivate the forced redirection. NOTES ===== -If you had an older version of this plugin installed and the SAML link no appears at the main view, edit the index.php and set the $RUNTIME_NOAPPS to FALSE; +If you had an older version of this plugin installed and the SAML link no appears at the main view, edit the index.php and set the $RUNTIME_NOAPPS to FALSE; + + + diff --git a/user_saml/appinfo/app.php b/user_saml/appinfo/app.php index 2bb6e9d42..6a26bbe91 100644 --- a/user_saml/appinfo/app.php +++ b/user_saml/appinfo/app.php @@ -23,6 +23,14 @@ if (OCP\App::isEnabled('user_saml')) { + $ocVersion = implode('.',OCP\Util::getVersion()); + if (version_compare($ocVersion,'5.0','<')) { + if ( ! function_exists('p')) { + function p($string) { + print(OC_Util::sanitizeHTML($string)); + } + } + } require_once 'user_saml/user_saml.php'; @@ -35,7 +43,9 @@ if (OCP\App::isEnabled('user_saml')) { OCP\Util::connectHook('OC_User', 'post_login', 'OC_USER_SAML_Hooks', 'post_login'); OCP\Util::connectHook('OC_User', 'logout', 'OC_USER_SAML_Hooks', 'logout'); - if( isset($_GET['app']) && $_GET['app'] == 'user_saml' ) { + $forceLogin = OCP\Config::getAppValue('user_saml', 'saml_force_saml_login', false); + + if( (isset($_GET['app']) && $_GET['app'] == 'user_saml') || (!OCP\User::isLoggedIn() && $forceLogin && !isset($_GET['admin_login']) )) { require_once 'user_saml/auth.php'; @@ -44,18 +54,20 @@ if (OCP\App::isEnabled('user_saml')) { OC_Log::write('saml','Error trying to authenticate the user', OC_Log::DEBUG); } - if (isset($_SERVER["QUERY_STRING"]) && !empty($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] != 'app=user_saml') { - header( 'Location: ' . OC::$WEBROOT . '/?' . $_SERVER["QUERY_STRING"]); + if (isset($_GET["linktoapp"])) { + $path = OC::$WEBROOT . '/?app='.$_GET["linktoapp"]; + if (isset($_GET["linktoargs"])) { + $path .= '&'.urldecode($_GET["linktoargs"]); + } + header( 'Location: ' . $path); exit(); } - OC::$REQUESTEDAPP = ''; + OC::$REQUESTEDAPP = ''; OC_Util::redirectToDefaultPage(); } - if (!OCP\User::isLoggedIn()) { - // Load js code in order to render the SAML link and to hide parts of the normal login form OCP\Util::addScript('user_saml', 'utils'); } diff --git a/user_saml/appinfo/info.xml b/user_saml/appinfo/info.xml index ac5b8ba4c..4d786cc97 100644 --- a/user_saml/appinfo/info.xml +++ b/user_saml/appinfo/info.xml @@ -5,7 +5,7 @@ <description>Authenticate Users by SAML</description> <licence>AGPL</licence> <author>Sixto Martin @ Yaco Sistemas</author> - <require>4.93</require> + <require>5</require> <types> <prelogin/> <authentication/> diff --git a/user_saml/appinfo/version b/user_saml/appinfo/version index be5863417..bd73f4707 100644 --- a/user_saml/appinfo/version +++ b/user_saml/appinfo/version @@ -1 +1 @@ -0.3 +0.4 diff --git a/user_saml/auth.php b/user_saml/auth.php index 641c975be..d99b4c123 100644 --- a/user_saml/auth.php +++ b/user_saml/auth.php @@ -21,6 +21,8 @@ * */ + OCP\App::checkAppEnabled('user_saml'); + $sspPath = OCP\Config::getAppValue('user_saml', 'saml_ssp_path', ''); $spSource = OCP\Config::getAppValue('user_saml', 'saml_sp_source', ''); $autocreate = OCP\Config::getAppValue('user_saml', 'saml_autocreate', false); diff --git a/user_saml/css/saml.css b/user_saml/css/saml.css index 8ac94c007..020ed003b 100644 --- a/user_saml/css/saml.css +++ b/user_saml/css/saml.css @@ -9,9 +9,18 @@ #samlSettings input[type="text"] { margin-left: 15px; - width: 15em; + width: 25em; } #samlSettings input[name="saml_ssp_path"] { - width: 20em; + width: 30em; +} + +#samlSettings input[name="saml_sp_source"] { + width: 15em; } + +#samlSettings input[name="saml_default_group"] { + width: 15em; +} + diff --git a/user_saml/lib/hooks.php b/user_saml/lib/hooks.php index a129f510f..20e0461e9 100644 --- a/user_saml/lib/hooks.php +++ b/user_saml/lib/hooks.php @@ -26,24 +26,49 @@ class OC_USER_SAML_Hooks { static public function post_login($parameters) { - $uid = $parameters['uid']; + $userid = $parameters['uid']; $samlBackend = new OC_USER_SAML(); if ($samlBackend->auth->isAuthenticated()) { $attributes = $samlBackend->auth->getAttributes(); - if (array_key_exists($samlBackend->usernameMapping, $attributes) && $attributes[$samlBackend->usernameMapping][0] == $uid) { + $usernameFound = false; + foreach($samlBackend->usernameMapping as $usernameMapping) { + if (array_key_exists($usernameMapping, $attributes) && !empty($attributes[$usernameMapping][0])) { + $usernameFound = true; + $uid = $attributes[$usernameMapping][0]; + OC_Log::write('saml','Authenticated user '.$uid,OC_Log::DEBUG); + break; + } + } + + if ($usernameFound && $uid == $userid) { $attributes = $samlBackend->auth->getAttributes(); - if (array_key_exists($samlBackend->mailMapping, $attributes)) { - $saml_email = $attributes[$samlBackend->mailMapping][0]; + $saml_email = ''; + foreach ($samlBackend->mailMapping as $mailMapping) { + if (array_key_exists($mailMapping, $attributes) && !empty($attributes[$mailMapping][0])) { + $saml_email = $attributes[$mailMapping][0]; + break; + } + } + + $saml_display_name = ''; + foreach ($samlBackend->displayNameMapping as $displayNameMapping) { + if (array_key_exists($displayNameMapping, $attributes) && !empty($attributes[$displayNameMapping][0])) { + $saml_display_name = $attributes[$displayNameMapping][0]; + break; + } } - if (array_key_exists($samlBackend->groupMapping, $attributes)) { - $saml_groups = $attributes[$samlBackend->groupMapping]; + $saml_groups = array(); + foreach ($samlBackend->groupMapping as $groupMapping) { + if (array_key_exists($groupMapping, $attributes) && !empty($attributes[$groupMapping])) { + $saml_groups = array_merge($saml_groups, $attributes[$groupMapping]); + } } - else if (!empty($samlBackend->defaultGroup)) { + if (empty($saml_groups) && !empty($samlBackend->defaultGroup)) { $saml_groups = array($samlBackend->defaultGroup); OC_Log::write('saml','Using default group "'.$samlBackend->defaultGroup.'" for the user: '.$uid, OC_Log::DEBUG); } @@ -54,23 +79,26 @@ class OC_USER_SAML_Hooks { return false; } else { - $random_password = random_password(); + $random_password = OC_Util::generate_random_bytes(20); OC_Log::write('saml','Creating new user: '.$uid, OC_Log::DEBUG); OC_User::createUser($uid, $random_password); - if(OC_User::userExists($uid)) { + OC_Util::setupFS($uid); if (isset($saml_email)) { update_mail($uid, $saml_email); - } if (isset($saml_groups)) { update_groups($uid, $saml_groups, $samlBackend->protectedGroups, true); } + if (isset($saml_display_name)) { + update_display_name($uid, $saml_display_name); + } } } } else { if ($samlBackend->updateUserData) { + OC_Util::setupFS($uid); OC_Log::write('saml','Updating data of the user: '.$uid,OC_Log::DEBUG); if(isset($saml_email)) { update_mail($uid, $saml_email); @@ -78,6 +106,9 @@ class OC_USER_SAML_Hooks { if (isset($saml_groups)) { update_groups($uid, $saml_groups, $samlBackend->protectedGroups, false); } + if (isset($saml_display_name)) { + update_display_name($uid, $saml_display_name); + } } } return true; @@ -90,7 +121,7 @@ class OC_USER_SAML_Hooks { static public function logout($parameters) { $samlBackend = new OC_USER_SAML(); if ($samlBackend->auth->isAuthenticated()) { - OC_Log::write('saml','Executing SAML logout: '.$parameters['uid'],OC_Log::DEBUG); + OC_Log::write('saml', 'Executing SAML logout', OC_Log::DEBUG); $samlBackend->auth->logout(); } return true; @@ -107,12 +138,12 @@ function update_mail($uid, $email) { } -function update_groups($uid, $groups, $protected_groups=array(), $just_created=false) { +function update_groups($uid, $groups, $protectedGroups=array(), $just_created=false) { if(!$just_created) { $old_groups = OC_Group::getUserGroups($uid); foreach($old_groups as $group) { - if(!in_array($group, $protected_groups) && !in_array($group, $groups)) { + if(!in_array($group, $protectedGroups) && !in_array($group, $groups)) { OC_Group::removeFromGroup($uid,$group); OC_Log::write('saml','Removed "'.$uid.'" from the group "'.$group.'"', OC_Log::DEBUG); } @@ -136,17 +167,6 @@ function update_groups($uid, $groups, $protected_groups=array(), $just_created=f } } - -function random_password() -{ - $valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - $length = 20; - $num_valid_chars = strlen($valid_chars); - - for ($i = 0; $i < $length; $i++) { - $random_pick = mt_rand(1, $num_valid_chars); - $random_char = $valid_chars[$random_pick-1]; - $random_string .= $random_char; - } - return $random_string; +function update_display_name($uid, $displayName) { + OC_User::setDisplayName($uid, $displayName); } diff --git a/user_saml/settings.php b/user_saml/settings.php index 5d930e251..d0b393f75 100644 --- a/user_saml/settings.php +++ b/user_saml/settings.php @@ -23,11 +23,14 @@ OC_Util::checkAdminUser(); -$params = array('saml_ssp_path', 'saml_sp_source', 'saml_autocreate', 'saml_update_user_data', 'saml_protected_groups', 'saml_default_group', 'saml_username_mapping', 'saml_email_mapping', 'saml_group_mapping'); +$params = array('saml_ssp_path', 'saml_sp_source', 'saml_force_saml_login', 'saml_autocreate', 'saml_update_user_data', 'saml_protected_groups', 'saml_default_group', 'saml_username_mapping', 'saml_email_mapping', 'saml_displayname_mapping', 'saml_group_mapping'); OCP\Util::addscript('user_saml', 'settings'); if ($_POST) { + // CSRF check + OCP\JSON::callCheck(); + foreach($params as $param) { if (isset($_POST[$param])) { OCP\Config::setAppValue('user_saml', $param, $_POST[$param]); @@ -52,12 +55,14 @@ foreach ($params as $param) { // settings with default values $tmpl->assign( 'saml_ssp_path', OCP\Config::getAppValue('user_saml', 'saml_ssp_path', '/var/www/sp/simplesamlphp')); $tmpl->assign( 'saml_sp_source', OCP\Config::getAppValue('user_saml', 'saml_sp_source', 'default-sp')); +$tmpl->assign( 'saml_force_saml_login', OCP\Config::getAppValue('user_saml', 'saml_force_saml_login', 0)); $tmpl->assign( 'saml_autocreate', OCP\Config::getAppValue('user_saml', 'saml_autocreate', 0)); $tmpl->assign( 'saml_update_user_data', OCP\Config::getAppValue('user_saml', 'saml_update_user_data', 0)); $tmpl->assign( 'saml_protected_groups', OCP\Config::getAppValue('user_saml', 'saml_protected_groups', '')); $tmpl->assign( 'saml_default_group', OCP\Config::getAppValue('user_saml', 'saml_default_group', '')); $tmpl->assign( 'saml_username_mapping', OCP\Config::getAppValue('user_saml', 'saml_username_mapping', 'uid')); $tmpl->assign( 'saml_email_mapping', OCP\Config::getAppValue('user_saml', 'saml_email_mapping', 'mail')); +$tmpl->assign( 'saml_displayname_mapping', OCP\Config::getAppValue('user_saml', 'saml_displayname_mapping', 'displayName')); $tmpl->assign( 'saml_group_mapping', OCP\Config::getAppValue('user_saml', 'saml_group_mapping', '')); return $tmpl->fetchPage(); diff --git a/user_saml/templates/settings.php b/user_saml/templates/settings.php index 9e1674488..5aad114e5 100644 --- a/user_saml/templates/settings.php +++ b/user_saml/templates/settings.php @@ -11,16 +11,19 @@ <fieldset id="samlSettings-1"> <p><label for="saml_ssp_path"><?php p($l->t('SimpleSAMLphp path'));?></label><input type="text" id="saml_ssp_path" name="saml_ssp_path" value="<?php p($_['saml_ssp_path']); ?>"></p> <p><label for="saml_sp_source"><?php p($l->t('SimpleSAMLphp SP source'));?></label><input type="text" id="saml_sp_source" name="saml_sp_source" value="<?php p($_['saml_sp_source']); ?>"></p> + <p><label for="saml_force_saml_login"><?php p($l->t('Force SAML login?'));?></label><input type="checkbox" id="saml_force_saml_login" name="saml_force_saml_login" <?php p((($_['saml_force_saml_login'] != false) ? 'checked="checked"' : '')); ?>></p> <p><label for="saml_autocreate"><?php p($l->t('Autocreate user after saml login?'));?></label><input type="checkbox" id="saml_autocreate" name="saml_autocreate" <?php p((($_['saml_autocreate'] != false) ? 'checked="checked"' : '')); ?>></p> <p><label for="saml_update_user_data"><?php p($l->t('Update user data after login?'));?></label><input type="checkbox" id="saml_update_user_data" name="saml_update_user_data" <?php p((($_['saml_update_user_data'] != false) ? 'checked="checked"' : '')); ?>></p> - <p><label for="saml_protected_groups"><?php p($l->t('Groups that will not be unlinked from the user when sync the IdP and the owncloud'));?></label><input type="text" id="saml_protected_groups" name="saml_protected_groups" value="<?php p($_['saml_protected_groups']); ?>" /></p> <?php p($l->t('(protected grop are multivalued, use comma to separate the values)')); ?> + <p><label for="saml_protected_groups"><?php p($l->t('Groups that will not be unlinked from the user when sync the IdP and the owncloud'));?></label><input type="text" id="saml_protected_groups" name="saml_protected_groups" value="<?php p($_['saml_protected_groups']); ?>" /></p> <?php p($l->t('(protected group are multivalued, use comma to separate the values)')); ?> <p><label for="saml_default_group"><?php p($l->t('Default group when autocreating users and not group data found for the user'));?></label><input type="text" id="saml_default_group" name="saml_default_group" value="<?php p($_['saml_default_group']); ?>"></p> </fieldset> <fieldset id="samlSettings-2"> <p><label for="saml_username_mapping"><?php p($l->t('Username'));?></label><input type="text" id="saml_username_mapping" name="saml_username_mapping" value="<?php p($_['saml_username_mapping']); ?>" /></p> <p><label for="saml_email_mapping"><?php p($l->t('Email'));?></label><input type="text" id="saml_email_mapping" name="saml_email_mapping" value="<?php p($_['saml_email_mapping']); ?>" /></p> + <p><label for="saml_displayname_mapping"><?php p($l->t('DisplayName'));?></label><input type="text" id="saml_displayname_mapping" name="saml_displayname_mapping" value="<?php p($_['saml_displayname_mapping']); ?>" /></p> <p><label for="saml_group_mapping"><?php p($l->t('Group'));?></label><input type="text" id="saml_group_mapping" name="saml_group_mapping" value="<?php p($_['saml_group_mapping']); ?>" /></p> </fieldset> + <input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken"> <input type="submit" value="Save" /> </div> diff --git a/user_saml/user_saml.php b/user_saml/user_saml.php index b014ec9ab..af5b5d68d 100644 --- a/user_saml/user_saml.php +++ b/user_saml/user_saml.php @@ -26,12 +26,14 @@ class OC_USER_SAML extends OC_User_Backend { // cached settings protected $sspPath; protected $spSource; + public $forceLogin; public $autocreate; public $updateUserData; public $protectedGroups; public $defaultGroup; public $usernameMapping; public $mailMapping; + public $displayNameMapping; public $groupMapping; public $auth; @@ -39,18 +41,26 @@ class OC_USER_SAML extends OC_User_Backend { public function __construct() { $this->sspPath = OCP\Config::getAppValue('user_saml', 'saml_ssp_path', ''); $this->spSource = OCP\Config::getAppValue('user_saml', 'saml_sp_source', ''); + $this->forceLogin = OCP\Config::getAppValue('user_saml', 'saml_force_saml_login', false); $this->autocreate = OCP\Config::getAppValue('user_saml', 'saml_autocreate', false); $this->updateUserData = OCP\Config::getAppValue('user_saml', 'saml_update_user_data', false); $this->defaultGroup = OCP\Config::getAppValue('user_saml', 'saml_default_group', ''); - $this->protectedGroups = explode (',', str_replace(' ', '', OCP\Config::getAppValue('user_saml', 'saml_protected_groups', ''))); - $this->usernameMapping = OCP\Config::getAppValue('user_saml', 'saml_username_mapping', ''); - $this->mailMapping = OCP\Config::getAppValue('user_saml', 'saml_email_mapping', ''); - $this->groupMapping = OCP\Config::getAppValue('user_saml', 'saml_group_mapping', ''); + $this->protectedGroups = explode (',', preg_replace('/\s+/', '', OCP\Config::getAppValue('user_saml', 'saml_protected_groups', ''))); + $this->usernameMapping = explode (',', preg_replace('/\s+/', '', OCP\Config::getAppValue('user_saml', 'saml_username_mapping', ''))); + $this->mailMapping = explode (',', preg_replace('/\s+/', '', OCP\Config::getAppValue('user_saml', 'saml_email_mapping', ''))); + $this->displayNameMapping = explode (',', preg_replace('/\s+/', '', OCP\Config::getAppValue('user_saml', 'saml_displayname_mapping', ''))); + $this->groupMapping = explode (',', preg_replace('/\s+/', '', OCP\Config::getAppValue('user_saml', 'saml_group_mapping', ''))); if (!empty($this->sspPath) && !empty($this->spSource)) { include_once $this->sspPath."/lib/_autoload.php"; $this->auth = new SimpleSAML_Auth_Simple($this->spSource); + + if (isset($_COOKIE["user_saml_logged_in"]) AND $_COOKIE["user_saml_logged_in"] AND !$this->auth->isAuthenticated()) { + unset($_COOKIE["user_saml_logged_in"]); + setcookie("user_saml_logged_in", null, -1); + OCP\User::logout(); + } } } @@ -63,14 +73,19 @@ class OC_USER_SAML extends OC_User_Backend { $attributes = $this->auth->getAttributes(); - if (array_key_exists($this->usernameMapping, $attributes)) { - $uid = $attributes[$this->usernameMapping][0]; - OC_Log::write('saml','Authenticated user '.$uid,OC_Log::DEBUG); - } - else { - OC_Log::write('saml','Not found attribute used to get the username ("'.$this->usernameMapping.'") at the requested saml attribute assertion',OC_Log::DEBUG); + foreach($this->usernameMapping as $usernameMapping) { + if (array_key_exists($usernameMapping, $attributes) && !empty($attributes[$usernameMapping][0])) { + $uid = $attributes[$usernameMapping][0]; + OC_Log::write('saml','Authenticated user '.$uid,OC_Log::DEBUG); + return $uid; + } } - return $uid; + OC_Log::write('saml','Not found attribute used to get the username at the requested saml attribute assertion',OC_Log::DEBUG); + $secure_cookie = OC_Config::getValue("forcessl", false); + $expires = time() + OC_Config::getValue('remember_login_cookie_lifetime', 60*60*24*15); + setcookie("user_saml_logged_in", "1", $expires, '', '', $secure_cookie); + + return false; } } |