zorn-v / nextcloud-social-login

GNU Affero General Public License v3.0
198 stars 137 forks source link

Use one nextcloud instance as oauth for another #335

Closed ghost closed 2 years ago

ghost commented 2 years ago

Hello,

I’m currently trying to use a Nextcloud instance provided by mail-in-a-box to authenticate my personal instance. This is to avoid having to make user accounts (although it would be much easier). Running only one instance is not an option as my VPS has little storage (~20GB).

On my mail-in-a-box server (runs on https://box.example1.com/cloud/) I’ve added an Oauth2 client in the Security Admin settings (docs):

Redirection URI     https://cloud.example2.com/index.php/apps/sociallogin/custom_oauth2/nc
Client Identifier   <CLIENT_ID>
Secret  <SECRET>

On my personal server (the aforementioned https://cloud.example2.com/) I’ve got the Social Login plugin and the following configuration (based on this, this and this):

Internal name: nc
Title: nc
API Base URL: https://box.example1.com/cloud/index.php
Authorize url: https://box.example1.com/cloud/index.php/apps/oauth2/authorize
Token url: https://box.example1.com/cloud/index.php/apps/oauth2/api/v1/token
Profile url: https://box.example1.com/cloud/index.php/ocs/v2.php/cloud/user?format=json
Client Id: <CLIENT_ID>
Client Secret: <SECRET>

The omitted options are unset.

It seems to work, and asks for a login up until it gets redirected back to https://cloud.example2.com where it just says: Error Can not get identifier from provider

From some research, it seems like I need to configure the Profile Fields with appropriate values since that is what the error seems to be pointing at. I could not find sufficient documentation for this and I've already asked on the Nextcloud Forums with no luck so far.

Thank you.

ghost commented 2 years ago

After reading through #170 I decided to add $data = new Data\Collection($data->get("ocs")->data); in the appropriate place in custom_apps/sociallogin/lib/Provider/CustomOAuth2.php. It now spits out a different error: Provider API returned an unexpected response.

print_r($data); die(); without the new line:

Hybridauth\Data\Collection Object ( [collection:protected] => stdClass Object ( [ocs] => stdClass Object ( [meta] => stdClass Object ( [status] => ok [statuscode] => 200 [message] => OK ) [data] => stdClass Object ( [storageLocation] => /home/user-data/owncloud/admin [id] => admin [lastLogin] => 1645887110000 [backend] => Database [subadmin] => Array ( ) [quota] => stdClass Object ( [free] => 20095176704 [used] => 16669138 [total] => 20111845842 [relative] => 0.08 [quota] => -3 ) [email] => [phone] => [address] => [website] => [twitter] => [groups] => Array ( ) [language] => en [locale] => [backendCapabilities] => stdClass Object ( [setDisplayName] => 1 [setPassword] => 1 ) [display-name] => Admin ) ) [identifier] => [displayName] => ) )

print_r($data); die(); with the new line:

Hybridauth\Data\Collection Object ( [collection:protected] => stdClass Object ( [storageLocation] => /home/user-data/owncloud/admin [id] => admin [lastLogin] => 1645887110000 [backend] => Database [subadmin] => Array ( ) [quota] => stdClass Object ( [free] => 20095139840 [used] => 16669138 [total] => 20111808978 [relative] => 0.08 [quota] => -3 ) [email] => [phone] => [address] => [website] => [twitter] => [groups] => Array ( ) [language] => en [locale] => [backendCapabilities] => stdClass Object ( [setDisplayName] => 1 [setPassword] => 1 ) [display-name] => Admin ) )

print_r($data->get('identifier')); die(); returns nothing print_r($data->identifier); die(); returns nothing

I tried to do some more debugging but I'm not fluent in PHP.

It seems like this block of code trips the error

if (!$data->exists('identifier')) {
    throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}

I tried to set $data->identifier = 'admin'; but I either did it wrong or it is ignored by the code. Looks like nextcloud is looking for the identifier but only receives id, so if my assumption is correct then by somehow setting $data->identifier to $data->id then the problem is fixed.

Thanks in advance

zorn-v commented 2 years ago

Try to update to v4.12.1 and check again

ghost commented 2 years ago

After updating, it gets farther than usual, but it spits out an "Internal Server Error". It shows an error in the logs:

Exception: Call to protected method OC\Accounts\AccountManager::getUser() from scope OCA\SocialLogin\Service\ProviderService in file '/var/www/html/custom_apps/sociallogin/lib/Service/ProviderService.php' line 549

This points to this block of code in the specific file:

if (isset($profile->address)) {
    $account = $this->accountManager->getUser($user); # <- this line specifically
    $account['address']['value'] = $profile->address;
    $this->accountManager->updateUser($user, $account);
}

So it can't call getUser() because it's outside the scope of the file. Is there a file that defines the app's scope so that nextcloud can give it the correct permission to execute getUser()?

Another explanation for the error would be that it's not parsing the user id properly, but I have no clue how that would work.

Thanks for the reply

edit: one question mark

zorn-v commented 2 years ago

When that code was written, there was not AccountManager::updateAccount method (added in nextcloud 21.0.1) and getUser was public. Fixed in v4.12.2

ghost commented 2 years ago

It works. Thanks so much!!!

xiaoche6690 commented 1 year ago

I have the same problem, could you elaborate on how you solved it? The version I use is v4.13.1

ghost commented 1 year ago

I've stopped using Nextcloud since but the configuration I used in my initial post did work in the past. Perhaps it's a configuration issue or some change to the upstream code might have broken it.