1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Spinen\Discourse\Controllers; |
4
|
|
|
|
5
|
|
|
use Cviebrock\DiscoursePHP\SSOHelper; |
6
|
|
|
use Illuminate\Contracts\Auth\Authenticatable as User; |
7
|
|
|
use Illuminate\Contracts\Config\Repository as Config; |
8
|
|
|
use Illuminate\Http\Request; |
9
|
|
|
use Illuminate\Routing\Controller; |
10
|
|
|
use Illuminate\Support\Collection; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Class SsoController |
14
|
|
|
* |
15
|
|
|
* Controller to process the Discourse SSO request. There is a good bit of logic in here that almost feels like too |
16
|
|
|
* much for a controller, but given that this is the only thing that this controller is doing, I am not going to break |
17
|
|
|
* it out into some service class. |
18
|
|
|
* |
19
|
|
|
* @package Spinen\Discourse |
20
|
|
|
*/ |
21
|
|
|
class SsoController extends Controller |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* Package configuration |
25
|
|
|
* |
26
|
|
|
* @var Collection |
27
|
|
|
*/ |
28
|
|
|
protected $config; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* SSOHelper Instance |
32
|
|
|
* |
33
|
|
|
* @var SSOHelper |
34
|
|
|
*/ |
35
|
|
|
protected $sso; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Authenticated user |
39
|
|
|
* |
40
|
|
|
* @var User |
41
|
|
|
*/ |
42
|
|
|
protected $user; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* SsoController constructor. |
46
|
|
|
* |
47
|
|
|
* @param Config $config |
48
|
|
|
* @param SSOHelper $sso |
49
|
|
|
*/ |
50
|
|
|
public function __construct(Config $config, SSOHelper $sso) |
51
|
|
|
{ |
52
|
|
|
$this->config = $config->get('services.discourse'); |
53
|
|
|
|
54
|
|
|
$this->sso = $sso->setSecret($this->config['secret']); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Build out the extra parameters to send to Discourse |
59
|
|
|
* |
60
|
|
|
* @return array |
61
|
|
|
*/ |
62
|
|
|
protected function buildExtraParameters() |
63
|
|
|
{ |
64
|
|
|
return collect($this->config['user']) |
65
|
|
|
->except(['external_id', 'email']) |
66
|
|
|
->reject([$this, 'nullProperty']) |
67
|
|
|
->map([$this, 'parseUserValue']) |
68
|
|
|
->toArray(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Process the SSO login request from Discourse |
73
|
|
|
* |
74
|
|
|
* @param Request $request |
75
|
|
|
* |
76
|
|
|
* @return mixed |
77
|
|
|
*/ |
78
|
|
|
public function login(Request $request) |
79
|
|
|
{ |
80
|
|
|
if (! ($this->sso->validatePayload($payload = $request->get('sso'), $request->get('sig')))) { |
81
|
|
|
abort(403); //Forbidden |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$this->user = $request->user(); |
85
|
|
|
|
86
|
|
|
$query = $this->sso->getSignInString( |
87
|
|
|
$this->sso->getNonce($payload), |
88
|
|
|
$this->user->{$this->config['user']['external_id']}, |
89
|
|
|
$this->user->{$this->config['user']['email']}, |
90
|
|
|
$this->buildExtraParameters($this->user) |
|
|
|
|
91
|
|
|
); |
92
|
|
|
|
93
|
|
|
return redirect(str_finish($this->config['url'], '/').'session/sso_login?'.$query); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Check to see if property is null |
98
|
|
|
* |
99
|
|
|
* @param string $property |
100
|
|
|
* @return bool |
101
|
|
|
*/ |
102
|
|
|
public function nullProperty($property) |
103
|
|
|
{ |
104
|
|
|
return is_null($property); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Get the property from the user |
109
|
|
|
* |
110
|
|
|
* If a string is passed in, then get it from the user object, otherwise, return what was given |
111
|
|
|
* |
112
|
|
|
* @param string $property |
113
|
|
|
* @return mixed |
114
|
|
|
*/ |
115
|
|
|
public function parseUserValue($property) |
116
|
|
|
{ |
117
|
|
|
if (! is_string($property)) { |
118
|
|
|
return $property; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $this->user->{$property}; |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.