summaryrefslogtreecommitdiffstats
path: root/lib/private/connector/sabre/auth.php
blob: 5a32a9112ba2a4ee0ed90a705d44c614d32fb8bc (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
<?php
/**
 * @author Arthur Schiwon <blizzz@owncloud.com>
 * @author Bart Visscher <bartv@thisnet.nl>
 * @author Christian Seiler <christian@iwakd.de>
 * @author Jakob Sack <mail@jakobsack.de>
 * @author Lukas Reschke <lukas@owncloud.com>
 * @author Markus Goetz <markus@woboq.com>
 * @author Michael Gapczynski <GapczynskiM@gmail.com>
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
 * @author Thomas Müller <thomas.mueller@tmit.eu>
 * @author Vincent Petry <pvince81@owncloud.com>
 *
 * @copyright Copyright (c) 2015, ownCloud, Inc.
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */
namespace OC\Connector\Sabre;

class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
	const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';

	/**
	 * Whether the user has initially authenticated via DAV
	 *
	 * This is required for WebDAV clients that resent the cookies even when the
	 * account was changed.
	 *
	 * @see https://github.com/owncloud/core/issues/13245
	 *
	 * @param string $username
	 * @return bool
	 */
	protected function isDavAuthenticated($username) {
		return !is_null(\OC::$server->getSession()->get(self::DAV_AUTHENTICATED)) &&
		\OC::$server->getSession()->get(self::DAV_AUTHENTICATED) === $username;
	}

	/**
	 * Validates a username and password
	 *
	 * This method should return true or false depending on if login
	 * succeeded.
	 *
	 * @param string $username
	 * @param string $password
	 * @return bool
	 */
	protected function validateUserPass($username, $password) {
		if (\OC_User::isLoggedIn() &&
			$this->isDavAuthenticated(\OC_User::getUser())
		) {
			\OC_Util::setupFS(\OC_User::getUser());
			\OC::$server->getSession()->close();
			return true;
		} else {
			\OC_Util::setUpFS(); //login hooks may need early access to the filesystem
			if(\OC_User::login($username, $password)) {
			        // make sure we use owncloud's internal username here
			        // and not the HTTP auth supplied one, see issue #14048
			        $ocUser = \OC_User::getUser();
				\OC_Util::setUpFS($ocUser);
				\OC::$server->getSession()->set(self::DAV_AUTHENTICATED, $ocUser);
				\OC::$server->getSession()->close();
				return true;
			} else {
				\OC::$server->getSession()->close();
				return false;
			}
		}
	}

	/**
	 * Returns information about the currently logged in username.
	 *
	 * If nobody is currently logged in, this method should return null.
	 *
	 * @return string|null
	 */
	public function getCurrentUser() {
		$user = \OC_User::getUser();
		if($user && $this->isDavAuthenticated($user)) {
			return $user;
		}
		return null;
	}

	/**
	  * Override function here. We want to cache authentication cookies
	  * in the syncing client to avoid HTTP-401 roundtrips.
	  * If the sync client supplies the cookies, then OC_User::isLoggedIn()
	  * will return true and we can see this WebDAV request as already authenticated,
	  * even if there are no HTTP Basic Auth headers.
	  * In other case, just fallback to the parent implementation.
	  *
	  * @param \Sabre\DAV\Server $server
	  * @param $realm
	  * @return bool
	  */
	public function authenticate(\Sabre\DAV\Server $server, $realm) {

		$result = $this->auth($server, $realm);
		return $result;
    }

	/**
	 * @param \Sabre\DAV\Server $server
	 * @param $realm
	 * @return bool
	 */
	private function auth(\Sabre\DAV\Server $server, $realm) {
		if (\OC_User::handleApacheAuth() ||
			(\OC_User::isLoggedIn() && is_null(\OC::$server->getSession()->get(self::DAV_AUTHENTICATED)))
		) {
			$user = \OC_User::getUser();
			\OC_Util::setupFS($user);
			$this->currentUser = $user;
			\OC::$server->getSession()->close();
			return true;
		}

		return parent::authenticate($server, $realm);
	}
}