/
Auth.php
133 lines (110 loc) · 3.96 KB
/
Auth.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
namespace Maicol07\SSO\User\Traits;
use GuzzleHttp\Exception\ClientException;
use RuntimeException;
/**
* Trait Auth
* @package Maicol07\SSO\Traits
*/
trait Auth
{
/**
* Logs the user in Flarum. Generally, you should use this method when an user successfully log into
* your SSO system (or main website).
*/
public function login(): bool
{
$r = $this->flarum->filter_hook('replace_login', null);
if ($r !== -1) {
return $r;
}
$this->flarum->action_hook('before_login');
if (empty($this->attributes->password)) {
throw new RuntimeException("User's password not set");
}
$token = $this->getToken();
$this->flarum->action_hook('after_token_obtained', $token);
// If no token has been returned...
if (empty($token)) {
// ...try to search the user...
try {
$this->flarum->api->users($this->attributes->username)->request();
// Backward compatibility (create password based on username)
$this->attributes->password = $this->createPassword();
$token = $this->getToken();
if (empty($token)) {
return false;
}
} catch (ClientException $e) {
// ...otherwise signup it
if ($e->getCode() === 404 && $e->getResponse()->getReasonPhrase() === "Not Found") {
$signed_up = $this->signup();
if (!$signed_up) {
return false;
}
$this->flarum->action_hook('after_signup');
$token = $this->getToken();
} else {
throw $e;
}
}
}
$this->flarum->action_hook('after_login', $token);
$deleted = $this->flarum->deleteLogoutCookie();
$created = $this->flarum->isSessionRemembered() ? $this->flarum->setRememberTokenCookie($token) : $this->flarum->setSessionTokenCookie($token);
return ($deleted && $created);
}
/**
* Sign up user in Flarum. Generally, you should use this method when an user successfully log into
* your SSO system (or main website) and you found out that user don't have a token (because he hasn't an account on Flarum)
*/
public function signup(): bool
{
$r = $this->flarum->filter_hook('replace_signup', null);
if ($r !== -1) {
return $r;
}
$this->flarum->action_hook('before_signup');
$data = [
"type" => "users",
"attributes" => $this->getAttributes()
];
try {
$user = $this->flarum->api->users()->post($data)->request();
$this->flarum->action_hook('after_signup');
return isset($user->id);
} catch (ClientException $e) {
if ($e->getResponse()->getReasonPhrase() === "Unprocessable Entity") {
return false;
}
throw $e;
}
}
/**
* Generates a password based on username and password token
*/
private function createPassword(): string
{
return hash('sha256', $this->attributes->username . $this->flarum->password_token);
}
/**
* Get user token from Flarum (if user exists)
*/
private function getToken(): ?string
{
$data = [
'identification' => $this->attributes->username,
'password' => $this->attributes->password,
'remember' => $this->flarum->isSessionRemembered(),
];
try {
$response = $this->flarum->api->token()->post($data)->request();
return $response->token ?? '';
} catch (ClientException $e) {
if ($e->getResponse()->getReasonPhrase() === "Unauthorized") {
return null;
}
throw $e;
}
}
}