aboutsummaryrefslogtreecommitdiff
path: root/app/controllers/api/oauth2/applications.php
blob: fd6a1bb7b7508eef3703ff98734b24b412a0ce69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php
use Studip\OAuth2\Models\AccessToken;
use Studip\OAuth2\Models\Scope;

/**
 * @property array $applications
 */
class Api_Oauth2_ApplicationsController extends AuthenticatedController
{
    public function index_action(): void
    {
        Navigation::activateItem('/profile/settings/oauth2');
        PageLayout::setTitle(_('Autorisierte Drittanwendungen'));
        Helpbar::get()->addPlainText(
            _('Autorisierte Drittanwendungen'),
            _("Sie können Ihren Stud.IP-Zugang über OAuth mit Anwendungen von Drittanbietern verbinden.\n\nWenn Sie eine OAuth-App autorisieren, sollten Sie sicherstellen, dass Sie der Anwendung vertrauen, überprüfen, wer sie entwickelt hat, und die Art der Informationen überprüfen, auf die die Anwendung zugreifen möchte.")
        );

        $user = User::findCurrent();
        $this->applications = $this->getApplications($user);
    }

    public function details_action(AccessToken $accessToken): void
    {
        $user = User::findCurrent();
        if ($accessToken['user_id'] !== $user->id) {
            throw new AccessDeniedException();
        }

        PageLayout::setTitle(_('Autorisierte OAuth2-Drittanwendung'));
        $this->application = $this->formatApplication($accessToken);

        if (!$this->application) {
            throw new Trails\Exception(500, 'Error finding client.');
        }
    }

    public function revoke_action(): void
    {
        CSRFProtection::verifyUnsafeRequest();

        $user = User::findCurrent();
        $accessToken = AccessToken::find(Request::option('application'));
        if (!$accessToken) {
            throw new Trails\Exception(404);
        }
        if ($accessToken['user_id'] !== $user->id) {
            throw new AccessDeniedException();
        }

        $accessToken->revoke();

        $this->redirect('api/oauth2/applications');
    }

    private function getApplications(User $user): array
    {
        return array_reduce(
            AccessToken::findValidTokens($user),
            function ($applications, $accessToken) {
                $application = $this->formatApplication($accessToken);
                if ($application) {
                    $applications[] = $application;
                }

                return $applications;
            },
            []
        );
    }

    private function formatApplication(AccessToken $accessToken): ?array
    {
        $allScopes = Scope::scopes();

        if (!$accessToken->client) {
            return null;
        }

        return [
            'id'          => $accessToken['id'],
            'name'        => $accessToken->client['name'],
            'description' => $accessToken->client['description'],
            'owner'       => $accessToken->client['owner'],
            'homepage'    => $accessToken->client['homepage'],
            'created'     => new DateTime('@' . $accessToken->client['mkdate']),

            'scopes' => array_reduce(
                json_decode($accessToken['scopes']),
                function ($scopes, $scopeIdentifier) use ($allScopes) {
                    if (isset($allScopes[$scopeIdentifier])) {
                        $scopes[] = $allScopes[$scopeIdentifier];
                    }

                    return $scopes;
                },
                []
            )
        ];
    }
}