Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.86% covered (warning)
79.86%
115 / 144
75.00% covered (warning)
75.00%
9 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccessSet
79.86% covered (warning)
79.86%
115 / 144
75.00% covered (warning)
75.00%
9 / 12
38.85
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 createFromPersonSession
81.82% covered (warning)
81.82%
27 / 33
0.00% covered (danger)
0.00%
0 / 1
9.49
 createFromAdminToken
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
2
 createFromLoginSession
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 jsonSerialize
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 getDisplayName
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasAccessType
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addAccessObjects
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 addTests
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 addGroupMonitors
50.00% covered (danger)
50.00%
10 / 20
0.00% covered (danger)
0.00%
0 / 1
10.50
 addStudyMonitor
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 addSystemChecks
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/** @noinspection PhpUnhandledExceptionInspection */
4declare(strict_types=1);
5
6// TODO add unit-tests
7
8class AccessSet extends DataCollectionTypeSafe {
9
10  protected string $token;
11  protected string $displayName;
12  protected ?int $id;
13  protected ?bool $pwSetByAdmin;
14  protected object $customTexts;
15  protected array $flags;
16  protected object $claims;
17  protected ?string $groupToken;
18
19  public function __construct(
20    string $token,
21    string $displayName,
22    array $flags = [],
23    stdClass $customTexts = null,
24    ?string $groupToken = null,
25    ?int $id = null,
26    ?bool $pwSetByAdmin = null
27  ) {
28    $this->token = $token;
29    $this->displayName = $displayName;
30    $this->flags = array_map(function ($flag) {
31      return (string) $flag;
32    }, $flags);
33    $this->claims = (object) [];
34    $this->customTexts = $customTexts ?? (object) [];
35    $this->groupToken = $groupToken;
36    $this->id = $id ?? null;
37    $this->pwSetByAdmin = $pwSetByAdmin;
38  }
39
40  static function createFromPersonSession(
41    PersonSession $loginWithPerson,
42    WorkspaceData|TestData|Group|SystemCheck ...$accessItems
43  ): AccessSet {
44    $login = $loginWithPerson->getLoginSession()->getLogin();
45
46    $displayName = self::getDisplayName(
47      $login->getGroupLabel(),
48      $login->getName(),
49      $loginWithPerson->getPerson()->getNameSuffix()
50    );
51
52    $accessSet = new AccessSet(
53      $loginWithPerson->getPerson()->getToken(),
54      $displayName,
55      [],
56      $login->getCustomTexts() ?? new stdClass()
57    );
58
59    $accessSet->groupToken = $loginWithPerson->getLoginSession()->getGroupToken();
60
61    foreach ($accessItems as $accessItem) {
62      switch (get_class($accessItem)) {
63        case 'WorkspaceData':
64          if ($login->getMode() == 'monitor-study') {
65            $accessSet->addStudyMonitor($accessItem);
66          }
67          break;
68        case 'Group':
69          $accessSet->addGroupMonitors($login, $accessItem);
70          break;
71        case 'TestData':
72          $accessSet->addTests($accessItem);
73          break;
74        case 'SystemCheck':
75          $accessSet->addSystemChecks($accessItem);
76      }
77    }
78
79    if (($login->getMode() == 'monitor-group') and str_starts_with($login->getGroupName(), 'experimental')) {
80      $accessSet->addAccessObjects(
81        AccessObjectType::ATTACHMENT_MANAGER,
82        new AccessObject($login->getGroupName(), AccessObjectType::ATTACHMENT_MANAGER, $login->getGroupLabel())
83      );
84    }
85
86    return $accessSet;
87  }
88
89  static function createFromAdminToken(Admin $admin, WorkspaceData ...$workspaces): AccessSet {
90    $accessSet = new AccessSet(
91      token: $admin->getToken(),
92      displayName: $admin->getName(),
93      id: $admin->getId(),
94      pwSetByAdmin: $admin->isPwSetByAdmin(),
95    );
96
97    $accessObjects = array_map(
98      function (WorkspaceData $workspace): AccessObject {
99        return new AccessObject(
100          (string) $workspace->getId(),
101          AccessObjectType::WORKSPACE_ADMIN,
102          $workspace->getName(),
103          ["mode" => $workspace->getMode()]
104        );
105      },
106      $workspaces
107    );
108
109    $accessSet->addAccessObjects(AccessObjectType::WORKSPACE_ADMIN, ...$accessObjects);
110
111    if ($admin->isSuperadmin()) {
112      $accessSet->addAccessObjects(AccessObjectType::SUPER_ADMIN);
113    }
114
115    return $accessSet;
116  }
117
118  static function createFromLoginSession(LoginSession $loginSession): AccessSet {
119    return new AccessSet(
120      $loginSession->getToken(),
121      "{$loginSession->getLogin()->getGroupLabel()}/{$loginSession->getLogin()->getName()}",
122      $loginSession->getLogin()->isCodeRequired() ? ['codeRequired'] : [],
123      $loginSession->getLogin()->getCustomTexts(),
124      $loginSession->getGroupToken()
125    );
126  }
127
128  function jsonSerialize(): mixed {
129    $json = parent::jsonSerialize();
130    $deprecatedFormat = (object) [];
131    foreach ($this->claims as $accessType => $accessObjectList) {
132      $deprecatedFormat->$accessType = [];
133
134      foreach ($accessObjectList as $accessObject) {
135        /** @var $accessObject AccessObject */
136        $deprecatedFormat->$accessType[] = $accessObject->id;
137      }
138    }
139    $json['access'] = $deprecatedFormat;
140    return $json;
141  }
142
143  static function getDisplayName(string $groupLabel, string $loginName, ?string $nameSuffix): string {
144    $displayName = "$groupLabel/$loginName";
145    $displayName .= $nameSuffix ? '/' . $nameSuffix : '';
146    return $displayName;
147  }
148
149  public function hasAccessType(AccessObjectType $type): bool {
150    $accessType = $type->value;
151    return isset($this->claims->$accessType);
152  }
153
154  private function addAccessObjects(AccessObjectType $type, AccessObject ...$accessObjects): void {
155    $accessType = $type->value;
156    if (!isset($this->claims->$accessType)) {
157      $this->claims->$accessType = [];
158    }
159
160    array_push($this->claims->$accessType, ...$accessObjects);
161  }
162
163  private function addTests(TestData ...$testsOfPerson): void {
164    $bookletsData = array_map(
165      function (TestData $testData): AccessObject {
166        return new AccessObject(
167          $testData->bookletId,
168          AccessObjectType::TEST,
169          $testData->label,
170          [
171            'locked' => $testData->locked,
172            'running' => $testData->running
173          ]
174        );
175      },
176      $testsOfPerson
177    );
178    $this->addAccessObjects(AccessObjectType::TEST, ...$bookletsData);
179  }
180
181  private function addGroupMonitors(Login $login, Group ...$groups): void {
182    $profiles = $login->getProfiles();
183
184    foreach ($groups as $group) {
185      $flags = [];
186      if ($group->_expired->type == ExpirationStateType::Expired) {
187        $flags['expired'] = $group->_expired->timestamp * 1000;
188      } else if ($group->_expired->type == ExpirationStateType::Scheduled) {
189        $flags['scheduled'] = $group->_expired->timestamp * 1000;
190      }
191      if (count($profiles)) {
192        foreach ($profiles as $profile) {
193          $profileFlags = $flags;
194          $profileFlags['profile'] = $profile['id'];
195          $profileFlags['subLabel'] = $profile['label'];
196          $this->addAccessObjects(
197            AccessObjectType::TEST_GROUP_MONITOR,
198            new AccessObject($group->name, AccessObjectType::TEST_GROUP_MONITOR, $group->label, $profileFlags)
199          );
200        }
201      } else {
202        $this->addAccessObjects(
203          AccessObjectType::TEST_GROUP_MONITOR,
204          new AccessObject($group->name, AccessObjectType::TEST_GROUP_MONITOR, $group->label, $flags)
205        );
206      }
207    }
208  }
209
210  private function addStudyMonitor(WorkspaceData $accessItem): void {
211    $this->addAccessObjects(
212      AccessObjectType::STUDY_MONITOR,
213      new AccessObject(
214        (string) $accessItem->getId(),
215        AccessObjectType::STUDY_MONITOR,
216        $accessItem->getName()
217      )
218    );
219  }
220
221  private function addSystemChecks(SystemCheck ...$accessItems): void {
222    $systemChecks = array_map(
223      function (SystemCheck $systemCheck) {
224        return new SystemCheckAccessObject(
225          $systemCheck->getWorkspaceId(),
226          $systemCheck->getId(),
227          AccessObjectType::SYS_CHECK,
228          $systemCheck->getLabel(),
229          $systemCheck->getDescription()
230        );
231      },
232      $accessItems
233    );
234
235    $this->addAccessObjects(AccessObjectType::SYS_CHECK, ...$systemChecks);
236  }
237}