Util::__clone()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * AppserverIo\Appserver\ServletEngine\Security\Utils\Util
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2015 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/appserver
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Appserver\ServletEngine\Security\Utils;
22
23
use AppserverIo\Lang\String;
24
use Doctrine\DBAL\DriverManager;
25
use AppserverIo\Collections\HashMap;
26
use AppserverIo\Appserver\ServletEngine\RequestHandler;
27
use AppserverIo\Appserver\Doctrine\Utils\ConnectionUtil;
28
use AppserverIo\Appserver\Naming\Utils\NamingDirectoryKeys;
29
use AppserverIo\Appserver\ServletEngine\Security\SimpleGroup;
30
use AppserverIo\Psr\Security\Auth\Spi\LoginModuleInterface;
31
use AppserverIo\Psr\Security\Auth\Login\LoginException;
32
use AppserverIo\Psr\Security\Auth\Login\FailedLoginException;
33
use AppserverIo\Psr\Naming\NamingException;
34
35
/**
36
 * Utility class for security purposes.
37
 *
38
 * @author    Tim Wagner <[email protected]>
39
 * @copyright 2015 TechDivision GmbH <[email protected]>
40
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
41
 * @link      https://github.com/appserver-io/appserver
42
 * @link      http://www.appserver.io
43
 */
44
class Util
45
{
46
47
    /**
48
     * Contains the default group name.
49
     *
50
     * @var string
51
     */
52
    const DEFAULT_GROUP_NAME = 'Roles';
53
54
    /**
55
     * Key for base64 encoding.
56
     *
57
     * @var string
58
     */
59
    const BASE64_ENCODING = 'base64Encoding';
60
61
    /**
62
     * Creates and returns a hashed version of the passed password.
63
     *
64
     * @param string                   $hashAlgorithm The hash algorithm to use
65
     * @param string                   $hashEncoding  The hash encoding to use
66
     * @param string                   $hashCharset   The hash charset to use
67
     * @param \AppserverIo\Lang\String $name          The login name
68
     * @param \AppserverIo\Lang\String $password      The password credential
69
     * @param mixed                    $callback      The callback providing some additional hashing functionality
70
     *
71
     * @return \AppserverIo\Lang\String The hashed password
72
     */
73
    public static function createPasswordHash($hashAlgorithm, $hashEncoding, $hashCharset, String $name, String $password, $callback)
0 ignored issues
show
Unused Code introduced by
The parameter $hashCharset is not used and could be removed. ( Ignorable by Annotation )

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

73
    public static function createPasswordHash($hashAlgorithm, $hashEncoding, /** @scrutinizer ignore-unused */ $hashCharset, String $name, String $password, $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $hashAlgorithm is not used and could be removed. ( Ignorable by Annotation )

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

73
    public static function createPasswordHash(/** @scrutinizer ignore-unused */ $hashAlgorithm, $hashEncoding, $hashCharset, String $name, String $password, $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $callback is not used and could be removed. ( Ignorable by Annotation )

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

73
    public static function createPasswordHash($hashAlgorithm, $hashEncoding, $hashCharset, String $name, String $password, /** @scrutinizer ignore-unused */ $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $hashEncoding is not used and could be removed. ( Ignorable by Annotation )

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

73
    public static function createPasswordHash($hashAlgorithm, /** @scrutinizer ignore-unused */ $hashEncoding, $hashCharset, String $name, String $password, $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

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

73
    public static function createPasswordHash($hashAlgorithm, $hashEncoding, $hashCharset, /** @scrutinizer ignore-unused */ String $name, String $password, $callback)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
74
    {
75
        $newPassword = clone $password;
76
        return $newPassword->md5();
77
    }
78
79
    /**
80
     * Execute the rolesQuery against the dsJndiName to obtain the roles for the authenticated user.
81
     *
82
     * @param \AppserverIo\Lang\String                                $username   The username to load the roles for
83
     * @param \AppserverIo\Lang\String                                $lookupName The lookup name for the datasource
84
     * @param \AppserverIo\Lang\String                                $rolesQuery The query to load the roles
85
     * @param \AppserverIo\Psr\Security\Auth\Spi\LoginModuleInterface $aslm       The login module to add the roles to
86
     *
87
     * @return array An array of groups containing the sets of roles
88
     * @throws \AppserverIo\Psr\Security\Auth\Login\LoginException Is thrown if an error during login occured
89
     */
90
    public static function getRoleSets(String $username, String $lookupName, String $rolesQuery, LoginModuleInterface $aslm)
91
    {
92
93
        try {
94
            // initialize the map for the groups
95
            $setsMap = new HashMap();
96
97
            // load the application context
98
            $application = RequestHandler::getApplicationContext();
99
100
            /** @var \AppserverIo\Appserver\Core\Api\Node\DatabaseNode $databaseNode */
101
            $databaseNode = $application->getNamingDirectory()->search($lookupName)->getDatabase();
0 ignored issues
show
Bug introduced by
The method getNamingDirectory() does not exist on AppserverIo\Psr\Application\ApplicationInterface. It seems like you code against a sub-type of AppserverIo\Psr\Application\ApplicationInterface such as AppserverIo\Appserver\Application\Application. ( Ignorable by Annotation )

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

101
            $databaseNode = $application->/** @scrutinizer ignore-call */ getNamingDirectory()->search($lookupName)->getDatabase();
Loading history...
102
103
            // prepare the connection parameters and create the DBAL connection
104
            $connection = DriverManager::getConnection(ConnectionUtil::get($application)->fromDatabaseNode($databaseNode));
105
106
            // try to load the principal's roles from the database
107
            $statement = $connection->prepare($rolesQuery);
108
            $statement->bindParam(1, $username);
109
            $statement->execute();
110
111
            // query whether or not we've a password found or not
112
            $row = $statement->fetch(\PDO::FETCH_NUM);
113
114
            // query whether or not we've found at least one role
115
            if ($row == false) {
116
                // try load the unauthenticated identity
117
                if ($aslm->getUnauthenticatedIdentity() == null) {
0 ignored issues
show
Bug introduced by
The method getUnauthenticatedIdentity() does not exist on AppserverIo\Psr\Security...pi\LoginModuleInterface. It seems like you code against a sub-type of AppserverIo\Psr\Security...pi\LoginModuleInterface such as AppserverIo\Appserver\Se...Spi\AbstractLoginModule. ( Ignorable by Annotation )

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

117
                if ($aslm->/** @scrutinizer ignore-call */ getUnauthenticatedIdentity() == null) {
Loading history...
118
                    throw new FailedLoginException('No matching username found in Roles');
119
                }
120
121
                // we're running with an unauthenticatedIdentity so create an empty roles set and return
122
                return array(new SimpleGroup(Util::DEFAULT_GROUP_NAME));
123
            }
124
125
            do {
126
                // load the found name and initialize the group name with a default value
127
                $name = $row[0];
128
                $groupName = Util::DEFAULT_GROUP_NAME;
129
130
                // query whether or not we've to initialize a default group
131
                if (isset($row[1])) {
132
                    $groupName = $row[1];
133
                }
134
135
                // query whether or not the group already exists in the set
136
                if ($setsMap->exists($groupName) === false) {
137
                    $group = new SimpleGroup(new String($groupName));
138
                    $setsMap->add($groupName, $group);
139
                } else {
140
                    $group = $setsMap->get($groupName);
141
                }
142
143
                try {
144
                    // add the user to the group
145
                    $group->addMember($aslm->createIdentity(new String($name)));
0 ignored issues
show
Bug introduced by
The method createIdentity() does not exist on AppserverIo\Psr\Security...pi\LoginModuleInterface. It seems like you code against a sub-type of AppserverIo\Psr\Security...pi\LoginModuleInterface such as AppserverIo\Appserver\Se...Spi\AbstractLoginModule. ( Ignorable by Annotation )

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

145
                    $group->addMember($aslm->/** @scrutinizer ignore-call */ createIdentity(new String($name)));
Loading history...
146
                    // log a message
147
                    $application
148
                        ->getNamingDirectory()
149
                        ->search(NamingDirectoryKeys::SYSTEM_LOGGER)
150
                        ->debug(sprintf('Assign user to role: %s', $name));
151
                } catch (\Exception $e) {
152
                    $application
153
                        ->getNamingDirectory()
154
                        ->search(NamingDirectoryKeys::SYSTEM_LOGGER)
155
                        ->error(sprintf('Failed to create principal: %s', $name));
156
                }
157
158
            // load one group after another
159
            } while ($row = $statement->fetch(\PDO::FETCH_OBJ));
160
161
        } catch (NamingException $ne) {
162
            throw new LoginException($ne->__toString());
163
        } catch (\PDOException $pdoe) {
164
            throw new LoginException($pdoe->__toString());
165
        }
166
167
        // close the prepared statement
168
        if ($statement != null) {
169
            try {
170
                $statement->closeCursor();
171
            } catch (\Exception $e) {
172
                $application
173
                    ->getNamingDirectory()
174
                    ->search(NamingDirectoryKeys::SYSTEM_LOGGER)
175
                    ->error($e->__toString());
176
            }
177
        }
178
179
        // close the DBAL connection
180
        if ($connection != null) {
181
            try {
182
                $connection->close();
183
            } catch (\Exception $e) {
184
                $application
185
                    ->getNamingDirectory()
186
                    ->search(NamingDirectoryKeys::SYSTEM_LOGGER)
187
                    ->error($e->__toString());
188
            }
189
        }
190
191
        // return the prepared groups
192
        return $setsMap->toArray();
193
    }
194
195
    /**
196
     * This is a utility class, so protect it against direct instantiation.
197
     */
198
    private function __construct()
199
    {
200
    }
201
202
    /**
203
     * This is a utility class, so protect it against cloning.
204
     *
205
     * @return void
206
     */
207
    private function __clone()
208
    {
209
    }
210
}
211