xref: /plugin/davcal/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAV\Auth\Backend;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV;
6*a1a3b679SAndreas Boehleruse Sabre\HTTP;
7*a1a3b679SAndreas Boehleruse Sabre\HTTP\RequestInterface;
8*a1a3b679SAndreas Boehleruse Sabre\HTTP\ResponseInterface;
9*a1a3b679SAndreas Boehler
10*a1a3b679SAndreas Boehler/**
11*a1a3b679SAndreas Boehler * HTTP Basic authentication backend class
12*a1a3b679SAndreas Boehler *
13*a1a3b679SAndreas Boehler * This class can be used by authentication objects wishing to use HTTP Basic
14*a1a3b679SAndreas Boehler * Most of the digest logic is handled, implementors just need to worry about
15*a1a3b679SAndreas Boehler * the validateUserPass method.
16*a1a3b679SAndreas Boehler *
17*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
18*a1a3b679SAndreas Boehler * @author James David Low (http://jameslow.com/)
19*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
20*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
21*a1a3b679SAndreas Boehler */
22*a1a3b679SAndreas Boehlerabstract class AbstractBasic implements BackendInterface {
23*a1a3b679SAndreas Boehler
24*a1a3b679SAndreas Boehler    /**
25*a1a3b679SAndreas Boehler     * Authentication Realm.
26*a1a3b679SAndreas Boehler     *
27*a1a3b679SAndreas Boehler     * The realm is often displayed by browser clients when showing the
28*a1a3b679SAndreas Boehler     * authentication dialog.
29*a1a3b679SAndreas Boehler     *
30*a1a3b679SAndreas Boehler     * @var string
31*a1a3b679SAndreas Boehler     */
32*a1a3b679SAndreas Boehler    protected $realm = 'sabre/dav';
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehler    /**
35*a1a3b679SAndreas Boehler     * This is the prefix that will be used to generate principal urls.
36*a1a3b679SAndreas Boehler     *
37*a1a3b679SAndreas Boehler     * @var string
38*a1a3b679SAndreas Boehler     */
39*a1a3b679SAndreas Boehler    protected $principalPrefix = 'principals/';
40*a1a3b679SAndreas Boehler
41*a1a3b679SAndreas Boehler    /**
42*a1a3b679SAndreas Boehler     * Validates a username and password
43*a1a3b679SAndreas Boehler     *
44*a1a3b679SAndreas Boehler     * This method should return true or false depending on if login
45*a1a3b679SAndreas Boehler     * succeeded.
46*a1a3b679SAndreas Boehler     *
47*a1a3b679SAndreas Boehler     * @param string $username
48*a1a3b679SAndreas Boehler     * @param string $password
49*a1a3b679SAndreas Boehler     * @return bool
50*a1a3b679SAndreas Boehler     */
51*a1a3b679SAndreas Boehler    abstract protected function validateUserPass($username, $password);
52*a1a3b679SAndreas Boehler
53*a1a3b679SAndreas Boehler    /**
54*a1a3b679SAndreas Boehler     * Sets the authentication realm for this backend.
55*a1a3b679SAndreas Boehler     *
56*a1a3b679SAndreas Boehler     * @param string $realm
57*a1a3b679SAndreas Boehler     * @return void
58*a1a3b679SAndreas Boehler     */
59*a1a3b679SAndreas Boehler    function setRealm($realm) {
60*a1a3b679SAndreas Boehler
61*a1a3b679SAndreas Boehler        $this->realm = $realm;
62*a1a3b679SAndreas Boehler
63*a1a3b679SAndreas Boehler    }
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler    /**
66*a1a3b679SAndreas Boehler     * When this method is called, the backend must check if authentication was
67*a1a3b679SAndreas Boehler     * successful.
68*a1a3b679SAndreas Boehler     *
69*a1a3b679SAndreas Boehler     * The returned value must be one of the following
70*a1a3b679SAndreas Boehler     *
71*a1a3b679SAndreas Boehler     * [true, "principals/username"]
72*a1a3b679SAndreas Boehler     * [false, "reason for failure"]
73*a1a3b679SAndreas Boehler     *
74*a1a3b679SAndreas Boehler     * If authentication was successful, it's expected that the authentication
75*a1a3b679SAndreas Boehler     * backend returns a so-called principal url.
76*a1a3b679SAndreas Boehler     *
77*a1a3b679SAndreas Boehler     * Examples of a principal url:
78*a1a3b679SAndreas Boehler     *
79*a1a3b679SAndreas Boehler     * principals/admin
80*a1a3b679SAndreas Boehler     * principals/user1
81*a1a3b679SAndreas Boehler     * principals/users/joe
82*a1a3b679SAndreas Boehler     * principals/uid/123457
83*a1a3b679SAndreas Boehler     *
84*a1a3b679SAndreas Boehler     * If you don't use WebDAV ACL (RFC3744) we recommend that you simply
85*a1a3b679SAndreas Boehler     * return a string such as:
86*a1a3b679SAndreas Boehler     *
87*a1a3b679SAndreas Boehler     * principals/users/[username]
88*a1a3b679SAndreas Boehler     *
89*a1a3b679SAndreas Boehler     * @param RequestInterface $request
90*a1a3b679SAndreas Boehler     * @param ResponseInterface $response
91*a1a3b679SAndreas Boehler     * @return array
92*a1a3b679SAndreas Boehler     */
93*a1a3b679SAndreas Boehler    function check(RequestInterface $request, ResponseInterface $response) {
94*a1a3b679SAndreas Boehler
95*a1a3b679SAndreas Boehler        $auth = new HTTP\Auth\Basic(
96*a1a3b679SAndreas Boehler            $this->realm,
97*a1a3b679SAndreas Boehler            $request,
98*a1a3b679SAndreas Boehler            $response
99*a1a3b679SAndreas Boehler        );
100*a1a3b679SAndreas Boehler
101*a1a3b679SAndreas Boehler        $userpass = $auth->getCredentials($request);
102*a1a3b679SAndreas Boehler        if (!$userpass) {
103*a1a3b679SAndreas Boehler            return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is mis-configured"];
104*a1a3b679SAndreas Boehler        }
105*a1a3b679SAndreas Boehler        if (!$this->validateUserPass($userpass[0], $userpass[1])) {
106*a1a3b679SAndreas Boehler            return [false, "Username or password was incorrect"];
107*a1a3b679SAndreas Boehler        }
108*a1a3b679SAndreas Boehler        return [true, $this->principalPrefix . $userpass[0]];
109*a1a3b679SAndreas Boehler
110*a1a3b679SAndreas Boehler    }
111*a1a3b679SAndreas Boehler
112*a1a3b679SAndreas Boehler    /**
113*a1a3b679SAndreas Boehler     * This method is called when a user could not be authenticated, and
114*a1a3b679SAndreas Boehler     * authentication was required for the current request.
115*a1a3b679SAndreas Boehler     *
116*a1a3b679SAndreas Boehler     * This gives you the opportunity to set authentication headers. The 401
117*a1a3b679SAndreas Boehler     * status code will already be set.
118*a1a3b679SAndreas Boehler     *
119*a1a3b679SAndreas Boehler     * In this case of Basic Auth, this would for example mean that the
120*a1a3b679SAndreas Boehler     * following header needs to be set:
121*a1a3b679SAndreas Boehler     *
122*a1a3b679SAndreas Boehler     * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV');
123*a1a3b679SAndreas Boehler     *
124*a1a3b679SAndreas Boehler     * Keep in mind that in the case of multiple authentication backends, other
125*a1a3b679SAndreas Boehler     * WWW-Authenticate headers may already have been set, and you'll want to
126*a1a3b679SAndreas Boehler     * append your own WWW-Authenticate header instead of overwriting the
127*a1a3b679SAndreas Boehler     * existing one.
128*a1a3b679SAndreas Boehler     *
129*a1a3b679SAndreas Boehler     * @param RequestInterface $request
130*a1a3b679SAndreas Boehler     * @param ResponseInterface $response
131*a1a3b679SAndreas Boehler     * @return void
132*a1a3b679SAndreas Boehler     */
133*a1a3b679SAndreas Boehler    function challenge(RequestInterface $request, ResponseInterface $response) {
134*a1a3b679SAndreas Boehler
135*a1a3b679SAndreas Boehler        $auth = new HTTP\Auth\Basic(
136*a1a3b679SAndreas Boehler            $this->realm,
137*a1a3b679SAndreas Boehler            $request,
138*a1a3b679SAndreas Boehler            $response
139*a1a3b679SAndreas Boehler        );
140*a1a3b679SAndreas Boehler        $auth->requireLogin();
141*a1a3b679SAndreas Boehler
142*a1a3b679SAndreas Boehler    }
143*a1a3b679SAndreas Boehler
144*a1a3b679SAndreas Boehler}
145