SsoController::castBooleansToString()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 3
rs 10
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
use Illuminate\Support\Str;
12
13
/**
14
 * Class SsoController
15
 *
16
 * Controller to process the Discourse SSO request.  There is a good bit of logic in here that almost feels like too
17
 * much for a controller, but given that this is the only thing that this controller is doing, I am not going to break
18
 * it out into a service class.
19
 *
20
 * @package Spinen\Discourse\Controllers
21
 */
22
class SsoController extends Controller
23
{
24
    /**
25
     * Package configuration
26
     *
27
     * @var Collection
28
     */
29
    protected $config;
30
31
    /**
32
     * SSOHelper Instance
33
     *
34
     * @var SSOHelper
35
     */
36
    protected $sso;
37
38
    /**
39
     * Authenticated user
40
     *
41
     * @var User
42
     */
43
    protected $user;
44
45
    /**
46
     * SsoController constructor.
47
     *
48
     * @param Config $config
49
     * @param SSOHelper $sso
50
     */
51 5
    public function __construct(Config $config, SSOHelper $sso)
52
    {
53 5
        $this->loadConfigs($config);
54
55 5
        $this->sso = $sso->setSecret($this->config->get('secret'));
56 5
    }
57
58
    /**
59
     * Build out the extra parameters to send to Discourse
60
     *
61
     * @return array
62
     */
63 1
    protected function buildExtraParameters()
64
    {
65 1
        return $this->config->get('user')
66 1
                            ->except(['access', 'email', 'external_id'])
67 1
                            ->reject([$this, 'nullProperty'])
68 1
                            ->map([$this, 'parseUserValue'])
69 1
                            ->map([$this, 'castBooleansToString'])
70 1
                            ->toArray();
71
    }
72
73
    /**
74
     * Make boolean's into string
75
     *
76
     * The Discourse SSO API does not accept 0 or 1 for false or true.  You must send
77
     * "false" or "true", so convert any boolean property to the string version.
78
     *
79
     * @param $property
80
     *
81
     * @return string
82
     */
83 1
    public function castBooleansToString($property)
84
    {
85 1
        if (! is_bool($property)) {
86 1
            return $property;
87
        }
88
89 1
        return ($property) ? 'true' : 'false';
90
    }
91
92
    /**
93
     * Cache the configs on the object as a collection
94
     *
95
     * The 'user' property will be an array, so go ahead and convert it to a collection
96
     *
97
     * @param Config $config
98
     */
99 5
    protected function loadConfigs(Config $config)
100
    {
101 5
        $this->config = collect($config->get('services.discourse'));
102 5
        $this->config->put('user', collect($this->config->get('user')));
103 5
    }
104
105
    /**
106
     * Process the SSO login request from Discourse
107
     *
108
     * @param Request $request
109
     *
110
     * @return mixed
111
     * @throws 403
112
     */
113 4
    public function login(Request $request)
114
    {
115 4
        $this->user = $request->user();
116 4
        $access = $this->config->get('user')
117 4
                               ->get('access', null);
118
119 4
        if (! is_null($access) && ! $this->parseUserValue($access)) {
120 1
            abort(403); //Forbidden
121
        }
122
123 3
        if (! ($this->sso->validatePayload($payload = $request->get('sso'), $request->get('sig')))) {
124 2
            abort(403); //Forbidden
125
        }
126
127 1
        $query = $this->sso->getSignInString(
128 1
            $this->sso->getNonce($payload),
129 1
            $this->parseUserValue($this->config->get('user')
130 1
                                               ->get('external_id')),
131 1
            $this->parseUserValue($this->config->get('user')
132 1
                                               ->get('email')),
133 1
            $this->buildExtraParameters()
134
        );
135
136 1
        return redirect(Str::finish($this->config->get('url'), '/').'session/sso_login?'.$query);
137
    }
138
139
    /**
140
     * Check to see if property is null
141
     *
142
     * @param string $property
143
     * @return bool
144
     */
145 1
    public function nullProperty($property)
146
    {
147 1
        return is_null($property);
148
    }
149
150
    /**
151
     * Get the property from the user
152
     *
153
     * If a string is passed in, then get it from the user object, otherwise, return what was given
154
     *
155
     * @param mixed $property
156
     * @return mixed
157
     */
158 2
    public function parseUserValue($property)
159
    {
160 2
        if (! is_string($property)) {
161 1
            return $property;
162
        }
163
164 2
        return $this->user->{$property};
165
    }
166
}
167