Memcookie   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 50
dl 0
loc 150
rs 10
c 1
b 0
f 0
wmc 11

4 Methods

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