AuthMemCookie   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 146
rs 10
c 0
b 0
f 0
wmc 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getUsernameAttr() 0 3 1
A __construct() 0 4 1
A logoutHandler() 0 3 1
A getMemcache() 0 18 4
A doLogout() 0 18 2
A getGroupsAttr() 0 3 1
A getInstance() 0 7 2
A getCookieName() 0 10 2
A getAuthSource() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\memcookie;
6
7
use Exception;
8
use Memcached;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\Utils;
11
12
use function strlen;
13
14
/**
15
 * This is a helper class for the Auth MemCookie module.
16
 * It handles the configuration, and implements the logout handler.
17
 *
18
 * @package SimpleSAMLphp
19
 */
20
class AuthMemCookie
21
{
22
    /**
23
     * @var \SimpleSAML\Module\memcookie\AuthMemCookie|null This is the singleton instance of this class.
24
     */
25
    private static ?AuthMemCookie $instance = null;
26
27
    /**
28
     * @var \SimpleSAML\Configuration The configuration for Auth MemCookie.
29
     */
30
    private Configuration $config;
31
32
33
    /**
34
     * This function is used to retrieve the singleton instance of this class.
35
     *
36
     * @return \SimpleSAML\Module\memcookie\AuthMemCookie The singleton instance of this class.
37
     */
38
    public static function getInstance(): AuthMemCookie
39
    {
40
        if (self::$instance === null) {
41
            self::$instance = new AuthMemCookie();
42
        }
43
44
        return self::$instance;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::instance could return the type null which is incompatible with the type-hinted return SimpleSAML\Module\memcookie\AuthMemCookie. Consider adding an additional type-check to rule them out.
Loading history...
45
    }
46
47
48
    /**
49
     * This function implements the constructor for this class. It loads the Auth MemCookie configuration.
50
     */
51
    private function __construct()
52
    {
53
        // load AuthMemCookie configuration
54
        $this->config = Configuration::getConfig('module_authmemcookie.php');
55
    }
56
57
58
    /**
59
     * Retrieve the authentication source that should be used to authenticate the user.
60
     *
61
     * @return string The login type which should be used for Auth MemCookie.
62
     */
63
    public function getAuthSource(): string
64
    {
65
        return $this->config->getString('authsource');
66
    }
67
68
69
    /**
70
     * This function retrieves the name of the cookie from the configuration.
71
     *
72
     * @return string The name of the cookie.
73
     * @throws \Exception If the value of the 'cookiename' configuration option is invalid.
74
     */
75
    public function getCookieName(): string
76
    {
77
        $cookieName = $this->config->getOptionalString('cookiename', 'AuthMemCookie');
78
        if (strlen($cookieName) === 0) {
0 ignored issues
show
Bug introduced by
It seems like $cookieName can also be of type null; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
        if (strlen(/** @scrutinizer ignore-type */ $cookieName) === 0) {
Loading history...
79
            throw new Exception(
80
                "Configuration option 'cookiename' contains an invalid value. This option should be a string.",
81
            );
82
        }
83
84
        return $cookieName;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $cookieName could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
85
    }
86
87
88
    /**
89
     * This function retrieves the name of the attribute which contains the username from the configuration.
90
     *
91
     * @return string|null The name of the attribute which contains the username.
92
     */
93
    public function getUsernameAttr(): ?string
94
    {
95
        return $this->config->getOptionalString('username', null);
96
    }
97
98
99
    /**
100
     * This function retrieves the name of the attribute which contains the groups from the configuration.
101
     *
102
     * @return string|null The name of the attribute which contains the groups.
103
     */
104
    public function getGroupsAttr(): ?string
105
    {
106
        return $this->config->getOptionalString('groups', null);
107
    }
108
109
110
    /**
111
     * This function creates and initializes a Memcache object from our configuration.
112
     *
113
     * @return \Memcached A Memcache object initialized from our configuration.
114
     */
115
    public function getMemcache(): \Memcached
116
    {
117
        $memcacheHost = $this->config->getOptionalString('memcache.host', '127.0.0.1');
118
        $memcachePort = $this->config->getOptionalInteger('memcache.port', 11211);
119
120
        $class = class_exists('\Memcached') ? '\Memcached' : false;
121
122
        if (!$class) {
123
            throw new Exception('Missing Memcached implementation. You must install either the Memcached extension.');
124
        }
125
126
        $memcache = new Memcached();
127
128
        foreach (explode(',', $memcacheHost) as $memcacheHost) {
0 ignored issues
show
Bug introduced by
It seems like $memcacheHost can also be of type null; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

128
        foreach (explode(',', /** @scrutinizer ignore-type */ $memcacheHost) as $memcacheHost) {
Loading history...
129
            $memcache->addServer($memcacheHost, $memcachePort);
130
        }
131
132
        return $memcache;
133
    }
134
135
136
    /**
137
     * This function logs the user out by deleting the session information from memcache.
138
     */
139
    private function doLogout(): void
140
    {
141
        $cookieName = $this->getCookieName();
142
143
        // check if we have a valid cookie
144
        if (!array_key_exists($cookieName, $_COOKIE)) {
145
            return;
146
        }
147
148
        $sessionID = $_COOKIE[$cookieName];
149
150
        // delete the session from memcache
151
        $memcache = $this->getMemcache();
152
        $memcache->delete($sessionID);
153
154
        // delete the session cookie
155
        $httpUtils = new Utils\HTTP();
156
        $httpUtils->setCookie($cookieName, null);
157
    }
158
159
160
    /**
161
     * This function implements the logout handler. It deletes the information from Memcache.
162
     */
163
    public static function logoutHandler(): void
164
    {
165
        self::getInstance()->doLogout();
166
    }
167
}
168