Lines 96.66% 58 / 60
Functions and Methods 50.00% 2 / 4
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
UseraccountEdit 96.66% 58 / 60 50.00% 2 / 4 15 0.00% 0 / 1
 readResponse 97.67% 42 / 43 0.00% 0 / 1 10
 writeUpdatedEntity 100.00% 7 / 7 100.00% 1 / 1 1
 loadRoleList 100.00% 6 / 6 100.00% 1 / 1 2
 hasSuperuserOnlyRole 75.00% 3 / 4 0.00% 0 / 1 2.06
1<?php
2
3/**
4 *
5 * @package Zmsadmin
6 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
7 *
8 */
9
10namespace BO\Zmsadmin;
11
12use BO\Slim\Render;
13use BO\Mellon\Validator;
14use BO\Zmsentities\Collection\RoleList;
15use BO\Zmsentities\Exception\UserAccountMissingRights;
16use BO\Zmsentities\Exception\UserAccountAccessRightsFailed;
17use BO\Zmsentities\Schema\Loader;
18use BO\Zmsentities\Useraccount;
19
20class UseraccountEdit extends BaseController
21{
22    private const array SUPERUSER_ONLY_ROLES = [
23        'system_admin',
24        'audit_viewer',
25    ];
26
27    /**
28     *
29     * @return \Psr\Http\Message\ResponseInterface
30     */
31    #[\Override]
32    public function readResponse(
33        \Psr\Http\Message\RequestInterface $request,
34        \Psr\Http\Message\ResponseInterface $response,
35        array $args
36    ): \Psr\Http\Message\ResponseInterface {
37        $workstation = \App::$http->readGetResult('/workstation/', ['resolveReferences' => 1])->getEntity();
38        if (! $workstation->getUseraccount()->hasPermissions(['useraccount'])) {
39            throw new UserAccountMissingRights();
40        }
41
42        $userAccountName = Validator::value($args['loginname'])->isString()->getValue();
43        $confirmSuccess = $request->getAttribute('validator')->getParameter('success')->isString()->getValue();
44        $userAccount = \App::$http->readGetResult('/useraccount/' . $userAccountName . '/')->getEntity();
45        if (
46            ! $workstation->getUseraccount()->isSuperUser()
47            && $this->hasSuperuserOnlyRole($userAccount)
48        ) {
49            throw new UserAccountAccessRightsFailed();
50        }
51        $ownerList = \App::$http->readGetResult('/owner/', ['resolveReferences' => 2])->getCollection();
52
53        if ($request->getMethod() === 'POST') {
54            $input = $request->getParsedBody();
55            $result = $this->writeUpdatedEntity($input, $userAccountName);
56            if ($result instanceof Useraccount) {
57                return Render::redirect(
58                    'useraccountEdit',
59                    array('loginname' => $result->id),
60                    array('success' => 'useraccount_saved')
61                );
62            }
63        }
64
65        $config = \App::$http->readGetResult('/config/', [], \App::CONFIG_SECURE_TOKEN)->getEntity();
66        $allowedProviderList = explode(',', $config->getPreference('oidc', 'provider') ?? '');
67
68        $roleList = $this->loadRoleList();
69
70        $userAccountRoles = (isset($userAccount->roles) && is_array($userAccount->roles))
71            ? $userAccount->roles
72            : [];
73
74
75        return Render::withHtml(
76            $response,
77            'page/useraccountEdit.twig',
78            [
79                'debug' => \App::DEBUG,
80                'userAccount' => $userAccount,
81                'success' => $confirmSuccess,
82                'ownerList' => $ownerList ? $ownerList->toDepartmentListByOrganisationName() : [],
83                'workstation' => $workstation,
84                'title' => 'Nutzer: Einrichtung und Administration','menuActive' => 'useraccount',
85                'exception' => (isset($result)) ? $result : null,
86                'metadata' => $this->getSchemaConstraintList(Loader::asArray(Useraccount::$schema)),
87                'oidcProviderList' => array_filter($allowedProviderList),
88                'isFromOidc' => in_array($userAccount->getOidcProviderFromName(), $allowedProviderList),
89                'roleList' => $roleList,
90                'userAccountRoles' => $userAccountRoles,
91            ]
92        );
93    }
94
95    protected function writeUpdatedEntity($input, $userAccountName)
96    {
97        $entity = (new Useraccount($input))->withCleanedUpFormData();
98        // TODO: Remove the password fields when password authentication is removed in the future
99        $entity->setPassword($input);
100        return $this->handleEntityWrite(function () use ($entity, $userAccountName) {
101            return \App::$http
102                ->readPostResult('/useraccount/' . $userAccountName . '/', $entity)
103                ->getEntity();
104        });
105    }
106
107    private function loadRoleList(): RoleList
108    {
109        $roleList = new RoleList();
110
111        $roleResult = \App::$http->readGetResult('/roles/', []);
112        $loaded = $roleResult->getCollection();
113        if ($loaded !== null) {
114            $roleList = $loaded;
115        }
116
117        return $roleList;
118    }
119
120    protected function hasSuperuserOnlyRole(Useraccount $userAccount): bool
121    {
122        $roles = $userAccount->roles ?? [];
123
124        if (! is_array($roles)) {
125            return false;
126        }
127
128        return (bool) array_intersect($roles, self::SUPERUSER_ONLY_ROLES);
129    }
130}