Passed
Push — master ( 5b1d5e...6bc2f3 )
by Justin
03:53
created

LDAPClient::listGroupsOfUser()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 42
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 42
rs 8.8571
cc 3
eloc 8
nc 4
nop 1
1
<?php
2
3
/**
4
 * Copyright (c) 2018 Justin Kuenzel (jukusoft.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
20
/**
21
 * Project: JuKuCMS
22
 * License: Apache 2.0 license
23
 * User: Justin
24
 * Date: 24.04.2018
25
 * Time: 23:00
26
 */
27
28
class LDAPClient {
29
30
	//host and port
31
	protected $host = "";
32
	protected $port = 389;
33
34
	//flag, if uri is used instead of host
35
	protected $uri_used = false;
36
	protected $uri = "";
37
38
	protected $conn = null;
39
	protected $res = null;
40
41
	protected $dn = "";
42
43
	protected $ldap_config = array();
44
45
	//flag, if connection is readonly
46
	protected $readonly = false;
47
48
	public function __construct (string $host = "", int $port = 0, bool $ssl = false) {
49
		$ldap_config = array(
50
			'enabled' => true,
51
			'ssl' => $ssl
52
		);
53
54
		if (empty($host)) {
55
			//load local config
56
			if (!file_exists(CONFIG_PATH . "ldap.php")) {
57
				throw new IllegalStateException("No ldap configuration file config/ldap.php exists!");
58
			}
59
60
			//override $ldap_config
61
			require(CONFIG_PATH . "ldap.php");
62
63
			//check, if ldap is enabled
64
			if ($ldap_config['enabled'] == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
introduced by
The condition $ldap_config['enabled'] == false is always false.
Loading history...
65
				throw new IllegalStateException("LDAP is disabled.");
66
			}
67
68
			$this->host = $ldap_config['host'];
69
			$this->port = intval($ldap_config['port']);
70
71
			$this->readonly = boolval($ldap_config['readonly']);
72
		} else {
73
			$this->host = $host;
74
			$this->port = $port;
75
		}
76
77
		//check, if SSL is enabled
78
		if ($ldap_config['ssl'] == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
79
			//use OpenLDAP 2.x.x URI instead of host
80
			$this->uri = "ldaps://" . $this->host . ":" . $this->port;
81
82
			//set flag, that uri is used
83
			$this->uri_used = true;
84
		}
85
86
		//check, if host / uri is valide (this statement doesnt connect to server!) - see also http://php.net/manual/de/function.ldap-connect.php
87
		if ($this->uri_used) {
88
			$this->conn = ldap_connect($this->uri);
89
		} else {
90
			$this->conn = ldap_connect($this->host, $this->port);
91
		}
92
93
		if ($this->conn === FALSE) {
0 ignored issues
show
introduced by
The condition $this->conn === FALSE is always false.
Loading history...
94
			throw new IllegalStateException("LDAP connection parameters (host or port) are invalide.");
95
		}
96
97
		$this->dn = $ldap_config['dn'];
98
99
		//set ldap params
100
		if (isset($ldap_config['params'])) {
101
			foreach ($ldap_config['params'] as $key=>$value) {
0 ignored issues
show
Bug introduced by
The expression $ldap_config['params'] of type boolean is not traversable.
Loading history...
102
				// configure ldap params
103
				ldap_set_option($this->conn,$key, $value);
104
			}
105
		}
106
107
		$this->ldap_config = $ldap_config;
108
	}
109
110
	public function bind (string $username = null, string $password = null) : bool {
111
		if (is_null($username) && isset($this->ldap_config['user'])) {
112
			$username = $this->ldap_config['user'];
113
			$password = $this->ldap_config['password'];
114
		}
115
116
		$ldap_usr_dom = "";
117
118
		if (isset($this->ldap_config['ldap_usr_dom'])) {
119
			$ldap_usr_dom = $this->ldap_config['ldap_usr_dom'];
120
		}
121
122
		if ($this->conn === FALSE) {
123
			throw new IllegalStateException("ldap connection check failed.");
124
		}
125
126
		//http://www.selfadsi.de/ads-attributes/user-sAMAccountName.htm
127
128
		//connect and bind to ldap server
129
		if (!is_null($username)) {
130
			//with authentification
131
			$this->res = @ldap_bind($this->conn, $username . $ldap_usr_dom, $password);
132
		} else {
133
			//anonymous binding
134
			$this->res = @ldap_bind($this->conn);
135
		}
136
137
		return $this->res !== FALSE;
138
	}
139
140
	public function listGroupsOfUser (string $user) : array {
141
		// check presence in groups
142
		$filter = "(sAMAccountName=" . $user . ")";
143
		$attr = array("memberof");
144
145
		//https://samjlevy.com/php-ldap-login/
146
147
		$result = ldap_search($this->conn, $this->dn, $filter, $attr) or exit("Unable to search LDAP server");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
148
149
		/*
150
		 *return_value["count"] = number of entries in the result
151
		 * return_value[0] : refers to the details of first entry
152
		 * return_value[i]["dn"] = DN of the ith entry in the result
153
		 * return_value[i]["count"] = number of attributes in ith entry
154
		 * return_value[i][j] = NAME of the jth attribute in the ith entry in the result
155
		 * return_value[i]["attribute"]["count"] = number of values for
156
		 * attribute in ith entry
157
		 * return_value[i]["attribute"][j] = jth value of attribute in ith entry
158
		 */
159
		$entries = ldap_get_entries($this->conn, $result);
160
161
		/*$array = array();
162
163
		$count = intval($entries['count']);
164
165
		for ($i = 0; $i < $count; $i++) {
166
			$entry = $entries[$i];
167
168
			$array[] = array(
169
				'dn' => $entry['dn'],
170
				'count' => $entry['count'],
171
				'attributes' => $entry,
172
			);
173
		}*/
174
175
		$groups = array();
176
177
		foreach($entries[0]['memberof'] as $grps) {
178
			$groups[] = $grps;
179
		}
180
181
		return $groups;
182
	}
183
184
	public function unbind () {
185
		//disconnect from ldap server
186
		ldap_unbind($this->conn);
187
	}
188
189
	public function getConnection () {
190
		return $this->conn;
191
	}
192
193
}
194
195
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
196