summaryrefslogtreecommitdiff
path: root/auth/multisites/auth.php
blob: 680f4e4c1ecdabf5bc00126ffba8b30a6bf84aed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
/**
 * $Header$
 *
 * @package users
 */

/**
 * Class that manages the bitweaver autentication method with additional limitations from multisites
 *
 * @package users
 * @subpackage auth
 */
namespace Bitweaver\Users;
use Bitweaver\KernelTools;

class MultisitesAuth extends BaseAuth {

	function __construct() {
		parent::__construct('multisites');
	}

	function validate($user,$pass,$challenge,$response) {
		parent::validate($user,$pass,$challenge,$response);
		global $gBitSystem;
		global $gBitDb;
		global $gMultisites;

		$ret = SERVER_ERROR;
		if( empty( $user ) ) {
			$this->mErrors['login'] = 'User not found';
		} elseif( empty( $pass ) ) {
			$this->mErrors['login'] = 'Password incorrect';
		} else {
			$loginVal = strtoupper( $user ); // case insensitive login
			$loginCol = ' UPPER(`'.(strpos( $user, '@' ) ? 'email' : 'login').'`)';
			// first verify that the user exists
			$query = "select `email`, `login`, `user_id`, `user_password` from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ?";
			$result = $gBitDb->query( $query, array( $loginVal ) );
			if( !$result->numRows() ) {
				$this->mErrors['login'] = 'User not found';
			} else {
				$res = $result->fetchRow();
				$userId = $res['user_id'];
				$user = $res['login'];
				// TikiWiki 1.8+ uses this bizarro conglomeration of fields to get the hash. this sucks for many reasons
				$hash = md5( strtolower($user) . $pass . $res['email']);
				$hash2 = md5($pass);
				// next verify the password with 2 hashes methods, the old one (pass)) and the new one (login.pass;email)
				// TODO - this needs cleaning up - wolff_borg
				if( !$gBitSystem->isFeatureActive( 'feature_challenge' ) || empty($response) ) {
					$query = "select `user_id`, `content_id`, `hash` from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ? and (`hash`=? or `hash`=?)";
					if ( $row = $gBitDb->getRow( $query, array( $loginVal, $hash, $hash2 ) ) ) {
						// auto-update old hashes with simple and standard md5( password )
						$hashUpdate = '';
						if( $row['hash'] == $hash ) {
							$hashUpdate = 'hash=?, ';
							$bindVars[] = $hash2;
						}
						$bindVars[] = $gBitSystem->getUTCTime();
						$bindVars[] = $userId;
						$query = "update `".BIT_DB_PREFIX."users_users` set  $hashUpdate `last_login`=`current_login`, `current_login`=? where `user_id`=?";
						$result = $gBitDb->query($query, $bindVars );
						$query = "select `multisite_id` from `".BIT_DB_PREFIX."multisite_content` where `content_id` = ?";
						$sites = $gBitDb->getAll($query, array( $row['content_id'] ) );
						if ( !$sites ) {
							$ret=USER_VALID;
						} else {
							// This will allow for additional by site checking in future
							// Currently only a single site per user_id is allowed
							$ret=PASSWORD_INCORRECT;
							foreach ( $sites as $id ) {
								if ( $id['multisite_id'] == $gMultisites->mMultisiteId ) {
									$ret=USER_VALID;
								}
							}
							if ( $ret == PASSWORD_INCORRECT ) {
								$this->mErrors[] = 'You are not authorized on this area of the site';
							}
						}
					} else {
						$ret=PASSWORD_INCORRECT;
						$this->mErrors[] = 'Password incorrect';
					}
				} else {
					// Use challenge-reponse method
					// Compare pass against md5(user,challenge,hash)
					$hash = $gBitDb->getOne("select `hash`  from `".BIT_DB_PREFIX."users_users` where " . $gBitDb->convertBinary(). " $loginCol = ?", array( $user ) );
					if (!isset($_SESSION["challenge"])) {
						$this->mErrors[] = 'Invalid challenge';
						$ret=PASSWORD_INCORRECT;
					}
					//print("pass: $pass user: $user hash: $hash <br/>");
					//print("challenge: ".$_SESSION["challenge"]." challenge: $challenge<br/>");
					//print("response : $response<br/>");
					if ($response == md5( strtolower($user) . $hash . $_SESSION["challenge"]) ) {
						$ret = USER_VALID;
						$this->updateLastLogin( $userId );
					} else {
						$this->mErrors[] = 'Invalid challenge';
						$ret=PASSWORD_INCORRECT;
					}
				}
			}
			if (!empty($userId)) {
				$this->mInfo['user_id']=$userId;
			}
		}
		return( $ret );
	}

	function canManageAuth() {
		global $gBitSystem;
		if( $gBitSystem->isPackageActive( 'multisites' ) ) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	function isSupported() {
		global $gBitSystem;
		if( $gBitSystem->isPackageActive( 'multisites' ) ) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	function createUser( &$pUserHash ) {
		//$authUserInfo = array( 'login' => $instance->mInfo['login'], 'password' => $instance->mInfo['password'], 'real_name' => $instance->mInfo['real_name'], 'email' => $instance->mInfo['email'] );
		$u = new BitPermUser();

		if( !$u->store( $pUserHash ) ) {
			$this->mErrors = array_merge($this->mErrors,$u->mErrors);
		}
		return $u->mUserId;
	}
}