Passed
Pull Request — master (#1307)
by René
03:59
created

SystemService::validateEmailAddress()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 2
crap 20
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Vinzenz Rosenkranz <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Service;
25
26
use OCA\Polls\Exceptions\TooShortException;
27
use OCA\Polls\Exceptions\InvalidUsernameException;
28
use OCA\Polls\Exceptions\InvalidEmailAddress;
29
30
use OCA\Polls\Db\ShareMapper;
31
use OCA\Polls\Db\VoteMapper;
32
use OCA\Polls\Model\Circle;
33
use OCA\Polls\Model\Contact;
34
use OCA\Polls\Model\ContactGroup;
35
use OCA\Polls\Model\Email;
36
use OCA\Polls\Model\Group;
37
use OCA\Polls\Model\User;
38
use OCA\Polls\Model\UserGroupClass;
39
40
class SystemService {
41
42
	/** @var VoteMapper */
43
	private $voteMapper;
44
45
	/** @var ShareMapper */
46
	private $shareMapper;
47
48
	public function __construct(
49
		VoteMapper $voteMapper,
50
		ShareMapper $shareMapper
51
	) {
52
		$this->voteMapper = $voteMapper;
53
		$this->shareMapper = $shareMapper;
54
	}
55
56
	/**
57
	 * 	 * Validate string as email address
58
	 *
59
	 * @return bool
60
	 */
61
	private static function isValidEmail(string $emailAddress): bool {
62
		return (!preg_match('/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/', $emailAddress)) ? false : true;
63
	}
64
65
	/**
66
	 * 	 * Validate email address and throw an exception
67
	 * 	 * return true, if email address is a valid
68
	 *
69
	 * @return true
70
	 */
71
	public static function validateEmailAddress(string $emailAddress, bool $emptyIsValid = false): bool {
72
		if (!$emailAddress && $emptyIsValid) {
73
			return true;
74
		} elseif (!self::isValidEmail($emailAddress)) {
75
			throw new InvalidEmailAddress;
76
		}
77
		return true;
78
	}
79
80
	/**
81
	 * Get a list of users
82
	 * @param string[] $skip
83
	 */
84
	public static function getSiteUsers(string $query = '', array $skip = []) {
85
		$users = [];
86
		foreach (\OC::$server->getUserManager()->searchDisplayName($query) as $user) {
87
			if (!in_array($user->getUID(), $skip) && $user->isEnabled()) {
88
				$users[] = new User($user->getUID());
89
			}
90
		}
91
		return $users;
92
	}
93
94
	/**
95
	 * 	 * Get a combined list of users, groups, circles, contact groups and contacts
96
	 *
97
	 * @return (Circle|Email|Group|User|Contact|ContactGroup|mixed)[]
98
	 *
99
	 * @psalm-return array<array-key, Circle|Email|Group|User|Contact|ContactGroup|mixed>
100
	 */
101
	public function getSiteUsersAndGroups(
102
		string $query = '',
103
		bool $getGroups = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getGroups is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

103
		/** @scrutinizer ignore-unused */ bool $getGroups = true,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
104
		bool $getUsers = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getUsers is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

104
		/** @scrutinizer ignore-unused */ bool $getUsers = true,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
105
		bool $getContacts = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getContacts is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

105
		/** @scrutinizer ignore-unused */ bool $getContacts = true,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
106
		bool $getContactGroups = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getContactGroups is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

106
		/** @scrutinizer ignore-unused */ bool $getContactGroups = true,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
107
		bool $getMail = true,
0 ignored issues
show
Unused Code introduced by
The parameter $getMail is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

107
		/** @scrutinizer ignore-unused */ bool $getMail = true,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
108
		array $skipGroups = [],
0 ignored issues
show
Unused Code introduced by
The parameter $skipGroups is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

108
		/** @scrutinizer ignore-unused */ array $skipGroups = [],

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
109
		array $skipUsers = []
0 ignored issues
show
Unused Code introduced by
The parameter $skipUsers is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

109
		/** @scrutinizer ignore-unused */ array $skipUsers = []

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
110
	): array {
111
		$list = [];
112
		if ($query !== '') {
113
			if (self::isValidEmail($query)) {
114
				$list[] = new Email($query);
115
			}
116
117
			$list = array_merge($list, UserGroupClass::search($query));
118
		}
119
120
		return $list;
121
	}
122
123
	/**
124
	 * 	 * Validate it the user name is reserved
125
	 * 	 * return false, if this username already exists as a user or as
126
	 * 	 * a participant of the poll
127
	 *
128
	 * @return true
129
	 */
130
	public function validatePublicUsername(string $userName, string $token): bool {
131
		$share = $this->shareMapper->findByToken($token);
132
133
		if ($share->getDisplayName() === $userName) {
134
			return true;
135
		}
136
137
		$userName = strtolower(trim($userName));
138
139
		// return forbidden, if the length of the userame is lower than 3 characters
140
		if (strlen($userName) < 3) {
141
			throw new TooShortException('Username must have at least 3 characters');
142
		}
143
144
		// get all groups
145
		foreach (Group::search() as $group) {
146
			if ($userName === strtolower(trim($group->getId()))
147
				|| $userName === strtolower(trim($group->getDisplayName()))) {
148
				throw new InvalidUsernameException;
149
			}
150
		}
151
152
		// get all users
153
		foreach (User::search() as $user) {
154
			if ($userName === strtolower(trim($user->getId()))
155
				|| $userName === strtolower(trim($user->getDisplayName()))) {
156
				throw new InvalidUsernameException;
157
			}
158
		}
159
160
		// get all participants
161
		foreach ($this->voteMapper->findParticipantsByPoll($share->getPollId()) as $vote) {
162
			if ($vote->getUserId()) {
163
				if ($userName === strtolower(trim($vote->getUserId()))) {
164
					throw new InvalidUsernameException;
165
				}
166
			}
167
		}
168
169
		// get all shares for this poll
170
		foreach ($this->shareMapper->findByPoll($share->getPollId()) as $share) {
171
			if ($share->getUserId() && $share->getType() !== Circle::TYPE) {
172
				if ($userName === strtolower(trim($share->getUserId()))
173
					|| $userName === strtolower(trim($share->getDisplayName()))) {
174
					throw new InvalidUsernameException;
175
				}
176
			}
177
		}
178
		// return true, if username is allowed
179
		return true;
180
	}
181
}
182