From e1fde296c6d1e93e055121387e027412e0328b71 Mon Sep 17 00:00:00 2001 From: Lutz Freitag Date: Sun, 24 Feb 2019 18:04:30 -0500 Subject: [PATCH 1/3] added an authentication handler for external HTTP basic auth Signed-off-by: Lutz Freitag --- appinfo/app.php | 1 + lib/basicauth.php | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 lib/basicauth.php diff --git a/appinfo/app.php b/appinfo/app.php index b7ae102..f503578 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -2,3 +2,4 @@ OC::$CLASSPATH['OC_User_IMAP']='user_external/lib/imap.php'; OC::$CLASSPATH['OC_User_SMB']='user_external/lib/smb.php'; OC::$CLASSPATH['OC_User_FTP']='user_external/lib/ftp.php'; +OC::$CLASSPATH['OC_User_BasicAuth']='user_external/lib/basicauth.php'; diff --git a/lib/basicauth.php b/lib/basicauth.php new file mode 100644 index 0000000..d8f7acc --- /dev/null +++ b/lib/basicauth.php @@ -0,0 +1,51 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class OC_User_BasicAuth extends \OCA\user_external\Base { + + private $authUrl; + + public function __construct($authUrl) { + parent::__construct($authUrl); + $this->authUrl =$authUrl; + } + + /** + * Check if the password is correct without logging in the user + * + * @param string $uid The username + * @param string $password The password + * + * @return true/false + */ + public function checkPassword($uid, $password) { + stream_context_set_default(array( + 'http'=>array( + 'method'=>"GET", + 'header' => "authorization: Basic " . base64_encode("$uid:$password") + )) + ); + $headers = get_headers($this->authUrl); + + if($headers === false) { + OC::$server->getLogger()->error( + 'ERROR: Not possible to connect to BasicAuth Url: "'.$this->authUrl.'"', + ['app' => 'user_external'] + ); + return false; + } + + $returnCode= substr($headers[0], 9, 3); + if(substr($returnCode, 0, 1) === '2') { + $this->storeUser($uid); + return $uid; + } else { + return false; + } + } +} From 71eb09546b4d31326bc049149e8f3bef930f0136 Mon Sep 17 00:00:00 2001 From: Lutz Freitag Date: Sun, 24 Feb 2019 18:27:08 -0500 Subject: [PATCH 2/3] added some README text to describe the basic auth feature Signed-off-by: Lutz Freitag --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 377319d..5d2510f 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,27 @@ Add the following to your `config.php`: ), +BasicAuth +------ + +Authenticate users by an [HTTP Basic access authentication][1] call. +HTTP server of your choice to authenticate. It should return HTTP 2xx for correct credentials and an appropriate other error code for wrong ones or refused access. + +### Configuration +The only supported parameter is the URL of the web server where the authentication happens. + +Add the following to your `config.php`: + + 'user_backends' => array( + array( + 'class' => '\OCA\User_External\BasicAuth', + 'arguments' => array('https://example.com/basic_auth'), + ), + ), + + +[1]: https://en.wikipedia.org/wiki/Basic_access_authentication + Alternatives ------------ Other extensions allow connecting to external user databases directly via SQL, which may be faster: From 9be32d66a6ffc456532177fc9d6f2a0e4d734c26 Mon Sep 17 00:00:00 2001 From: Lutz Freitag Date: Sun, 24 Feb 2019 18:33:01 -0500 Subject: [PATCH 3/3] added a TestCase for basic auth Signed-off-by: Lutz Freitag --- README.md | 2 +- lib/basicauth.php | 4 ++-- tests/basic_auth.php | 35 +++++++++++++++++++++++++++++++++++ tests/config.php | 6 ++++++ 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tests/basic_auth.php diff --git a/README.md b/README.md index 5d2510f..704522d 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ Add the following to your `config.php`: 'user_backends' => array( array( - 'class' => '\OCA\User_External\BasicAuth', + 'class' => 'OC_User_BasicAuth', 'arguments' => array('https://example.com/basic_auth'), ), ), diff --git a/lib/basicauth.php b/lib/basicauth.php index d8f7acc..2427ea1 100644 --- a/lib/basicauth.php +++ b/lib/basicauth.php @@ -32,9 +32,9 @@ class OC_User_BasicAuth extends \OCA\user_external\Base { ); $headers = get_headers($this->authUrl); - if($headers === false) { + if(!$headers) { OC::$server->getLogger()->error( - 'ERROR: Not possible to connect to BasicAuth Url: "'.$this->authUrl.'"', + 'ERROR: Not possible to connect to BasicAuth Url: '.$this->authUrl, ['app' => 'user_external'] ); return false; diff --git a/tests/basic_auth.php b/tests/basic_auth.php new file mode 100644 index 0000000..d7c77cd --- /dev/null +++ b/tests/basic_auth.php @@ -0,0 +1,35 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_User_BasicAuth extends \Test\TestCase { + /** + * @var OC_User_BasicAuth $instance + */ + private $instance; + + private function getConfig() { + return include(__DIR__.'/config.php'); + } + + function skip() { + $config=$this->getConfig(); + $this->skipUnless($config['basic_auth']['run']); + } + + protected function setUp() { + parent::setUp(); + $config=$this->getConfig(); + $this->instance=new OC_User_BasicAuth($config['basic_auth']['url']); + } + + function testLogin() { + $config=$this->getConfig(); + $this->assertEquals($config['basic_auth']['user'],$this->instance->checkPassword($config['basic_auth']['user'],$config['basic_auth']['password'])); + $this->assertFalse($this->instance->checkPassword($config['basic_auth']['user'],$config['basic_auth']['password'].'foo')); + } +} diff --git a/tests/config.php b/tests/config.php index a5c7ce8..b29c6c7 100644 --- a/tests/config.php +++ b/tests/config.php @@ -26,4 +26,10 @@ return array( 'user'=>'test',//valid username/password combination 'password'=>'test', ), + 'basic_auth'=>array( + 'run'=>false, + 'url'=>'localhost/basic_auth', + 'user'=>'test',//valid username/password combination + 'password'=>'test', + ), );