Passed
Pull Request — master (#8)
by Tim
02:11
created

Memcookie::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\memcookie\Controller;
6
7
use SimpleSAML\Auth;
8
use SimpleSAML\Configuration;
9
use SimpleSAML\Error;
10
use SimpleSAML\HTTP\RunnableResponse;
11
use SimpleSAML\Module\memcookie\AuthMemCookie;
12
use SimpleSAML\Session;
13
use SimpleSAML\Utils;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
17
/**
18
 * Controller class for the memcookie module.
19
 *
20
 * This class serves the different views available in the module.
21
 *
22
 * @package simplesamlphp/simplesamlphp-module-memcookie
23
 */
24
class Memcookie
25
{
26
    /**
27
     * @var \SimpleSAML\Auth\Simple|string
28
     * @psalm-var \SimpleSAML\Auth\Simple|class-string
29
     */
30
    protected $auth_simple = Auth\Simple::class;
31
32
    /** @var \SimpleSAML\Configuration */
33
    protected $config;
34
35
    /**
36
     * @var \SimpleSAML\Utils\HTTP|string
37
     * @psalm-var \SimpleSAML\Utils\HTTP|class-string
38
     */
39
    protected $http_utils = Utils\HTTP::class;
40
41
    /** @var \SimpleSAML\Session */
42
    protected $session;
43
44
45
    /**
46
     * Controller constructor.
47
     *
48
     * It initializes the global configuration and session for the controllers implemented here.
49
     *
50
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
51
     * @param \SimpleSAML\Session $session The session to use by the controllers.
52
     *
53
     * @throws \Exception
54
     */
55
    public function __construct(
56
        Configuration $config,
57
        Session $session
58
    ) {
59
        $this->config = $config;
60
        $this->session = $session;
61
    }
62
63
64
    /**
65
     * Inject the \SimpleSAML\Auth\Simple dependency.
66
     *
67
     * @param \SimpleSAML\Auth\Simple $authSimple
68
     */
69
    public function setAuthSimple(Auth\Simple $authSimple): void
70
    {
71
        $this->auth_simple = $authSimple;
72
    }
73
74
75
    /**
76
     * Inject the \SimpleSAML\Utils\HTTP dependency.
77
     *
78
     * @param \SimpleSAML\Utils\HTTP $httpUtils
79
     */
80
    public function setHttpUtils(Utils\HTTP $httpUtils): void
81
    {
82
        $this->http_utils = $httpUtils;
83
    }
84
85
86
    /**
87
     * This method implements an script which can be used to authenticate users with Auth MemCookie.
88
     * See: https://zenprojects.github.io/Apache-Authmemcookie-Module/
89
     *
90
     * The configuration for this script is stored in config/module_authmemcookie.php.
91
     *
92
     * The file extra/auth_memcookie.conf contains an example of how Auth Memcookie can be configured
93
     * to use SimpleSAMLphp.
94
     *
95
     * @param \Symfony\Component\HttpFoundation\Request $request
96
     * @return \SimpleSAML\HTTP\RunnableResponse
97
     */
98
    public function main(Request $request): RunnableResponse
99
    {
100
        // load SimpleSAMLphp configuration
101
        $ssp_cf = $this->config::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $ssp_cf is dead and can be removed.
Loading history...
102
103
        // load Auth MemCookie configuration
104
        $amc_cf = AuthMemCookie::getInstance();
105
106
        $sourceId = $amc_cf->getAuthSource();
107
        $simple = $this->auth_simple;
108
        $s = new $simple($sourceId);
109
110
        // check if the user is authorized. We attempt to authenticate the user if not
111
        $s->requireAuth();
112
113
        // generate session id and save it in a cookie
114
        $sessionID = Utils\Random::generateID();
115
        $cookieName = $amc_cf->getCookieName();
116
        $this->http_utils::setCookie($cookieName, $sessionID);
117
118
        // generate the authentication information
119
        $attributes = $s->getAttributes();
120
121
        $authData = [];
122
123
        // username
124
        $usernameAttr = $amc_cf->getUsernameAttr();
125
        if ($usernameAttr === null || !array_key_exists($usernameAttr, $attributes)) {
126
            throw new Error\Exception(
127
                "The user doesn't have an attribute named '" . $usernameAttr .
128
                "'. This attribute is expected to contain the username."
129
            );
130
        }
131
        $authData['UserName'] = $attributes[$usernameAttr];
132
133
        // groups
134
        $groupsAttr = $amc_cf->getGroupsAttr();
135
        if ($groupsAttr !== null) {
0 ignored issues
show
introduced by
The condition $groupsAttr !== null is always true.
Loading history...
136
            if (!array_key_exists($groupsAttr, $attributes)) {
137
                throw new Error\Exception(
138
                    "The user doesn't have an attribute named '" . $groupsAttr .
139
                    "'. This attribute is expected to contain the groups the user is a member of."
140
                );
141
            }
142
            $authData['Groups'] = $attributes[$groupsAttr];
143
        } else {
144
            $authData['Groups'] = [];
145
        }
146
147
        $authData['RemoteIP'] = $request->server->get('REMOTE_ADDR');
148
149
        foreach ($attributes as $n => $v) {
150
            $authData['ATTR_' . $n] = $v;
151
        }
152
153
        // store the authentication data in the memcache server
154
        $data = '';
155
        foreach ($authData as $n => $v) {
156
            if (is_array($v)) {
157
                $v = implode(':', $v);
158
            }
159
            $data .= $n . '=' . $v . "\r\n";
160
        }
161
162
        $memcache = $amc_cf->getMemcache();
163
        $expirationTime = $s->getAuthData('Expire');
164
        $memcache->set($sessionID, $data, $expirationTime ?? 0);
165
166
        // register logout handler
167
        $this->session->registerLogoutHandler($sourceId, '\SimpleSAML\Module\memcookie\AuthMemCookie', 'logoutHandler');
168
169
        // redirect the user back to this page to signal that the login is completed
170
        return new RunnableResponse([$this->http_utils, 'redirectTrustedURL'], [$this->http_utils::getSelfURL()]);
171
    }
172
}
173