Browse Source

Finish merge/upgrade

master
Skylar Ittner 7 months ago
parent
commit
28b8563ea0
5 changed files with 653 additions and 0 deletions
  1. 5
    0
      langs/en/actions.json
  2. 127
    0
      langs/en/strings.json
  3. 72
    0
      lib/Log.lib.php
  4. 137
    0
      lib/Report.lib.php
  5. 312
    0
      lib/User.lib.php

+ 5
- 0
langs/en/actions.json View File

@@ -0,0 +1,5 @@
1
+{
2
+    "Edit": "Edit",
3
+    "cancel": "Cancel",
4
+    "Choose a user": "Choose a user"
5
+}

+ 127
- 0
langs/en/strings.json View File

@@ -0,0 +1,127 @@
1
+{
2
+    "sign in": "Sign In",
3
+    "username": "Username",
4
+    "password": "Password",
5
+    "continue": "Continue",
6
+    "authcode": "Authentication code",
7
+    "2fa prompt": "Enter the six-digit code from your mobile authenticator app.",
8
+    "2fa incorrect": "Authentication code incorrect.",
9
+    "login incorrect": "Login incorrect.",
10
+    "no admin permission": "You do not have permission to access this system.",
11
+    "account locked": "This account has been disabled. Contact technical support.",
12
+    "password expired": "You must change your password before continuing.",
13
+    "account terminated": "Account terminated.  Access denied.",
14
+    "account state error": "Your account state is not stable.  Log out, restart your browser, and try again.",
15
+    "welcome user": "Welcome, {user}!",
16
+    "settings": "Settings",
17
+    "options": "Options",
18
+    "login server user data error": "The login server refused to provide account information.  Try again or contact technical support.",
19
+    "captcha error": "There was a problem with the CAPTCHA (robot test).  Try again.",
20
+    "home": "Home",
21
+    "users": "Users",
22
+    "more": "More",
23
+    "actions": "Actions",
24
+    "name": "Name",
25
+    "email": "Email",
26
+    "status": "Status",
27
+    "type": "Type",
28
+    "new user": "New User",
29
+    "total users": "Total Users",
30
+    "view users": "View Users",
31
+    "normal accounts": "Normal Accounts",
32
+    "locked accounts": "Locked Accounts",
33
+    "editing user": "Editing {user}",
34
+    "invalid userid": "Invalid user ID.",
35
+    "user saved": "User saved.",
36
+    "adding user": "Adding new user",
37
+    "placeholder name": "John Doe",
38
+    "placeholder username": "jdoe",
39
+    "placeholder email address": "jdoe@example.com",
40
+    "placeholder password": "swordfish",
41
+    "new password": "New Password",
42
+    "non-local account warning": "This account is not locally managed.  Changes made here will not synchronize to the directory server and some attributes cannot be edited.",
43
+    "delete user": "Delete User",
44
+    "really delete user": "Are you sure you want to delete this user?  This action cannot be reversed.",
45
+    "user deleted": "User account deleted.",
46
+    "user does not exist": "User does not exist.",
47
+    "logtime": "Date\/Time",
48
+    "logtype": "Event Type",
49
+    "ip address": "IP Address",
50
+    "other data": "Other",
51
+    "security log": "Security Log",
52
+    "event type reference": "Event Type Reference",
53
+    "clear log": "Clear Log",
54
+    "really clear log": "Are you sure you want to purge the security log?  This action cannot be reversed.",
55
+    "log cleared": "Security log cleared.",
56
+    "removed n entries": "Removed {n} entries",
57
+    "security log entries": "Security Log Entries",
58
+    "view security log": "View Security Log",
59
+    "managers": "Managers",
60
+    "manager": "Manager",
61
+    "employee": "Employee",
62
+    "delete relationship": "Delete Relationship",
63
+    "really delete relationship": "Are you sure you want to remove this manager-employee relationship?  This action cannot be reversed.",
64
+    "relationship deleted": "Relationship deleted.",
65
+    "edit relationship": "Edit Relationship",
66
+    "adding relationship": "Adding Relationship",
67
+    "relationship added": "Relationship added.",
68
+    "permissions": "Permissions",
69
+    "permission": "Permission",
70
+    "new permission": "New Permission",
71
+    "delete permission": "Delete Permission",
72
+    "adding permission": "Adding Permission",
73
+    "user": "User",
74
+    "permission does not exist": "Permission does not exist: {arg}",
75
+    "really delete permission": "Are you sure you want to revoke this permission?",
76
+    "permission added": "Permission assigned.",
77
+    "permission deleted": "Permission deleted.",
78
+    "remove 2fa": "Reset 2FA",
79
+    "action performed by": "Action performed by {user}",
80
+    "2fa removed": "2-factor authentication removed.",
81
+    "2fa": "2FA",
82
+    "show deleted": "Show deleted",
83
+    "editing deleted account": "You are editing an account marked as deleted.  The account will be undeleted if you press Save.",
84
+    "manager assigned": "Manager relationships saved.",
85
+    "manager does not exist": "The selected manager username does not exist.",
86
+    "type to add a person": "Type to add a person",
87
+    "employees": "Employees",
88
+    "type to select a manager": "Type to select a manager",
89
+    "select a manager to view or edit employees": "Select a manager to view or edit the assigned employees.",
90
+    "report export": "Reports\/Export",
91
+    "report type": "Report type",
92
+    "format": "Format",
93
+    "generate report": "Generate report",
94
+    "choose an option": "Choose an option",
95
+    "csv file": "CSV text file",
96
+    "ods file": "ODS spreadsheet",
97
+    "html file": "HTML web page",
98
+    "uid": "User ID",
99
+    "manager name": "Manager",
100
+    "manager username": "Mgr. Username",
101
+    "employee name": "Employee",
102
+    "employee username": "Emp. Username",
103
+    "permission id": "Perm. ID",
104
+    "permissions assigned": "Permissions assigned.",
105
+    "type to select a user": "Type to select a user",
106
+    "type to add a permission": "Type to add a permission",
107
+    "Choose a permission": "Choose a permission",
108
+    "select a user to view or edit permissions": "Select a user to view or edit the assigned permissions.",
109
+    "group": "Group",
110
+    "groups": "Groups",
111
+    "group does not exist": "That group does not exist.",
112
+    "group members updated": "Group members updated.",
113
+    "group added": "Group added.",
114
+    "group deleted": "Group deleted.",
115
+    "group already exists": "A group with that name already exists.",
116
+    "save": "Save",
117
+    "next": "Next",
118
+    "add": "Add",
119
+    "delete": "Delete",
120
+    "new group": "New group",
121
+    "delete group": "Delete group",
122
+    "enter group name": "Group name",
123
+    "group management": "Group Management",
124
+    "group assignments": "Group Assignments",
125
+    "group id": "Group ID",
126
+    "group name": "Group Name"
127
+}

+ 72
- 0
lib/Log.lib.php View File

@@ -0,0 +1,72 @@
1
+<?php
2
+
3
+/*
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
+ */
8
+
9
+class Log {
10
+
11
+    /**
12
+     *
13
+     * @global $database
14
+     * @param int/LogType $type Either an integer (as defined by the constants in class LogType) or a LogType object.
15
+     * @param int/User $user Either a UID number or a User object.
16
+     * @param string $data Extra data to include in the log, in addition to the timestamp, log type, user, and IP address.
17
+     */
18
+    public static function insert($type, $user, string $data = "") {
19
+        global $database;
20
+        // find IP address
21
+        $ip = IPUtils::getClientIP();
22
+        if (gettype($type) == "object" && is_a($type, "LogType")) {
23
+            $type = $type->getType();
24
+        }
25
+
26
+        if (is_a($user, "User")) {
27
+            $uid = $user->getUID();
28
+        } else if (gettype($user) == "integer") {
29
+            $uid = $user;
30
+        } else {
31
+            $uid = null;
32
+        }
33
+
34
+        $database->insert("authlog", ['logtime' => date("Y-m-d H:i:s"), 'logtype' => $type, 'uid' => $uid, 'ip' => $ip, 'otherdata' => $data]);
35
+    }
36
+
37
+}
38
+
39
+class LogType {
40
+
41
+    const LOGIN_OK = 1;
42
+    const LOGIN_FAILED = 2;
43
+    const PASSWORD_CHANGED = 3;
44
+    const API_LOGIN_OK = 4;
45
+    const API_LOGIN_FAILED = 5;
46
+    const BAD_2FA = 6;
47
+    const API_BAD_2FA = 7;
48
+    const BAD_CAPTCHA = 8;
49
+    const ADDED_2FA = 9;
50
+    const REMOVED_2FA = 10;
51
+    const LOGOUT = 11;
52
+    const API_AUTH_OK = 12;
53
+    const API_AUTH_FAILED = 13;
54
+    const API_BAD_KEY = 14;
55
+    const LOG_CLEARED = 15;
56
+    const USER_REMOVED = 16;
57
+    const USER_ADDED = 17;
58
+    const USER_EDITED = 18;
59
+    const MOBILE_LOGIN_OK = 19;
60
+    const MOBILE_LOGIN_FAILED = 20;
61
+    const MOBILE_BAD_KEY = 21;
62
+
63
+    private $type;
64
+
65
+    function __construct(int $type) {
66
+        $this->type = $type;
67
+    }
68
+
69
+    public function getType(): int {
70
+        return $type;
71
+    }
72
+}

+ 137
- 0
lib/Report.lib.php View File

@@ -0,0 +1,137 @@
1
+<?php
2
+
3
+/*
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
+ */
8
+
9
+use League\Csv\Writer;
10
+use League\Csv\HTMLConverter;
11
+use odsPhpGenerator\ods;
12
+use odsPhpGenerator\odsTable;
13
+use odsPhpGenerator\odsTableRow;
14
+use odsPhpGenerator\odsTableColumn;
15
+use odsPhpGenerator\odsTableCellString;
16
+use odsPhpGenerator\odsStyleTableColumn;
17
+use odsPhpGenerator\odsStyleTableCell;
18
+
19
+class Report {
20
+
21
+    private $title = "";
22
+    private $header = [];
23
+    private $data = [];
24
+
25
+    public function __construct(string $title = "", array $header = [], array $data = []) {
26
+        $this->title = $title;
27
+        $this->header = $header;
28
+        $this->data = $data;
29
+    }
30
+
31
+    public function setHeader(array $header) {
32
+        $this->header = $header;
33
+    }
34
+
35
+    public function addDataRow(array $columns) {
36
+        $this->data[] = $columns;
37
+    }
38
+
39
+    public function getHeader(): array {
40
+        return $this->header;
41
+    }
42
+
43
+    public function getData(): array {
44
+        return $this->data;
45
+    }
46
+
47
+    public function output(string $format) {
48
+        switch ($format) {
49
+            case "ods":
50
+                $this->toODS();
51
+                break;
52
+            case "html":
53
+                $this->toHTML();
54
+                break;
55
+            case "csv":
56
+            default:
57
+                $this->toCSV();
58
+                break;
59
+        }
60
+    }
61
+
62
+    private function toODS() {
63
+        $ods = new ods();
64
+        $styleColumn = new odsStyleTableColumn();
65
+        $styleColumn->setUseOptimalColumnWidth(true);
66
+        $headerstyle = new odsStyleTableCell();
67
+        $headerstyle->setFontWeight("bold");
68
+        $table = new odsTable($this->title);
69
+
70
+        for ($i = 0; $i < count($this->header); $i++) {
71
+            $table->addTableColumn(new odsTableColumn($styleColumn));
72
+        }
73
+
74
+        $row = new odsTableRow();
75
+        foreach ($this->header as $cell) {
76
+            $row->addCell(new odsTableCellString($cell, $headerstyle));
77
+        }
78
+        $table->addRow($row);
79
+
80
+        foreach ($this->data as $cols) {
81
+            $row = new odsTableRow();
82
+            foreach ($cols as $cell) {
83
+                $row->addCell(new odsTableCellString($cell));
84
+            }
85
+            $table->addRow($row);
86
+        }
87
+        $ods->addTable($table);
88
+        // The @ is a workaround to silence the tempnam notice,
89
+        // which breaks the file.  This is apparently the intended behavior:
90
+        // https://bugs.php.net/bug.php?id=69489
91
+        @$ods->downloadOdsFile($this->title . "_" . date("Y-m-d_Hi") . ".ods");
92
+    }
93
+
94
+    private function toHTML() {
95
+        global $SECURE_NONCE;
96
+        $data = array_merge([$this->header], $this->data);
97
+        // HTML exporter doesn't like null values
98
+        for ($i = 0; $i < count($data); $i++) {
99
+            for ($j = 0; $j < count($data[$i]); $j++) {
100
+                if (is_null($data[$i][$j])) {
101
+                    $data[$i][$j] = '';
102
+                }
103
+            }
104
+        }
105
+        header('Content-type: text/html');
106
+        $converter = new HTMLConverter();
107
+        $out = "<!DOCTYPE html>\n"
108
+                . "<meta charset=\"utf-8\">\n"
109
+                . "<meta name=\"viewport\" content=\"width=device-width\">\n"
110
+                . "<title>" . $this->title . "_" . date("Y-m-d_Hi") . "</title>\n"
111
+                . <<<STYLE
112
+<style nonce="$SECURE_NONCE">
113
+    .table-csv-data {
114
+        border-collapse: collapse;
115
+    }
116
+    .table-csv-data tr:first-child {
117
+        font-weight: bold;
118
+    }
119
+    .table-csv-data tr td {
120
+        border: 1px solid black;
121
+    }
122
+</style>
123
+STYLE
124
+                . $converter->convert($data);
125
+        echo $out;
126
+    }
127
+
128
+    private function toCSV() {
129
+        $csv = Writer::createFromString('');
130
+        $data = array_merge([$this->header], $this->data);
131
+        $csv->insertAll($data);
132
+        header('Content-type: text/csv');
133
+        header('Content-Disposition: attachment; filename="' . $this->title . "_" . date("Y-m-d_Hi") . ".csv" . '"');
134
+        echo $csv;
135
+    }
136
+
137
+}

+ 312
- 0
lib/User.lib.php View File

@@ -0,0 +1,312 @@
1
+<?php
2
+
3
+/*
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
+ */
8
+
9
+use Base32\Base32;
10
+use OTPHP\TOTP;
11
+
12
+class User {
13
+
14
+    private $uid = null;
15
+    private $username;
16
+    private $passhash;
17
+    private $email;
18
+    private $realname;
19
+    private $authsecret;
20
+    private $has2fa = false;
21
+    private $exists = false;
22
+
23
+    public function __construct(int $uid, string $username = "") {
24
+        global $database;
25
+        if ($database->has('accounts', ['AND' => ['uid' => $uid, 'deleted' => false]])) {
26
+            $this->uid = $uid;
27
+            $user = $database->get('accounts', ['username', 'password', 'email', 'realname', 'authsecret'], ['uid' => $uid]);
28
+            $this->username = $user['username'];
29
+            $this->passhash = $user['password'];
30
+            $this->email = $user['email'];
31
+            $this->realname = $user['realname'];
32
+            $this->authsecret = $user['authsecret'];
33
+            $this->has2fa = !empty($user['authsecret']);
34
+            $this->exists = true;
35
+        } else {
36
+            $this->uid = $uid;
37
+            $this->username = $username;
38
+        }
39
+    }
40
+
41
+    public static function byUsername(string $username): User {
42
+        global $database;
43
+        $username = strtolower($username);
44
+        if ($database->has('accounts', ['AND' => ['username' => $username, 'deleted' => false]])) {
45
+            $uid = $database->get('accounts', 'uid', ['username' => $username]);
46
+            return new self($uid * 1);
47
+        }
48
+        return new self(-1, $username);
49
+    }
50
+
51
+    /**
52
+     * Add a user to the system.  /!\ Assumes input is OK /!\
53
+     * @param string $username Username, saved in lowercase.
54
+     * @param string $password Password, will be hashed before saving.
55
+     * @param string $realname User's real legal name
56
+     * @param string $email User's email address.
57
+     * @param string $phone1 Phone number #1
58
+     * @param string $phone2 Phone number #2
59
+     * @param int $type Account type
60
+     * @return int The new user's ID number in the database.
61
+     */
62
+    public static function add(string $username, string $password, string $realname, string $email = null, string $phone1 = "", string $phone2 = "", int $type = 1): int {
63
+        global $database;
64
+        $database->insert('accounts', [
65
+            'username' => strtolower($username),
66
+            'password' => (is_null($password) ? null : password_hash($password, PASSWORD_BCRYPT)),
67
+            'realname' => $realname,
68
+            'email' => $email,
69
+            'phone1' => $phone1,
70
+            'phone2' => $phone2,
71
+            'acctstatus' => 1,
72
+            'accttype' => $type
73
+        ]);
74
+        return $database->id();
75
+    }
76
+
77
+    public function exists(): bool {
78
+        return $this->exists;
79
+    }
80
+
81
+    public function has2fa(): bool {
82
+        return $this->has2fa;
83
+    }
84
+
85
+    function getUsername() {
86
+        return $this->username;
87
+    }
88
+
89
+    function getUID() {
90
+        return $this->uid;
91
+    }
92
+
93
+    function getEmail() {
94
+        return $this->email;
95
+    }
96
+
97
+    function getName() {
98
+        return $this->realname;
99
+    }
100
+
101
+    /**
102
+     * Check the given plaintext password against the stored hash.
103
+     * @param string $password
104
+     * @return bool
105
+     */
106
+    function checkPassword(string $password): bool {
107
+        return password_verify($password, $this->passhash);
108
+    }
109
+
110
+    /**
111
+     * Change the user's password.
112
+     * @global $database $database
113
+     * @param string $old The current password
114
+     * @param string $new The new password
115
+     * @param string $new2 New password again
116
+     * @throws PasswordMatchException
117
+     * @throws PasswordMismatchException
118
+     * @throws IncorrectPasswordException
119
+     * @throws WeakPasswordException
120
+     */
121
+    function changePassword(string $old, string $new, string $new2) {
122
+        global $database, $SETTINGS;
123
+        if ($old == $new) {
124
+            throw new PasswordMatchException();
125
+        }
126
+        if ($new != $new2) {
127
+            throw new PasswordMismatchException();
128
+        }
129
+
130
+        if (!$this->checkPassword($old)) {
131
+            throw new IncorrectPasswordException();
132
+        }
133
+
134
+        require_once __DIR__ . "/worst_passwords.php";
135
+
136
+        $passrank = checkWorst500List($new);
137
+        if ($passrank !== FALSE) {
138
+            throw new WeakPasswordException();
139
+        }
140
+        if (strlen($new) < $SETTINGS['min_password_length']) {
141
+            throw new WeakPasswordException();
142
+        }
143
+
144
+        $database->update('accounts', ['password' => password_hash($new, PASSWORD_DEFAULT), 'acctstatus' => 1], ['uid' => $this->uid]);
145
+        Log::insert(LogType::PASSWORD_CHANGED, $this);
146
+        return true;
147
+    }
148
+
149
+    function check2fa(string $code): bool {
150
+        if (!$this->has2fa) {
151
+            return true;
152
+        }
153
+
154
+        $totp = new TOTP(null, $this->authsecret);
155
+        $time = time();
156
+        if ($totp->verify($code, $time)) {
157
+            return true;
158
+        }
159
+        if ($totp->verify($code, $time - 30)) {
160
+            return true;
161
+        }
162
+        if ($totp->verify($code, $time + 30)) {
163
+            return true;
164
+        }
165
+
166
+        return false;
167
+    }
168
+
169
+    /**
170
+     * Generate a TOTP secret for the given user.
171
+     * @return string OTP provisioning URI (for generating a QR code)
172
+     */
173
+    function generate2fa(): string {
174
+        global $SETTINGS;
175
+        $secret = random_bytes(20);
176
+        $encoded_secret = Base32::encode($secret);
177
+        $totp = new TOTP((empty($this->email) ? $this->realname : $this->email), $encoded_secret);
178
+        $totp->setIssuer($SETTINGS['system_name']);
179
+        return $totp->getProvisioningUri();
180
+    }
181
+
182
+    /**
183
+     * Save a TOTP secret for the user.
184
+     * @global $database $database
185
+     * @param string $username
186
+     * @param string $secret
187
+     */
188
+    function save2fa(string $secret) {
189
+        global $database;
190
+        $database->update('accounts', ['authsecret' => $secret], ['username' => $this->username]);
191
+    }
192
+
193
+    /**
194
+     * Check if the given username has the given permission (or admin access)
195
+     * @global $database $database
196
+     * @param string $code
197
+     * @return boolean TRUE if the user has the permission (or admin access), else FALSE
198
+     */
199
+    function hasPermission(string $code): bool {
200
+        global $database;
201
+        return $database->has('assigned_permissions', [
202
+                    '[>]permissions' => [
203
+                        'permid' => 'permid'
204
+                    ]
205
+                        ], ['AND' => ['OR' => ['permcode #code' => $code, 'permcode #admin' => 'ADMIN'], 'uid' => $this->uid]]) === TRUE;
206
+    }
207
+
208
+    /**
209
+     * Get the account status.
210
+     * @return \AccountStatus
211
+     */
212
+    function getStatus(): AccountStatus {
213
+        global $database;
214
+        $statuscode = $database->get('accounts', 'acctstatus', ['uid' => $this->uid]);
215
+        return new AccountStatus($statuscode);
216
+    }
217
+
218
+    function sendAlertEmail(string $appname = null) {
219
+        global $SETTINGS;
220
+        if (is_null($appname)) {
221
+            $appname = $SETTINGS['site_title'];
222
+        }
223
+        if (empty(ADMIN_EMAIL) || filter_var(ADMIN_EMAIL, FILTER_VALIDATE_EMAIL) === FALSE) {
224
+            return "invalid_to_email";
225
+        }
226
+        if (empty(FROM_EMAIL) || filter_var(FROM_EMAIL, FILTER_VALIDATE_EMAIL) === FALSE) {
227
+            return "invalid_from_email";
228
+        }
229
+
230
+        $mail = new PHPMailer;
231
+
232
+        if ($SETTINGS['debug']) {
233
+            $mail->SMTPDebug = 2;
234
+        }
235
+
236
+        if ($SETTINGS['email']['use_smtp']) {
237
+            $mail->isSMTP();
238
+            $mail->Host = $SETTINGS['email']['host'];
239
+            $mail->SMTPAuth = $SETTINGS['email']['auth'];
240
+            $mail->Username = $SETTINGS['email']['user'];
241
+            $mail->Password = $SETTINGS['email']['password'];
242
+            $mail->SMTPSecure = $SETTINGS['email']['secure'];
243
+            $mail->Port = $SETTINGS['email']['port'];
244
+            if ($SETTINGS['email']['allow_invalid_certificate']) {
245
+                $mail->SMTPOptions = array(
246
+                    'ssl' => array(
247
+                        'verify_peer' => false,
248
+                        'verify_peer_name' => false,
249
+                        'allow_self_signed' => true
250
+                    )
251
+                );
252
+            }
253
+        }
254
+
255
+        $mail->setFrom(FROM_EMAIL, 'Account Alerts');
256
+        $mail->addAddress(ADMIN_EMAIL, "System Admin");
257
+        $mail->isHTML(false);
258
+        $mail->Subject = $Strings->get("admin alert email subject", false);
259
+        $mail->Body = $Strings->build("admin alert email message", ["username" => $this->username, "datetime" => date("Y-m-d H:i:s"), "ipaddr" => IPUtils::getClientIP(), "appname" => $appname], false);
260
+
261
+        if (!$mail->send()) {
262
+            return $mail->ErrorInfo;
263
+        }
264
+        return true;
265
+    }
266
+
267
+}
268
+
269
+class AccountStatus {
270
+
271
+    const NORMAL = 1;
272
+    const LOCKED_OR_DISABLED = 2;
273
+    const CHANGE_PASSWORD = 3;
274
+    const TERMINATED = 4;
275
+    const ALERT_ON_ACCESS = 5;
276
+
277
+    private $status;
278
+
279
+    public function __construct(int $status) {
280
+        $this->status = $status;
281
+    }
282
+
283
+    /**
284
+     * Get the account status/state as an integer.
285
+     * @return int
286
+     */
287
+    public function get(): int {
288
+        return $this->status;
289
+    }
290
+
291
+    /**
292
+     * Get the account status/state as a string representation.
293
+     * @return string
294
+     */
295
+    public function getString(): string {
296
+        switch ($this->status) {
297
+            case self::NORMAL:
298
+                return "NORMAL";
299
+            case self::LOCKED_OR_DISABLED:
300
+                return "LOCKED_OR_DISABLED";
301
+            case self::CHANGE_PASSWORD:
302
+                return "CHANGE_PASSWORD";
303
+            case self::TERMINATED:
304
+                return "TERMINATED";
305
+            case self::ALERT_ON_ACCESS:
306
+                return "ALERT_ON_ACCESS";
307
+            default:
308
+                return "OTHER_" . $this->status;
309
+        }
310
+    }
311
+
312
+}

Loading…
Cancel
Save