SSO 3rd Party integration

Disqus

GET /api/v1/sso/disqus/{forum_slug}/profile

required scope

sso

Rocket Chat

GET /api/v1/sso/rocket-chat/{forum_slug}/profile

required scope

sso

Change-Id: Ie72bc4846356cbef00c04a52d1329af53469e9a6
Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
smarcet 2020-05-30 01:21:07 -03:00
parent e5898c4fab
commit cff54c01e6
32 changed files with 1532 additions and 9 deletions

View File

@ -0,0 +1,66 @@
<?php namespace App\Http\Controllers\Api\OAuth2;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Services\Auth\IDisqusSSOService;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use OAuth2\IResourceServerContext;
use Utils\Services\ILogService;
/**
* Class OAuth2DisqusSSOApiController
* @package App\Http\Controllers\Api\OAuth2
*/
final class OAuth2DisqusSSOApiController extends OAuth2ProtectedController
{
/**
* @var IDisqusSSOService
*/
private $service;
public function __construct
(
IDisqusSSOService $service,
IResourceServerContext $resource_server_context,
ILogService $log_service
)
{
parent::__construct($resource_server_context, $log_service);
$this->service = $service;
}
/**
* @param string $forum_slug
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function getUserProfile(string $forum_slug){
try{
$profile = $this->service->getUserProfile($forum_slug);
return $this->ok($profile->serialize());
}
catch (ValidationException $ex) {
Log::warning($ex);
return $this->error412([$ex->getMessage()]);
}
catch(EntityNotFoundException $ex)
{
Log::warning($ex);
return $this->error404(['message'=> $ex->getMessage()]);
}
catch (\Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@ -0,0 +1,65 @@
<?php namespace App\Http\Controllers\Api\OAuth2;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Services\Auth\IRocketChatSSOService;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use OAuth2\IResourceServerContext;
use Utils\Services\ILogService;
/**
* Class OAuth2RocketChatSSOApiController
* @package App\Http\Controllers\Api\OAuth2
*/
class OAuth2RocketChatSSOApiController extends OAuth2ProtectedController
{
/**
* @var IRocketChatSSOService
*/
private $service;
public function __construct
(
IRocketChatSSOService $service,
IResourceServerContext $resource_server_context,
ILogService $log_service
)
{
parent::__construct($resource_server_context, $log_service);
$this->service = $service;
}
/**
* @param string $forum_slug
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function getUserProfile(string $forum_slug){
try{
$profile = $this->service->getUserProfile($forum_slug);
return $this->ok($profile->serialize());
}
catch (ValidationException $ex) {
Log::warning($ex);
return $this->error412([$ex->getMessage()]);
}
catch(EntityNotFoundException $ex)
{
Log::warning($ex);
return $this->error404(['message'=> $ex->getMessage()]);
}
catch (\Exception $ex) {
Log::error($ex);
return $this->error500($ex);
}
}
}

View File

@ -27,7 +27,7 @@ use Exception;
* Class OAuth2UserApiController
* @package App\Http\Controllers\Api\OAuth2
*/
final class OAuth2UserApiController extends OAuth2ProtectedController
final class OAuth2UserApiController extends OAuth2ProtectedController
{
use GetAllTrait;

View File

@ -193,7 +193,7 @@ final class OAuth2BearerAccessTokenRequestValidator
//if js client , then check if the origin is allowed ....
if($client->getApplicationType() == IClient::ApplicationType_JS_Client)
{
if(!$client->isOriginAllowed($origin))
if(!empty($origin) && !$client->isOriginAllowed($origin))
throw new OAuth2ResourceServerException
(
403,

View File

@ -160,7 +160,7 @@ Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => 'web' ], fu
});
});
//Admin Backend API
// Admin Backend Services
Route::group([
'namespace' => 'Api',
@ -365,7 +365,8 @@ Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => 'web' ], fu
});
});
//OAuth2 Protected API
// OAuth2 Protected API
Route::group(
[
'namespace' => 'App\Http\Controllers\Api\OAuth2',
@ -383,4 +384,21 @@ Route::group(
Route::group(['prefix' => 'user-registration-requests'], function(){
Route::post('', 'OAuth2UserRegistrationRequestApiController@register');
});
// 3rd Party SSO integrations
Route::group(['prefix' => 'sso'], function () {
Route::group(['prefix' => 'disqus'], function () {
Route::group(['prefix' => '{forum_slug}'], function () {
Route::get('profile', 'OAuth2DisqusSSOApiController@getUserProfile');
});
});
Route::group(['prefix' => 'rocket-chat'], function () {
Route::group(['prefix' => '{forum_slug}'], function () {
Route::get('profile', 'OAuth2RocketChatSSOApiController@getUserProfile');
});
});
});
});

View File

@ -0,0 +1,24 @@
<?php namespace App\Models\Repositories;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\SSO\DisqusSSOProfile;
use models\utils\IBaseRepository;
/**
* Interface IDisqusSSOProfileRepository
* @package App\Models\Repositories
*/
interface IDisqusSSOProfileRepository extends IBaseRepository
{
public function getByForumSlug(string $forum_slug):?DisqusSSOProfile;
}

View File

@ -0,0 +1,23 @@
<?php namespace App\Models\Repositories;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\SSO\RocketChatSSOProfile;
use models\utils\IBaseRepository;
/**
* Interface IRocketChatSSOProfileRepository
* @package App\Models\Repositories
*/
interface IRocketChatSSOProfileRepository extends IBaseRepository
{
public function getByForumSlug(string $forum_slug):?RocketChatSSOProfile;
}

View File

@ -0,0 +1,91 @@
<?php namespace App\Models\SSO;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Utils\BaseEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping AS ORM;
/**
* @ORM\Entity(repositoryClass="App\Repositories\DoctrineDisqusSSOProfileRepository")
* @ORM\Table(name="sso_disqus_profile")
* Class DisqusSSOProfile
* @package App\Models\SSO
*/
class DisqusSSOProfile extends BaseEntity
{
/**
* @ORM\Column(name="forum_slug", type="string")
* @var string
*/
private $forum_slug;
/**
* @ORM\Column(name="public_key", type="string")
* @var string
*/
private $public_key;
/**
* @ORM\Column(name="secret_key", type="string")
* @var string
*/
private $secret_key;
/**
* @return string
*/
public function getForumSlug(): string
{
return $this->forum_slug;
}
/**
* @param string $forum_slug
*/
public function setForumSlug(string $forum_slug): void
{
$this->forum_slug = $forum_slug;
}
/**
* @return string
*/
public function getPublicKey(): string
{
return $this->public_key;
}
/**
* @param string $public_key
*/
public function setPublicKey(string $public_key): void
{
$this->public_key = $public_key;
}
/**
* @return string
*/
public function getSecretKey(): string
{
return $this->secret_key;
}
/**
* @param string $secret_key
*/
public function setSecretKey(string $secret_key): void
{
$this->secret_key = $secret_key;
}
}

View File

@ -0,0 +1,107 @@
<?php namespace App\Models\SSO\Disqus;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\SSO\DisqusSSOProfile;
use Auth\User;
/**
* Class DisqusUserProfile
* @package App\Models\SSO\Disqus
*/
class DisqusUserProfile
{
/**
* @var string
*/
private $public_key;
/**
* @var string
*/
private $user_id;
/**
* @var string
*/
private $user_email;
/**
* @var string
*/
private $user_name;
/**
* @var string
*/
private $private_key;
/**
* DisqusUserProfile constructor.
* @param DisqusSSOProfile $profile
* @param User $user
*/
public function __construct(DisqusSSOProfile $profile, User $user)
{
$this->public_key = $profile->getPublicKey();
$this->private_key = $profile->getSecretKey();
$this->user_id = $user->getId();
$this->user_email = $user->getEmail();
$this->user_name = $user->getNickName();
}
/**
* @param string $data
* @param string $key
* @return string
*/
private function dsq_hmacsha1(string $data, string $key):string {
$blocksize=64;
$hashfunc='sha1';
if (strlen($key)>$blocksize)
$key=pack('H*', $hashfunc($key));
$key=str_pad($key,$blocksize,chr(0x00));
$ipad=str_repeat(chr(0x36),$blocksize);
$opad=str_repeat(chr(0x5c),$blocksize);
$hmac = pack(
'H*',$hashfunc(
($key^$opad).pack(
'H*',$hashfunc(
($key^$ipad).$data
)
)
)
);
return bin2hex($hmac);
}
/**
* @return array
*/
public function serialize(){
$data = [
"id" => $this->user_id,
"username" => $this->user_name,
"email" => $this->user_email
];
$message = base64_encode(json_encode($data));
$timestamp = time();
$hmac = $this->dsq_hmacsha1($message . ' ' . $timestamp, $this->private_key);
return [
'auth' => $message." ".$hmac." ".$timestamp,
'public_key' => $this->public_key
];
}
}

View File

@ -0,0 +1,91 @@
<?php namespace App\Models\SSO;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Utils\BaseEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping AS ORM;
/**
* @ORM\Entity(repositoryClass="App\Repositories\DoctrineRocketChatSSOProfileRepository")
* @ORM\Table(name="sso_rocket_chat_profile")
* Class RocketChatSSOProfile
* @package App\Models\SSO
*/
class RocketChatSSOProfile extends BaseEntity
{
/**
* @ORM\Column(name="forum_slug", type="string")
* @var string
*/
private $forum_slug;
/**
* @ORM\Column(name="base_url", type="string")
* @var string
*/
private $base_url;
/**
* @ORM\Column(name="service_name", type="string")
* @var string
*/
private $service_name;
/**
* @return string
*/
public function getForumSlug(): string
{
return $this->forum_slug;
}
/**
* @param string $forum_slug
*/
public function setForumSlug(string $forum_slug): void
{
$this->forum_slug = $forum_slug;
}
/**
* @return string
*/
public function getBaseUrl(): string
{
return $this->base_url;
}
/**
* @param string $base_url
*/
public function setBaseUrl(string $base_url): void
{
$this->base_url = $base_url;
}
/**
* @return string
*/
public function getServiceName(): string
{
return $this->service_name;
}
/**
* @param string $service_name
*/
public function setServiceName(string $service_name): void
{
$this->service_name = $service_name;
}
}

View File

@ -0,0 +1,41 @@
<?php namespace App\Models\SSO;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class RocketChatUserProfile
* @package App\Models\SSO
*/
class RocketChatUserProfile
{
/**
* @var array
*/
private $payload;
/**
* RocketChatUserProfile constructor.
* @param array $payload
*/
public function __construct(array $payload)
{
$this->payload = $payload;
}
/**
* @return array
*/
public function serialize():array {
return $this->payload['data'] ?? [];
}
}

View File

@ -0,0 +1,42 @@
<?php namespace App\Repositories;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Repositories\IDisqusSSOProfileRepository;
use App\Models\SSO\DisqusSSOProfile;
/**
* Class DoctrineDisqusSSOProfileRepository
* @package App\Repositories
*/
final class DoctrineDisqusSSOProfileRepository extends ModelDoctrineRepository
implements IDisqusSSOProfileRepository
{
/**
* @inheritDoc
*/
protected function getBaseEntity()
{
return DisqusSSOProfile::class;
}
/**
* @param string $forum_slug
* @return DisqusSSOProfile|null
*/
public function getByForumSlug(string $forum_slug): ?DisqusSSOProfile
{
return $this->findOneBy([
'forum_slug' => trim($forum_slug)
]);
}
}

View File

@ -0,0 +1,42 @@
<?php namespace App\Repositories;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Repositories\IRocketChatSSOProfileRepository;
use App\Models\SSO\RocketChatSSOProfile;
/**
* Class DoctrineRocketChatSSOProfileRepository
* @package App\Repositories
*/
final class DoctrineRocketChatSSOProfileRepository extends ModelDoctrineRepository
implements IRocketChatSSOProfileRepository
{
/**
* @inheritDoc
*/
protected function getBaseEntity()
{
return RocketChatSSOProfile::class;
}
/**
* @param string $forum_slug
* @return RocketChatSSOProfile|null
*/
public function getByForumSlug(string $forum_slug): ?RocketChatSSOProfile
{
return $this->findOneBy([
'forum_slug' => trim($forum_slug)
]);
}
}

View File

@ -21,6 +21,10 @@ use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
use App\libs\Auth\Repositories\IUserRegistrationRequestRepository;
use App\libs\Auth\Repositories\IWhiteListedIPRepository;
use App\libs\OAuth2\Repositories\IOAuth2TrailExceptionRepository;
use App\Models\Repositories\IDisqusSSOProfileRepository;
use App\Models\Repositories\IRocketChatSSOProfileRepository;
use App\Models\SSO\DisqusSSOProfile;
use App\Models\SSO\RocketChatSSOProfile;
use App\Repositories\IServerConfigurationRepository;
use App\Repositories\IServerExtensionRepository;
use Auth\Group;
@ -224,6 +228,20 @@ final class RepositoriesProvider extends ServiceProvider
}
);
App::singleton(
IDisqusSSOProfileRepository::class,
function(){
return EntityManager::getRepository(DisqusSSOProfile::class);
}
);
App::singleton(
IRocketChatSSOProfileRepository::class,
function(){
return EntityManager::getRepository(RocketChatSSOProfile::class);
}
);
}
public function provides()
@ -246,6 +264,8 @@ final class RepositoriesProvider extends ServiceProvider
IWhiteListedIPRepository::class,
IUserRegistrationRequestRepository::class,
ISpamEstimatorFeedRepository::class,
IDisqusSSOProfileRepository::class,
IRocketChatSSOProfileRepository::class,
];
}
}

View File

@ -0,0 +1,33 @@
<?php namespace App\Services\Apis;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Interface IRocketChatAPI
* @package App\Services\Apis
*/
interface IRocketChatAPI
{
/**
* @param string $base_url
* @return IRocketChatAPI
*/
public function setBaseUrl(string $base_url):IRocketChatAPI;
/**
* @param string $service_name
* @return array
*/
public function login(string $service_name):array;
}

View File

@ -0,0 +1,89 @@
<?php namespace App\Services\Apis;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use GuzzleHttp\Client;
use Exception;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Support\Facades\Log;
use models\exceptions\ValidationException;
use OAuth2\IResourceServerContext;
/**
* Class RocketChatAPI
* @package App\Services\Apis
*/
final class RocketChatAPI implements IRocketChatAPI
{
/**
* @var IResourceServerContext
*/
private $resource_server_context;
/**
* @var string
*/
private $base_url;
/**
* RocketChatAPI constructor.
* @param IResourceServerContext $resource_server_context
*/
public function __construct(IResourceServerContext $resource_server_context)
{
$this->resource_server_context = $resource_server_context;
}
/**
* @param string $service_name
* @return array
* @throws Exception
*/
public function login(string $service_name): array
{
try {
$client = new Client();
$endpoint = sprintf("%s/api/v1/login", $this->base_url);
$payload = [
'serviceName' => $service_name,
'accessToken' => $this->resource_server_context->getCurrentAccessToken(),
"expiresIn" => 3600
];
$response = $client->post($endpoint, [
'json' => $payload
]);
$json = $response->getBody()->getContents();
return json_decode($json, true);
}
catch (ClientException $ex){
Log::error($ex->getMessage());
throw new ValidationException($ex->getMessage());
}
catch(Exception $ex){
Log::error($ex->getMessage());
throw $ex;
}
}
/**
* @param string $base_url
* @return IRocketChatAPI
*/
public function setBaseUrl(string $base_url): IRocketChatAPI
{
$this->base_url = $base_url;
return $this;
}
}

View File

@ -0,0 +1,122 @@
<?php namespace App\Services\Auth;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Repositories\IDisqusSSOProfileRepository;
use App\Models\SSO\Disqus\DisqusUserProfile;
use App\Services\AbstractService;
use Auth\Repositories\IUserRepository;
use Auth\User;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\utils\IEntity;
use OAuth2\IResourceServerContext;
use Utils\Db\ITransactionService;
/**
* Class DisqusSSOService
* @package App\Services\Auth
*/
final class DisqusSSOService extends AbstractService implements IDisqusSSOService
{
/**
* @var IDisqusSSOProfileRepository
*/
private $repository;
/**
* @var IResourceServerContext
*/
private $resource_server_context;
/**
* @var IUserRepository
*/
private $user_repository;
/**
* DisqusSSOService constructor.
* @param IResourceServerContext $resource_server_context
* @param IUserRepository $user_repository
* @param IDisqusSSOProfileRepository $repository
* @param ITransactionService $tx_service
*/
public function __construct
(
IResourceServerContext $resource_server_context,
IUserRepository $user_repository,
IDisqusSSOProfileRepository $repository,
ITransactionService $tx_service
)
{
parent::__construct($tx_service);
$this->repository = $repository;
$this->user_repository = $user_repository;
$this->resource_server_context = $resource_server_context;
}
/**
* @inheritDoc
*/
public function create(array $payload): IEntity
{
// TODO: Implement create() method.
}
/**
* @inheritDoc
*/
public function update(int $id, array $payload): IEntity
{
// TODO: Implement update() method.
}
/**
* @inheritDoc
*/
public function delete(int $id): void
{
// TODO: Implement delete() method.
}
/**
* @param string $forum_slug
* @return DisqusUserProfile|null
* @throws \Exception
*/
public function getUserProfile(string $forum_slug): ?DisqusUserProfile
{
return $this->tx_service->transaction(function() use($forum_slug){
Log::debug("DisqusSSOService::getUserProfile");
$current_user_id = $this->resource_server_context->getCurrentUserId();
Log::debug(sprintf("DisqusSSOService::getUserProfile current_user_id %s", $current_user_id));
if (is_null($current_user_id)) {
throw new ValidationException('me is no set!.');
}
$current_user = $this->user_repository->getById($current_user_id);
if(is_null($current_user)) throw new EntityNotFoundException();
if(!$current_user instanceof User) throw new EntityNotFoundException();
$sso_profile = $this->repository->getByForumSlug($forum_slug);
if(is_null($sso_profile)){
throw new EntityNotFoundException("Forum not found");
}
return new DisqusUserProfile($sso_profile, $current_user);
});
}
}

View File

@ -0,0 +1,31 @@
<?php namespace App\Services\Auth;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\SSO\Disqus\DisqusUserProfile;
use App\Services\IBaseService;
use models\exceptions\EntityNotFoundException;
/**
* Interface IDisqusSSOService
* @package App\Services\Auth
*/
interface IDisqusSSOService extends IBaseService
{
/**
* @param string $forum_slug
* @return DisqusUserProfile|null
* @throws EntityNotFoundException
*/
public function getUserProfile(string $forum_slug):?DisqusUserProfile;
}

View File

@ -0,0 +1,29 @@
<?php namespace App\Services\Auth;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\SSO\RocketChatUserProfile;
use App\Services\IBaseService;
use models\exceptions\EntityNotFoundException;
/**
* Interface IRocketChatSSOService
* @package App\Services\Auth
*/
interface IRocketChatSSOService extends IBaseService
{
/**
* @param string $forum_slug
* @return RocketChatUserProfile|null
* @throws EntityNotFoundException
*/
public function getUserProfile(string $forum_slug):?RocketChatUserProfile;
}

View File

@ -0,0 +1,136 @@
<?php namespace App\Services\Auth;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Models\Repositories\IRocketChatSSOProfileRepository;
use App\Models\SSO\RocketChatUserProfile;
use App\Services\AbstractService;
use App\Services\Apis\IRocketChatAPI;
use Auth\Repositories\IUserRepository;
use Auth\User;
use Illuminate\Support\Facades\Log;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\utils\IEntity;
use OAuth2\IResourceServerContext;
use Utils\Db\ITransactionService;
/**
* Class RocketChatSSOService
* @package App\Services\Auth
*/
final class RocketChatSSOService extends AbstractService implements IRocketChatSSOService
{
/**
* @var IRocketChatSSOProfileRepository
*/
private $repository;
/**
* @var IResourceServerContext
*/
private $resource_server_context;
/**
* @var IUserRepository
*/
private $user_repository;
/**
* @var IRocketChatAPI
*/
private $rocket_chat_api;
/**
* RocketChatSSOService constructor.
* @param IResourceServerContext $resource_server_context
* @param IUserRepository $user_repository
* @param IRocketChatSSOProfileRepository $repository
* @param IRocketChatAPI $rocket_chat_api
* @param ITransactionService $tx_service
*/
public function __construct
(
IResourceServerContext $resource_server_context,
IUserRepository $user_repository,
IRocketChatSSOProfileRepository $repository,
IRocketChatAPI $rocket_chat_api,
ITransactionService $tx_service
)
{
parent::__construct($tx_service);
$this->repository = $repository;
$this->user_repository = $user_repository;
$this->resource_server_context = $resource_server_context;
$this->rocket_chat_api = $rocket_chat_api;
}
/**
* @inheritDoc
*/
public function create(array $payload): IEntity
{
// TODO: Implement create() method.
}
/**
* @inheritDoc
*/
public function update(int $id, array $payload): IEntity
{
// TODO: Implement update() method.
}
/**
* @inheritDoc
*/
public function delete(int $id): void
{
// TODO: Implement delete() method.
}
/**
* @param string $forum_slug
* @return RocketChatUserProfile|null
* @throws \Exception
*/
public function getUserProfile(string $forum_slug): ?RocketChatUserProfile
{
return $this->tx_service->transaction(function() use($forum_slug){
Log::debug("RocketChatSSOService::getUserProfile");
$current_user_id = $this->resource_server_context->getCurrentUserId();
$access_token = $this->resource_server_context->getCurrentAccessToken();
if(empty($access_token)){
throw new ValidationException("Access Token is empty.");
}
Log::debug(sprintf("RocketChatSSOService::getUserProfile current_user_id %s", $current_user_id));
if (is_null($current_user_id)) {
throw new ValidationException('me is no set!.');
}
$current_user = $this->user_repository->getById($current_user_id);
if(is_null($current_user)) throw new EntityNotFoundException();
if(!$current_user instanceof User) throw new EntityNotFoundException();
$sso_profile = $this->repository->getByForumSlug($forum_slug);
if(is_null($sso_profile)){
throw new EntityNotFoundException("Forum not found");
}
return new RocketChatUserProfile
(
$this->rocket_chat_api->setBaseUrl($sso_profile->getBaseUrl())->login($sso_profile->getServiceName())
);
});
}
}

View File

@ -15,6 +15,7 @@ use App\ModelSerializers\SerializerRegistry;
use Auth\Repositories\IUserRepository;
use Auth\User;
use Exception;
use Illuminate\Support\Facades\Log;
use jwt\impl\JWTClaimSet;
use jwt\JWTClaim;
use OAuth2\AddressClaim;
@ -102,9 +103,10 @@ final class UserService extends OAuth2ProtectedService implements IUserService
$data = [];
try
{
Log::debug("UserService::getCurrentUserInfo");
$current_user_id = $this->resource_server_context->getCurrentUserId();
Log::debug(sprintf("UserService::getCurrentUserInfo current_user_id %s", $current_user_id));
if (is_null($current_user_id)) {
throw new Exception('me is no set!.');
}
@ -114,10 +116,11 @@ final class UserService extends OAuth2ProtectedService implements IUserService
if(!$current_user instanceof User) throw new EntityNotFoundException();
$scopes = $this->resource_server_context->getCurrentScope();
$scopes = $this->resource_server_context->getCurrentScope();
if (in_array(self::UserProfileScope_Address, $scopes)) {
// Address Claims
Log::debug(sprintf("UserService::getCurrentUserInfo current_user_id %s address", $current_user_id));
$data[AddressClaim::Country] = $current_user->getCountry();
$data[AddressClaim::StreetAddress] = $current_user->getCountry();
$data[AddressClaim::PostalCode] = $current_user->getPostalCode();
@ -125,6 +128,7 @@ final class UserService extends OAuth2ProtectedService implements IUserService
$data[AddressClaim::Locality] = $current_user->getLocality();
}
if (in_array(self::UserProfileScope_Profile, $scopes)) {
Log::debug(sprintf("UserService::getCurrentUserInfo current_user_id %s profile", $current_user_id));
// Profile Claims
$data[StandardClaims::Name] = $current_user->getFullName();
$data[StandardClaims::GivenName] = $current_user->getFirstName();
@ -152,6 +156,7 @@ final class UserService extends OAuth2ProtectedService implements IUserService
$data[StandardClaims::Groups] = $user_groups;
}
if (in_array(self::UserProfileScope_Email, $scopes)) {
Log::debug(sprintf("UserService::getCurrentUserInfo current_user_id %s email", $current_user_id));
// Email Claim
$data[StandardClaims::Email] = $current_user->getEmail();
$data[StandardClaims::SecondEmail] = $current_user->getSecondEmail();

View File

@ -11,11 +11,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\libs\Auth\Repositories\IUserExceptionTrailRepository;
use App\Services\Apis\IRocketChatAPI;
use App\Services\Apis\RocketChatAPI;
use App\Services\Auth\DisqusSSOService;
use App\Services\Auth\GroupService;
use App\Services\Auth\IDisqusSSOService;
use App\Services\Auth\IGroupService;
use App\Services\Auth\IRocketChatSSOService;
use App\Services\Auth\IUserService;
use App\Services\Auth\RocketChatSSOService;
use App\Services\Auth\UserService;
use Illuminate\Support\ServiceProvider;
use Services\SecurityPolicies\AuthorizationCodeRedeemPolicy;
@ -84,12 +89,15 @@ final class ServicesProvider extends ServiceProvider
App::singleton(IUserService::class, UserService::class);
App::singleton(IGroupService::class, GroupService::class);
App::singleton(IDisqusSSOService::class, DisqusSSOService::class);
App::singleton(IRocketChatSSOService::class, RocketChatSSOService::class);
App::singleton(IRocketChatAPI::class, RocketChatAPI::class);
}
public function provides()
{
return [
\Services\IUserActionService::class,
IUserActionService::class,
\Services\SecurityPolicies\DelayCounterMeasure::class,
\Services\SecurityPolicies\LockUserCounterMeasure::class,
\Services\SecurityPolicies\RevokeAuthorizationCodeRelatedTokens::class,
@ -100,6 +108,9 @@ final class ServicesProvider extends ServiceProvider
AuthorizationCodeRedeemPolicy::class,
UtilsServiceCatalog::CheckPointService,
IUserService::class,
IDisqusSSOService::class,
IRocketChatSSOService::class,
IRocketChatAPI::class,
];
}
}

View File

@ -25,5 +25,6 @@ interface IUserScopes
const Address = 'address';
const Registration = 'user-registration';
const ReadAll = 'users-read-all';
const SSO = 'sso';
}

View File

@ -0,0 +1,65 @@
<?php namespace Database\Migrations;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema as Schema;
use LaravelDoctrine\Migrations\Schema\Builder;
use LaravelDoctrine\Migrations\Schema\Table;
/**
* Class Version20200528175450
* @package Database\Migrations
*/
class Version20200528175450 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$builder = new Builder($schema);
if (!$builder->hasTable("sso_disqus_profile")) {
$builder->create("sso_disqus_profile", function (Table $table) {
$table->increments('id');
$table->timestamps();
$table->string("forum_slug")->setNotnull(true);
$table->string("public_key")->setNotnull(true);
$table->string("secret_key")->setNotnull(true);
$table->unique("forum_slug");
});
}
if (!$builder->hasTable("sso_rocket_chat_profile")) {
$builder->create("sso_rocket_chat_profile", function (Table $table) {
$table->increments('id');
$table->timestamps();
$table->string("forum_slug")->setNotnull(true);
$table->string("base_url")->setNotnull(true);
$table->string("service_name")->setNotnull(true);
$table->unique("forum_slug");
});
}
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$builder = new Builder($schema);
$builder->dropIfExists("sso_disqus_profile");
$builder->dropIfExists("sso_rocket_chat_profile");
}
}

View File

@ -0,0 +1,72 @@
<?php namespace Database\Migrations;
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\libs\OAuth2\IUserScopes;
use Doctrine\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema as Schema;
use SeedUtils;
/**
* Class Version20200530150357
* @package Database\Migrations
*/
class Version20200530150357 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
if(!SeedUtils::seedApi("sso", "SSO Integration API")) return;
SeedUtils::seedScopes([
[
'name' => IUserScopes::SSO,
'short_description' => 'Allows SSO integration',
'description' => 'Allows SSO integration',
'system' => false,
'default' => false,
'groups' => true,
],
], 'sso');
SeedUtils::seedApiEndpoints('sso', [
[
'name' => 'sso-disqus',
'active' => true,
'route' => '/api/v1/sso/disqus/{forum_slug}/profile',
'http_method' => 'GET',
'scopes' => [
\App\libs\OAuth2\IUserScopes::SSO
],
],
[
'name' => 'sso-rocket-chat',
'active' => true,
'route' => '/api/v1/sso/rocket-chat/{forum_slug}/profile',
'http_method' => 'GET',
'scopes' => [
\App\libs\OAuth2\IUserScopes::SSO
],
],
]);
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
}
}

View File

@ -26,6 +26,7 @@ class ApiEndpointSeeder extends Seeder
DB::table('oauth2_api_endpoint')->delete();
$this->seedUsersEndpoints();
$this->seedRegistrationEndpoints();
$this->seedSSOEndpoints();
}
@ -92,4 +93,27 @@ class ApiEndpointSeeder extends Seeder
]);
}
private function seedSSOEndpoints(){
SeedUtils::seedApiEndpoints('sso', [
[
'name' => 'sso-disqus',
'active' => true,
'route' => '/api/v1/sso/disqus/{forum_slug}/profile',
'http_method' => 'GET',
'scopes' => [
\App\libs\OAuth2\IUserScopes::SSO
],
],
[
'name' => 'sso-rocket-chat',
'active' => true,
'route' => '/api/v1/sso/rocket-chat/{forum_slug}/profile',
'http_method' => 'GET',
'scopes' => [
\App\libs\OAuth2\IUserScopes::SSO
],
],
]);
}
}

View File

@ -30,6 +30,7 @@ class ApiScopeSeeder extends Seeder {
DB::table('oauth2_api_scope')->delete();
$this->seedUsersScopes();
$this->seedRegistrationScopes();
$this->seedSSOScopes();
}
@ -99,6 +100,19 @@ class ApiScopeSeeder extends Seeder {
],
], 'user-registration');
}
private function seedSSOScopes(){
SeedUtils::seedScopes([
[
'name' => IUserScopes::SSO,
'short_description' => 'Allows SSO integration',
'description' => 'Allows SSO integration',
'system' => false,
'default' => false,
'groups' => true,
],
], 'sso');
}
}

View File

@ -52,5 +52,15 @@ class ApiSeeder extends Seeder {
EntityManager::persist($api);
EntityManager::flush();
$api = new Api();
$api->setName('sso');
$api->setActive(true);
$api->setDescription('SSO Integration API');
$api->setResourceServer($rs);
EntityManager::persist($api);
EntityManager::flush();
}
}

View File

@ -16,11 +16,34 @@ use Models\OAuth2\ApiEndpoint;
use Models\OAuth2\ApiScope;
use Models\OAuth2\Api;
use LaravelDoctrine\ORM\Facades\EntityManager;
use Models\OAuth2\ResourceServer;
/**
* Class SeedUtils
*/
final class SeedUtils
{
/**
* @param string $api_name
* @param string $api_description
* @return bool
*/
public static function seedApi(string $api_name, string $api_description){
$resource_server_repository = EntityManager::getRepository(ResourceServer::class);
$rs = $resource_server_repository->find(1);
if(is_null($rs)) return false;
$api = new Api();
$api->setName($api_name);
$api->setActive(true);
$api->setDescription($api_description);
$api->setResourceServer($rs);
EntityManager::persist($api);
EntityManager::flush();
return true;
}
/**
* @param string $api_name
* @param array $endpoints_info

View File

@ -418,6 +418,7 @@ PPK;
$this->seedApiScopeScopes();
$this->seedUsersScopes();
$this->seedUsersRegistrationScopes();
$this->seedSSOScopes();
$this->seedPublicCloudScopes();
$this->seedPrivateCloudScopes();
$this->seedConsultantScopes();
@ -427,6 +428,7 @@ PPK;
$this->seedApiEndpoints();
$this->seedUsersEndpoints();
$this->seedUserRegistrationEndpoints();
$this->seedSSOEndpoints();
/*
$this->seedApiEndpointEndpoints();
$this->seedScopeEndpoints();
@ -669,6 +671,13 @@ PPK;
'resource_server' => $resource_server,
'logo' => asset('/assets/img/apis/server.png')
),
array(
'name' => 'sso',
'active' => true,
'description' => 'SSO Integration',
'resource_server' => $resource_server,
'logo' => asset('/assets/img/apis/server.png')
),
array(
'name' => 'public-clouds',
'active' => true,
@ -1405,6 +1414,31 @@ PPK;
EntityManager::flush();
}
private function seedSSOScopes(){
$api_repository = EntityManager::getRepository(Api::class);
$api = $api_repository->findOneBy(['name' => 'sso']);
$current_realm = Config::get('app.url');
$api_scope_payloads = [
array(
'name' => IUserScopes::SSO,
'short_description' => 'Allows SSO integration',
'description' => 'Allows SSO integration',
'api' => $api,
'system' => false,
'active' => true,
),
];
foreach($api_scope_payloads as $payload) {
EntityManager::persist(ApiScopeFactory::build($payload));
}
EntityManager::flush();
}
private function seedPublicCloudScopes(){
$api_repository = EntityManager::getRepository(Api::class);
@ -1688,6 +1722,46 @@ PPK;
EntityManager::flush();
}
private function seedSSOEndpoints(){
$api_repository = EntityManager::getRepository(Api::class);
$endpoint_repository = EntityManager::getRepository(ApiEndpoint::class);
$api = $api_repository->findOneBy(['name' => 'sso']);
$api_scope_payloads = [
array(
'name' => 'sso-disqus',
'active' => true,
'api' => $api,
'route' => '/api/v1/sso/disqus/{forum_slug}/profile',
'http_method' => 'GET'
),
array(
'name' => 'sso-rocket-chat',
'active' => true,
'api' => $api,
'route' => '/api/v1/sso/rocket-chat/{forum_slug}/profile',
'http_method' => 'GET'
),
];
foreach($api_scope_payloads as $payload) {
EntityManager::persist(ApiEndpointFactory::build($payload));
}
EntityManager::flush();
$api_scope_repository = EntityManager::getRepository(ApiScope::class);
$scope = $api_scope_repository->findOneBy(['name' => \App\libs\OAuth2\IUserScopes::SSO]);
foreach($api_scope_payloads as $payload) {
$endpoint = $endpoint_repository->findOneBy(['name' => $payload['name']]);
$endpoint->addScope($scope);
EntityManager::persist($endpoint);
}
EntityManager::flush();
}
/*
private function seedApiEndpointEndpoints(){

View File

@ -34,7 +34,7 @@ abstract class BrowserKitTestCase extends BaseTestCase
*/
protected $baseUrl = 'http://localhost';
public function setUp()
protected function setUp()
{
parent::setUp(); // Don't forget this!
$this->redis = Redis::connection();

View File

@ -0,0 +1,154 @@
<?php
/**
* Copyright 2020 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use LaravelDoctrine\ORM\Facades\EntityManager;
use LaravelDoctrine\ORM\Facades\Registry;
use Doctrine\Common\Persistence\ObjectRepository;
use Illuminate\Support\Facades\DB;
use App\Models\SSO\DisqusSSOProfile;
use App\Models\Utils\BaseEntity;
use App\Models\SSO\RocketChatSSOProfile;
/**
* Class OAuthSSOApiControllerTest
*/
final class OAuthSSOApiControllerTest extends OAuth2ProtectedApiTest
{
/**
* @var EntityManager
*/
static $em;
/**
* @var ObjectRepository
*/
static $disqus_repository;
/**
* @var ObjectRepository
*/
static $rocket_chat_repository;
/**
* @var DisqusSSOProfile
*/
static $disqus_profile;
/**
* @var RocketChatSSOProfile
*/
static $rocket_chat_profile;
public function setUp()
{
parent::setUp();
DB::table("sso_disqus_profile")->delete();
DB::table("sso_rocket_chat_profile")->delete();
self::$disqus_repository = EntityManager::getRepository(DisqusSSOProfile::class);
self::$rocket_chat_repository = EntityManager::getRepository(RocketChatSSOProfile::class);
self::$disqus_profile = new DisqusSSOProfile();
self::$disqus_profile->setForumSlug("poc_disqus");
self::$disqus_profile->setPublicKey("PUBLIC_KEY");
self::$disqus_profile->setSecretKey("SECRET_KEY");
self::$rocket_chat_profile = new RocketChatSSOProfile();
self::$rocket_chat_profile->setForumSlug("poc_rocket_chat");
self::$rocket_chat_profile->setBaseUrl("https://rocket-chat.dev.fnopen.com");
self::$rocket_chat_profile->setServiceName("fnid");
self::$em = Registry::getManager(BaseEntity::EntityManager);
if (!self::$em ->isOpen()) {
self::$em = Registry::resetManager(BaseEntity::EntityManager);
}
self::$em->persist(self::$disqus_profile);
self::$em->persist(self::$rocket_chat_profile);
self::$em->flush();
}
protected function tearDown()
{
self::$em = Registry::resetManager(BaseEntity::EntityManager);
self::$disqus_profile = self::$disqus_repository->find(self::$disqus_profile->getId());
self::$em->remove(self::$disqus_profile);
self::$em->flush();
parent::tearDown();
}
public function testDisqusGetUserProfile(){
$params = [
"forum_slug" => self::$disqus_profile->getForumSlug()
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action
(
"GET",
"Api\\OAuth2\\OAuth2DisqusSSOApiController@getUserProfile",
$params,
[],
[],
[],
$headers
);
$this->assertResponseStatus(200);
$content = $response->getContent();
$profile = json_decode($content);
$this->assertTrue(!empty($profile->auth));
$this->assertTrue(!empty($profile->public_key));
$this->assertTrue($profile->public_key == self::$disqus_profile->getPublicKey());
}
public function testRocketGetUserProfileFails(){
$params = [
"forum_slug" => self::$rocket_chat_profile->getForumSlug()
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action
(
"GET",
"Api\\OAuth2\\OAuth2RocketChatSSOApiController@getUserProfile",
$params,
[],
[],
[],
$headers
);
$this->assertResponseStatus(412);
$content = $response->getContent();
}
protected function getScopes()
{
$scope = array(
\App\libs\OAuth2\IUserScopes::SSO
);
return $scope;
}
}