Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
OAuth2
100.00% covered (success)
100.00%
56 / 56
100.00% covered (success)
100.00%
4 / 4
14
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 login
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 getSsoTeams
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 syncTeams
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Events\Listener;
6
7use Engelsystem\Config\Config;
8use Engelsystem\Helpers\Authenticator;
9use Engelsystem\Models\AngelType;
10use Engelsystem\Models\User\User;
11use Illuminate\Support\Arr;
12use Illuminate\Support\Collection;
13use Psr\Log\LoggerInterface;
14
15class OAuth2
16{
17    protected array $config;
18
19    public function __construct(Config $config, protected LoggerInterface $log, protected Authenticator $auth)
20    {
21        $this->config = $config->get('oauth');
22    }
23
24    /**
25     * @param string     $provider OAuth provider name
26     * @param Collection $data OAuth userdata
27     */
28    public function login(string $event, string $provider, Collection $data): void
29    {
30        $user = $this->auth->user();
31        $ssoTeams = $this->getSsoTeams($provider);
32        $groupsKey = ($this->config[$provider] ?? [])['groups'] ?? 'groups';
33        $userGroups = $data->get($groupsKey, []);
34
35        foreach ($userGroups as $groupName) {
36            if (!isset($ssoTeams[$groupName])) {
37                continue;
38            }
39
40            $this->syncTeams($provider, $user, $ssoTeams[$groupName]);
41        }
42    }
43
44    public function getSsoTeams(string $provider): array
45    {
46        $config = $this->config[$provider] ?? [];
47
48        $teams = [];
49        foreach ($config['teams'] ?? [] as $ssoName => $conf) {
50            $conf = Arr::wrap($conf);
51            $teamId = $conf['id'] ?? $conf[0];
52            $isSupporter = $conf['supporter'] ?? false;
53
54            $teams[$ssoName] = ['id' => $teamId, 'supporter' => $isSupporter];
55        }
56
57        return $teams;
58    }
59
60    protected function syncTeams(string $providerName, User $user, array $ssoTeam): void
61    {
62        $currentUserAngeltypes = $user->userAngelTypes;
63        $angelType = AngelType::find($ssoTeam['id']);
64        /** @var AngelType $userAngeltype */
65        $userAngeltype = $currentUserAngeltypes->where('pivot.angel_type_id', $ssoTeam['id'])->first();
66        $supporter = $ssoTeam['supporter'];
67        $confirmed = $supporter ? $user->id : null;
68
69        if (!$userAngeltype) {
70            $this->log->info(
71                'SSO {provider}: Added to angeltype {angeltype}, confirmed: {confirmed}, supporter: {supporter}',
72                [
73                    'provider'  => $providerName,
74                    'angeltype' => $angelType->name,
75                    'confirmed' => $confirmed ? 'yes' : 'no',
76                    'supporter' => $supporter ? 'yes' : 'no',
77                ]
78            );
79
80            $user->userAngelTypes()->attach($angelType, ['supporter' => $supporter, 'confirm_user_id' => $confirmed]);
81
82            return;
83        }
84
85        if (!$supporter) {
86            return;
87        }
88
89        if ($userAngeltype->pivot->supporter != $supporter) {
90            $userAngeltype->pivot->supporter = $supporter;
91            $userAngeltype->pivot->save();
92
93            $this->log->info(
94                'SSO {provider}: Set supporter state for angeltype {angeltype}',
95                [
96                    'provider'  => $providerName,
97                    'angeltype' => $userAngeltype->pivot->angelType->name,
98                ]
99            );
100        }
101
102        if (!$userAngeltype->pivot->confirm_user_id) {
103            $userAngeltype->pivot->confirmUser()->associate($user);
104            $userAngeltype->pivot->save();
105            $this->log->info(
106                'SSO {provider}: Set confirmed state for angeltype {angeltype}',
107                [
108                    'provider'  => $providerName,
109                    'angeltype' => $userAngeltype->pivot->angelType->name,
110                ]
111            );
112        }
113    }
114}