Passed
Push — master ( 0baeb0...d4017c )
by Tony
19:18 queued 08:55
created

app/Providers/LegacyUserProvider.php (1 issue)

1
<?php
2
/**
3
 * LegacyUserProvider.php
4
 *
5
 * -Description-
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * @package    LibreNMS
21
 * @link       http://librenms.org
22
 * @copyright  2018 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace App\Providers;
27
28
use App\Models\ApiToken;
29
use App\Models\User;
30
use DB;
31
use Illuminate\Contracts\Auth\Authenticatable;
32
use Illuminate\Contracts\Auth\UserProvider;
33
use LibreNMS\Authentication\LegacyAuth;
34
use LibreNMS\Exceptions\AuthenticationException;
35
use Log;
36
use Request;
37
use Session;
38
use Toastr;
39
40
class LegacyUserProvider implements UserProvider
41
{
42
    /**
43
     * Retrieve a user by their unique identifier.
44
     *
45
     * @param  mixed $identifier
46
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
47
     */
48
    public function retrieveById($identifier)
49
    {
50
        return User::find($identifier);
51
    }
52
53
    /**
54
     * Retrieve a user by their legacy auth specific identifier.
55
     *
56
     * @param  int $identifier
57
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
58
     */
59
    public function retrieveByLegacyId($identifier)
60
    {
61
        error_reporting(0);
62
        $legacy_user = LegacyAuth::get()->getUser($identifier);
63
        error_reporting(-1);
64
65
        return $this->retrieveByCredentials(['username' => $legacy_user['username'] ?? null]);
66
    }
67
68
    /**
69
     * Retrieve a user by their unique identifier and "remember me" token.
70
     *
71
     * @param  mixed $identifier
72
     * @param  string $token
73
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
74
     */
75
    public function retrieveByToken($identifier, $token)
76
    {
77
        $user = new User();
78
        $user = $user->where($user->getAuthIdentifierName(), $identifier)->first();
79
80
        if (!$user) {
81
            return null;
82
        }
83
84
        $rememberToken = $user->getRememberToken();
85
        if ($rememberToken && hash_equals($rememberToken, $token)) {
86
            if (LegacyAuth::get()->userExists($user->username)) {
87
                return $user;
88
            }
89
        }
90
91
        return null;
92
    }
93
94
    /**
95
     * Update the "remember me" token for the given user in storage.
96
     *
97
     * @param  \Illuminate\Contracts\Auth\Authenticatable $user
98
     * @param  string $token
99
     * @return void
100
     */
101
    public function updateRememberToken(Authenticatable $user, $token)
102
    {
103
        $user->setRememberToken($token);
104
        $timestamps = $user->timestamps;
105
        $user->timestamps = false;
106
        $user->save();
107
        $user->timestamps = $timestamps;
108
    }
109
110
    /**
111
     * Validate a user against the given credentials.
112
     *
113
     * @param  \Illuminate\Contracts\Auth\Authenticatable $user
114
     * @param  array $credentials
115
     * @return bool
116
     */
117
    public function validateCredentials(Authenticatable $user, array $credentials)
118
    {
119
        error_reporting(0);
120
121
        $authorizer = LegacyAuth::get();
122
123
        try {
124
            // try authentication methods
125
            if ($authorizer->authIsExternal()) {
126
                $credentials['username'] = $authorizer->getExternalUsername();
127
            }
128
129
            if (empty($credentials['username']) || !$authorizer->authenticate($credentials)) {
130
                throw new AuthenticationException('Invalid Credentials');
131
            }
132
133
            return true;
134
        } catch (AuthenticationException $ae) {
135
            global $debug;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
136
137
            $auth_message = $ae->getMessage();
138
            if ($debug) {
139
                $auth_message .= '<br /> ' . $ae->getFile() . ': ' . $ae->getLine();
140
            }
141
            \Toastr::error($auth_message);
142
143
            if (empty($username)) {
144
                $username = Session::get('username', $credentials['username']);
145
            }
146
            DB::table('authlog')->insert(['user' => $username, 'address' => Request::ip(), 'result' => $auth_message]);
147
        } finally {
148
            error_reporting(-1);
149
        }
150
151
        return false;
152
    }
153
154
    /**
155
     * Retrieve a user by the given credentials.
156
     *
157
     * @param  array $credentials
158
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
159
     */
160
    public function retrieveByCredentials(array $credentials)
161
    {
162
        error_reporting(0);
163
164
        $auth = LegacyAuth::get();
165
        $type = LegacyAuth::getType();
166
167
        // ldap based auth we should bind before using, otherwise searches may fail due to anonymous bind
168
        if (method_exists($auth, 'bind')) {
169
            $auth->bind($credentials);
170
        }
171
172
        $username = $credentials['username'] ?? null;
173
        $auth_id = $auth->getUserid($username);
174
        $new_user = $auth->getUser($auth_id);
175
176
        error_reporting(-1);
177
178
        if (empty($new_user)) {
179
            // some legacy auth create users in the authenticate method, if it doesn't exist yet, lets try authenticate (Laravel calls retrieveByCredentials first)
180
            try {
181
                error_reporting(0);
182
183
                $auth->authenticate($credentials);
184
                $auth_id = $auth->getUserid($username);
185
                $new_user = $auth->getUser($auth_id);
186
187
                error_reporting(-1);
188
            } catch (AuthenticationException $ae) {
189
                Toastr::error($ae->getMessage());
190
            }
191
192
            if (empty($new_user)) {
193
                Log::error("Auth Error ($type): No user ($auth_id) [$username]");
194
                return null;
195
            }
196
        }
197
198
        unset($new_user['user_id']);
199
200
        // remove null fields
201
        $new_user = array_filter($new_user, function ($var) {
202
            return !is_null($var);
203
        });
204
205
        // always create an entry in the users table, but separate by type
206
        $user = User::thisAuth()->firstOrNew(['username' => $username], $new_user);
207
        /** @var User $user */
208
209
210
        $user->fill($new_user); // fill all attributes
211
        $user->auth_type = $type; // doing this here in case it was null (legacy)
212
        $user->auth_id = $auth_id;
213
        $user->save();
214
215
        return $user;
216
    }
217
}
218