Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F/http #166

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,41 @@ Add the following to your `config.php`:
),
),

0 - Database Host
1 - Prosody Database Name
2 - Database User
3 - Database User Password
4 - XMPP Domain
5 - Hashed Passwords in Database (true) / Plaintext Passwords in Database (false)
- 0 - Database Host
- 1 - Prosody Database Name
- 2 - Database User
- 3 - Database User Password
- 4 - XMPP Domain
- 5 - Hashed Passwords in Database (true) / Plaintext Passwords in Database (false)

**⚠⚠ Warning:** If you need to set *5 (Hashed Password in Database)* to false, your Prosody Instance is storing passwords in plaintext. This is insecure and not recommended. We highly recommend that you change your Prosody configuration to protect the passwords of your Prosody users. ⚠⚠


HTTP
----
Authenticate Nextcloud users against a generic HTTP interface.
A user and password need to be given for the Nextcloud login. If the configured HTTP interface responds with HTTP Status Code *202*, the user is authenticated successfully.


### Configuration
Add the following to your `config.php`:

'user_backends' => array (
0 => array (
'class' => 'OC_User_HTTP',
'arguments' => array (
0 => 'https://example.com/authenticate.php',
1 => 'sha1',
2 => 'GbTESTexHJyWYs3Yr9WiUwIuJgH7zsJSax',
),
),
),

- 0 - (Required) Authentication Endpoint: This is the URL to your authentication endpoint. You are fully responsible for doing proper authentication on your authentication endpoint's side. If the authentication was successful, your authentication endpoint must respond with HTTP status code *202*, any other HTTP status code will be detected as unauthenticated.
- 1 - (Optional) Hash Algorithm: By default, the user's password is sent in plaintext your authentication endpoint. If you set a hash algorithm, only the hashed password is sent to your authentication endpoint. Supportet algorithms: https://www.php.net/manual/en/function.hash-algos.php
- 2 - (Optional) Access Key: If you have secured your authentication endpoint you can define an access key. This key is sent to your authentication endpoint when Nextcloud tries to send requests to your authentication endpoint.


Alternatives
------------
Other extensions allow connecting to external user databases directly via SQL, which may be faster:
Expand Down
3 changes: 2 additions & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>user_external</id>
<name>External user authentication</name>
<summary>Use external user authentication methods like IMAP, SMB, FTP, WebDAV, HTTP BasicAuth, SSH and XMPP</summary>
<summary>Use external user authentication methods like IMAP, SMB, FTP, WebDAV, HTTP BasicAuth, SSH, XMPP and HTTP</summary>
<description><![CDATA[Use external user authentication methods to give users acces to your Nextcloud instance:

* IMAP
Expand All @@ -13,6 +13,7 @@
* HTTP BasicAuth
* SSH
* XMPP
* HTTP

Read the [documentation](https://github.com/nextcloud/user_external#readme) to learn how to configure it!
]]></description>
Expand Down
76 changes: 76 additions & 0 deletions lib/http.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
* Copyright (c) 2021 Sebastian Sterk <sebastian@wiuwiu.de>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/

/**
* User authentication against a generic HTTP auth interface
*
* @category Apps
* @package UserExternal
* @author Sebastian Sterk https://wiuwiu.de/Imprint
* @license http://www.gnu.org/licenses/agpl AGPL
*/
class OC_User_HTTP extends \OCA\user_external\Base {
private $hashAlgo;
private $accessKey;
private $authenticationEndpoint;

public function __construct($authenticationEndpoint, $hashAlgo = false, $accessKey = '') {
parent::__construct($authenticationEndpoint);
$this->authenticationEndpoint = $authenticationEndpoint;
$this->hashAlgo = $hashAlgo;
$this->accessKey = $accessKey;
}

public function sendUserData($user, $password){
if($this->hashAlgo !== false){
$password = $this->hashPassword($password);
}
$ch = curl_init();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why manual curl and not \OCP\Http\Client\IClientService? Raw curl won't work with Nextcloud's configured HTTP proxies and some other things by default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any example or documentation about how to use \OCP\Http\Client\IClientService? Thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curl_setopt($ch, CURLOPT_URL, $this->authenticationEndpoint);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
http_build_query(array(
'accessKey' => $this->accessKey,
'user' => $user,
'password' => $password
)
)
);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpCode == 202){
return true;
} else{
return false;
}

}

public function hashPassword($password){
sebastiansterk marked this conversation as resolved.
Show resolved Hide resolved
return hash($this->hashAlgo, $password);
}

public function checkPassword($uid, $password){
if(isset($uid)
&& isset($password)) {

$authenticationStatus = $this->sendUserData($uid, $password);
if ($authenticationStatus) {
$uid = mb_strtolower($uid);
$this->storeUser($uid);
return $uid;
} else {
return false;
}
}
}
}