OAuth: Added display name and metrics, show providers on user page

This commit is contained in:
Igor Scheller 2020-11-22 14:45:24 +01:00 committed by msquare
parent 13501a3b84
commit 251f2cbfa6
8 changed files with 97 additions and 12 deletions

View File

@ -66,7 +66,9 @@ return [
'oauth' => [ 'oauth' => [
// '[name]' => [config] // '[name]' => [config]
/* /*
'name' => [ '[name]' => [
// Name shown to the user (optional)
'name' => 'Some Provider',
// Auth client ID // Auth client ID
'client_id' => 'engelsystem', 'client_id' => 'engelsystem',
// Auth client secret // Auth client secret

View File

@ -5,6 +5,7 @@ use Engelsystem\Models\Room;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\Models\Worklog; use Engelsystem\Models\Worklog;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Str;
/** /**
* Renders user settings page * Renders user settings page
@ -666,12 +667,13 @@ function User_view(
]) ])
]), ]),
div('row', [ div('row', [
div('col-md-3', [ div('col-md-2', [
heading(glyph('phone') . $user_source->contact->dect, 1) heading(glyph('phone') . $user_source->contact->dect, 1)
]), ]),
User_view_state($admin_user_privilege, $freeloader, $user_source), User_view_state($admin_user_privilege, $freeloader, $user_source),
User_angeltypes_render($user_angeltypes), User_angeltypes_render($user_angeltypes),
User_groups_render($user_groups) User_groups_render($user_groups),
$admin_user_privilege ? User_oauth_render($user_source) : '',
]), ]),
($its_me || $admin_user_privilege) ? '<h2>' . __('Shifts') . '</h2>' : '', ($its_me || $admin_user_privilege) ? '<h2>' . __('Shifts') . '</h2>' : '',
$myshifts_table, $myshifts_table,
@ -710,7 +712,7 @@ function User_view_state($admin_user_privilege, $freeloader, $user_source)
$state = User_view_state_user($user_source); $state = User_view_state_user($user_source);
} }
return div('col-md-3', [ return div('col-md-2', [
heading(__('User state'), 4), heading(__('User state'), 4),
join('<br>', $state) join('<br>', $state)
]); ]);
@ -815,7 +817,7 @@ function User_angeltypes_render($user_angeltypes)
. ($angeltype['supporter'] ? glyph('education') : '') . $angeltype['name'] . ($angeltype['supporter'] ? glyph('education') : '') . $angeltype['name']
. '</a>'; . '</a>';
} }
return div('col-md-3', [ return div('col-md-2', [
heading(__('Angeltypes'), 4), heading(__('Angeltypes'), 4),
join('<br>', $output) join('<br>', $output)
]); ]);
@ -833,12 +835,35 @@ function User_groups_render($user_groups)
$output[] = __($groupName); $output[] = __($groupName);
} }
return div('col-md-3', [ return div('col-md-2', [
'<h4>' . __('Rights') . '</h4>', '<h4>' . __('Rights') . '</h4>',
join('<br>', $output) join('<br>', $output)
]); ]);
} }
/**
* @param User $user
* @return string
*/
function User_oauth_render(User $user)
{
$config = config('oauth');
$output = [];
foreach ($user->oauth as $oauth) {
$output[] = __(
isset($config[$oauth->provider]['name'])
? $config[$oauth->provider]['name']
: Str::ucfirst($oauth->provider)
);
}
return div('col-md-2', [
heading(__('OAuth'), 4),
join('<br>', $output),
]);
}
/** /**
* Render a user nickname. * Render a user nickname.
* *

View File

@ -67,9 +67,12 @@
</div> </div>
<div class="form-group btn-group btn-group-justified"> <div class="form-group btn-group btn-group-justified">
{% for type,config in config('oauth') %} {% for name,config in config('oauth') %}
<a href="{{ url('oauth/' ~ type) }}" class="btn btn-primary btn-lg{% if config.hidden|default(false) %} hidden{% endif %}"> <a href="{{ url('oauth/' ~ name) }}" class="btn btn-primary btn-lg{% if config.hidden|default(false) %} hidden{% endif %}">
{{ __('oauth.login-using-provider', [type|capitalize]) }} {{ __(
'oauth.login-using-provider',
[__(config.name|default(name|capitalize))]
) }}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -14,9 +14,11 @@
<tr{% if config.hidden|default(false) %} class="hidden"{% endif %}> <tr{% if config.hidden|default(false) %} class="hidden"{% endif %}>
<th> <th>
{% if config.url|default %} {% if config.url|default %}
<a href="{{ config.url }}" target="_blank" rel="noopener">{{ name|capitalize }}</a> <a href="{{ config.url }}" target="_blank" rel="noopener">
{{ __(config.name|default(name|capitalize)) }}
</a>
{% else %} {% else %}
{{ name|capitalize }} {{ __(config.name|default(name|capitalize)) }}
{% endif %} {% endif %}
</th> </th>
<td> <td>

View File

@ -71,12 +71,20 @@ class Controller extends BaseController
$userTshirtSizes = $this->formatStats($this->stats->tshirtSizes(), 'tshirt_sizes', 'shirt_size', 'size'); $userTshirtSizes = $this->formatStats($this->stats->tshirtSizes(), 'tshirt_sizes', 'shirt_size', 'size');
$userLocales = $this->formatStats($this->stats->languages(), 'locales', 'language', 'locale'); $userLocales = $this->formatStats($this->stats->languages(), 'locales', 'language', 'locale');
$userThemes = $this->formatStats($this->stats->themes(), 'available_themes', 'theme'); $userThemes = $this->formatStats($this->stats->themes(), 'available_themes', 'theme');
$userOauth = $this->formatStats($this->stats->oauth(), 'oauth', 'provider');
$themes = $this->config->get('available_themes'); $themes = $this->config->get('available_themes');
foreach ($userThemes as $key => $theme) { foreach ($userThemes as $key => $theme) {
$userThemes[$key]['labels']['name'] = $themes[$theme['labels']['theme']]; $userThemes[$key]['labels']['name'] = $themes[$theme['labels']['theme']];
} }
$oauthProviders = $this->config->get('oauth');
foreach ($userOauth as $key => $oauth) {
$provider = $oauth['labels']['provider'];
$name = isset($oauthProviders[$provider]['name']) ? $oauthProviders[$provider]['name'] : $provider;
$userOauth[$key]['labels']['name'] = $name;
}
$data = [ $data = [
$this->config->get('app_name') . ' stats', $this->config->get('app_name') . ' stats',
'info' => [ 'info' => [
@ -173,6 +181,7 @@ class Controller extends BaseController
['labels' => ['type' => 'write'], 'value' => $this->stats->databaseWrite()], ['labels' => ['type' => 'write'], 'value' => $this->stats->databaseWrite()],
], ],
'sessions' => ['type' => 'gauge', $this->stats->sessions()], 'sessions' => ['type' => 'gauge', $this->stats->sessions()],
'oauth' => ['type' => 'gauge', 'help' => 'The configured OAuth providers'] + $userOauth,
'log_entries' => [ 'log_entries' => [
'type' => 'counter', 'type' => 'counter',
[ [

View File

@ -11,6 +11,7 @@ use Engelsystem\Models\LogEntry;
use Engelsystem\Models\Message; use Engelsystem\Models\Message;
use Engelsystem\Models\News; use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment; use Engelsystem\Models\NewsComment;
use Engelsystem\Models\OAuth;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\User\PasswordReset; use Engelsystem\Models\User\PasswordReset;
@ -430,6 +431,17 @@ class Stats
->count(); ->count();
} }
/**
* @return Collection
*/
public function oauth(): Collection
{
return OAuth::query()
->select(['provider', $this->raw('COUNT(provider) AS count')])
->groupBy(['provider'])
->get();
}
/** /**
* @return float * @return float
*/ */

View File

@ -62,6 +62,7 @@ class ControllerTest extends TestCase
$this->assertArrayHasKey('registration_enabled', $data); $this->assertArrayHasKey('registration_enabled', $data);
$this->assertArrayHasKey('database', $data); $this->assertArrayHasKey('database', $data);
$this->assertArrayHasKey('sessions', $data); $this->assertArrayHasKey('sessions', $data);
$this->assertArrayHasKey('oauth', $data);
$this->assertArrayHasKey('log_entries', $data); $this->assertArrayHasKey('log_entries', $data);
$this->assertArrayHasKey('scrape_duration_seconds', $data); $this->assertArrayHasKey('scrape_duration_seconds', $data);
@ -133,6 +134,9 @@ class ControllerTest extends TestCase
$this->setExpects($stats, 'themes', null, new Collection([ $this->setExpects($stats, 'themes', null, new Collection([
['theme' => '1', 'count' => 3], ['theme' => '1', 'count' => 3],
])); ]));
$this->setExpects($stats, 'oauth', null, new Collection([
['provider' => 'test', 'count' => 2],
]));
$this->setExpects($stats, 'shifts', null, 142); $this->setExpects($stats, 'shifts', null, 142);
$this->setExpects($stats, 'messages', null, 3); $this->setExpects($stats, 'messages', null, 3);
$this->setExpects($stats, 'passwordResets', null, 1); $this->setExpects($stats, 'passwordResets', null, 1);
@ -153,7 +157,10 @@ class ControllerTest extends TestCase
]); ]);
$config->set('metrics', [ $config->set('metrics', [
'work' => [60 * 60], 'work' => [60 * 60],
'voucher' => [1] 'voucher' => [1],
]);
$config->set('oauth', [
'test' => ['name' => 'Test'],
]); ]);
$this->setExpects($version, 'getVersion', [], '0.42.42'); $this->setExpects($version, 'getVersion', [], '0.42.42');

View File

@ -8,6 +8,7 @@ use Engelsystem\Models\LogEntry;
use Engelsystem\Models\Message; use Engelsystem\Models\Message;
use Engelsystem\Models\News; use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment; use Engelsystem\Models\NewsComment;
use Engelsystem\Models\OAuth;
use Engelsystem\Models\Question; use Engelsystem\Models\Question;
use Engelsystem\Models\Room; use Engelsystem\Models\Room;
use Engelsystem\Models\User\PasswordReset; use Engelsystem\Models\User\PasswordReset;
@ -284,6 +285,30 @@ class StatsTest extends TestCase
$this->assertEquals(4, $stats->sessions()); $this->assertEquals(4, $stats->sessions());
} }
/**
* @covers \Engelsystem\Controllers\Metrics\Stats::oauth
*/
public function testOauth()
{
$this->addUsers();
$user1 = User::find(1);
$user2 = User::find(2);
$user3 = User::find(3);
(new OAuth(['provider' => 'test', 'identifier' => '1']))->user()->associate($user1)->save();
(new OAuth(['provider' => 'test', 'identifier' => '2']))->user()->associate($user2)->save();
(new OAuth(['provider' => 'another-provider', 'identifier' => 'usr3']))->user()->associate($user3)->save();
$stats = new Stats($this->database);
$oauth = $stats->oauth();
$this->assertCount(2, $oauth);
$this->assertEquals([
['provider' => 'another-provider', 'count' => 1],
['provider' => 'test', 'count' => 2],
], $oauth->toArray());
}
/** /**
* @covers \Engelsystem\Controllers\Metrics\Stats::databaseRead * @covers \Engelsystem\Controllers\Metrics\Stats::databaseRead
* @covers \Engelsystem\Controllers\Metrics\Stats::databaseWrite * @covers \Engelsystem\Controllers\Metrics\Stats::databaseWrite