Skip to content

Commit

Permalink
Merge branch 'release/2.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ssfinney committed Apr 3, 2020
2 parents 46d8ce8 + d283330 commit d7b7566
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ matrix:
- php: 7.3
- php: 7.3
env: SETUP=lowest
- php: 7.4
- php: 7.4
env: SETUP=lowest

sudo: false

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.0
2.5.0
16 changes: 10 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@
{
"name": "Jimmy Puckett",
"email": "[email protected]"
},
{
"name": "Stephen Finney",
"email": "[email protected]"
}
],
"require": {
"php": ">=7.2",
"ext-json": "*",
"cviebrock/discourse-php": "^0.9.3",
"guzzlehttp/guzzle": "^6.4",
"illuminate/auth": "~5.5|~6",
"illuminate/routing": "~5.5|~6",
"illuminate/support": "~5.5|~6"
"illuminate/auth": "~5.5|~6|~7",
"illuminate/routing": "~5.5|~6|~7",
"illuminate/support": "~5.5|~6|~7"
},
"require-dev": {
"mockery/mockery": "^1",
"phpunit/phpunit": "~7.0.1|~8.0",
"psy/psysh": "^0.9.9",
"mockery/mockery": "^1.3.1",
"phpunit/phpunit": "^8.4|^9.0",
"psy/psysh": "^0.10",
"symfony/thanks": "^1.1",
"symfony/var-dumper": "~3.0|^4.2"
},
Expand Down
4 changes: 2 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="true"
processIsolation="false"
stopOnFailure="false"
verbose="true">

Expand Down Expand Up @@ -48,7 +48,7 @@
showOnlySummary="true"
showUncoveredFiles="false"/>
<log type="coverage-clover" target="build/phpunit/logs/clover.xml"/>
<log type="json" target="./build/phpunit/logs/logfile.json"/>
<log type="plain" target="./build/phpunit/logs/logfile.log"/>
<log type="junit" target="./build/phpunit/logs/junit.xml"/>
</logging>
</phpunit>
37 changes: 35 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ $ composer require spinen/laravel-discourse-sso

The package uses the [auto registration feature](https://laravel.com/docs/5.8/packages#package-discovery) of Laravel 5.

## Configuration
## Package Configuration

All of the configuration values are stored in under a `discourse` key in `config/services.php`. Here is the array to add...

Expand Down Expand Up @@ -128,6 +128,40 @@ You can then add logic to the `User` model inside of [Accessors](https://laravel
}
```

## Discourse Configuration
### Settings -> Login
These are the configs we have under `Settings -> Login`. If a setting isn't listed, then ours is set to the default value.

| **Setting** | **Value** |
|--------------------------|----------------------------------------------------------|
| login required | true |
| enable sso | true |
| sso url | Our Laravel's SSO route (FQDN) |
| sso secret | Our SSO secret key |
| sso overrides bio | true |
| sso overrides email | true |
| sso overrides username | true |
| sso overrides name | true |
| sso overrides avatar | true |
| sso not approved url | Our Laravel homepage (same as `url` in `config/app.php`) |
| hide email address taken | true |
_______________________________________________________________________


### Settings -> Users
These are the configs we have under `Settings -> Users`. If a setting isn't listed, then ours is set to the default value.

| **Setting** | **Value** |
|-------------------------------------------|----------------------------------------------------------|
| reserved usernames | We added our client's company name |
| min password length | 8 |
| min admin password length | 8 |
| email editable | false |
| logout redirect | Our Laravel homepage (same as `url` in `config/app.php`) |
| purge unactivated users grace period days | 30 |
| hide user profiles from public | true |
_______________________________________________________________________

## Logging out the Discourse User

There's a listener in `src/Listeners/LogoutDiscourseUser.php` that will automatically log out the user from Discourse when certain events are fired. To use the Listener, [you need to register the event](https://laravel.com/docs/master/events#registering-events-and-listeners) in the `$listen` array in your `EventServiceProvider`.
Expand All @@ -149,7 +183,6 @@ When a Laravel `User` logs out, to log out their Discourse session Simply add th

## Left to do

* document Discourse configuration
* badges for user
* support for [`custom_fields`](https://meta.discourse.org/t/custom-user-fields-for-plugins/14956)
* failed login redirect
Expand Down
16 changes: 11 additions & 5 deletions src/Listeners/LogoutDiscourseUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ public function handle($event)
];

// Get Discourse user to match this one, and send a Logout request to Discourse and get the response
$user = json_decode(
$this->client->get("users/by-external/{$event->user->id}.json", $configs)
->getBody()
)->user;
$response = $this->client->get("users/by-external/{$event->user->id}.json", $configs);

$response = $this->client->post("admin/users/{$user->id}/log_out");
if ($response->getStatusCode() !== 200) {
$this->logger->warning(
"When getting user {$event->user->id} Discourse returned status code {$response->getStatusCode()}",
['reason' => $response->getReasonPhrase()]
);
return;
}

$user = json_decode($response->getBody())->user;
$response = $this->client->post("admin/users/{$user->id}/log_out", $configs);

if ($response->getStatusCode() !== 200) {
$this->logger->notice(
Expand Down
71 changes: 62 additions & 9 deletions tests/Listeners/LogoutDiscourseUserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public function it_logs_out_the_discourse_user_when_triggered()
->andReturn(json_encode(['user' => $this->user_mock]));

$this->response_mock->shouldReceive('getStatusCode')
->once()
->twice()
->andReturn(200);

$this->guzzle_mock->shouldReceive('get')
Expand All @@ -138,7 +138,7 @@ public function it_logs_out_the_discourse_user_when_triggered()
->andReturn($this->response_mock);

$this->guzzle_mock->shouldReceive('post')
->with('admin/users/1/log_out')
->with('admin/users/1/log_out', $configs)
->andReturn($this->response_mock);

$this->listener->handle($this->event_mock);
Expand All @@ -160,13 +160,12 @@ public function if_it_receives_no_user_it_does_nothing_and_returns()
/**
* @test
*/
public function if_discourse_response_code_is_not_200_log_a_notice_with_the_status_code()
public function on_getting_user_if_discourse_response_code_is_not_200_log_a_warning_with_the_status_code()
{
$this->user_mock->id = 1;
$this->event_mock->user = $this->user_mock;

$this->logger_mock->shouldReceive('notice')->once();

$this->logger_mock->shouldReceive('warning')->once();

$configs = [
'base_uri' => 'http://discourse.example.com',
Expand All @@ -191,9 +190,53 @@ public function if_discourse_response_code_is_not_200_log_a_notice_with_the_stat
->once()
->andReturn($configs['headers']['Api-Username']);

$this->response_mock->shouldReceive('getBody')
$this->response_mock->shouldReceive('getStatusCode')
->andReturn(500);

$this->response_mock->shouldReceive('getReasonPhrase')
->once()
->andReturn(json_encode(['user' => $this->user_mock]));
->andReturn('Server error');

$this->guzzle_mock->shouldReceive('get')
->with('users/by-external/1.json', $configs)
->once()
->andReturn($this->response_mock);

$this->listener->handle($this->event_mock);
}

/**
* @test
*/
public function on_user_logout_if_discourse_response_code_is_not_200_log_a_notice_with_the_status_code()
{
$this->user_mock->id = 1;
$this->event_mock->user = $this->user_mock;

$this->logger_mock->shouldReceive('notice')->once();

$configs = [
'base_uri' => 'http://discourse.example.com',
'headers' => [
'Api-Key' => 'testkey',
'Api-Username' => 'testuser',
],
];

$this->config_mock->shouldReceive('get')
->with('services.discourse.url')
->once()
->andReturn($configs['base_uri']);

$this->config_mock->shouldReceive('get')
->with('services.discourse.api.key')
->once()
->andReturn($configs['headers']['Api-Key']);

$this->config_mock->shouldReceive('get')
->with('services.discourse.api.user')
->once()
->andReturn($configs['headers']['Api-Username']);

$this->response_mock->shouldReceive('getStatusCode')
->andReturn(500);
Expand All @@ -202,13 +245,23 @@ public function if_discourse_response_code_is_not_200_log_a_notice_with_the_stat
->once()
->andReturn('Server error');

$good_response = Mockery::mock(Response::class);

$good_response->shouldReceive('getStatusCode')
->once()
->andReturn(200);

$good_response->shouldReceive('getBody')
->once()
->andReturn(json_encode(['user' => $this->user_mock]));

$this->guzzle_mock->shouldReceive('get')
->with('users/by-external/1.json', $configs)
->once()
->andReturn($this->response_mock);
->andReturn($good_response);

$this->guzzle_mock->shouldReceive('post')
->with('admin/users/1/log_out')
->with('admin/users/1/log_out', $configs)
->andReturn($this->response_mock);

$this->listener->handle($this->event_mock);
Expand Down

0 comments on commit d7b7566

Please sign in to comment.