Passed
Push — master ( b2e6ed...98569b )
by Conrad
01:14
created

GraphqlTest::testGraphQLContexts()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 101
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 67
nc 1
nop 0
dl 0
loc 101
rs 8.72
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace AdvancedLearning\Oauth2Server\Tests;
4
5
use AdvancedLearning\Oauth2Server\Models\Client;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2Server\Models\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use AdvancedLearning\Oauth2Server\Repositories\AccessTokenRepository;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2S...s\AccessTokenRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use AdvancedLearning\Oauth2Server\Repositories\ClientRepository;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2S...tories\ClientRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use AdvancedLearning\Oauth2Server\Repositories\RefreshTokenRepository;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2S...\RefreshTokenRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use AdvancedLearning\Oauth2Server\Repositories\ScopeRepository;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2S...itories\ScopeRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use AdvancedLearning\Oauth2Server\Repositories\UserRepository;
0 ignored issues
show
Bug introduced by
The type AdvancedLearning\Oauth2S...sitories\UserRepository was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use GraphQL\Type\Definition\ObjectType;
0 ignored issues
show
Bug introduced by
The type GraphQL\Type\Definition\ObjectType was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use GraphQL\Type\Definition\Type;
0 ignored issues
show
Bug introduced by
The type GraphQL\Type\Definition\Type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use GuzzleHttp\Psr7\Response;
0 ignored issues
show
Bug introduced by
The type GuzzleHttp\Psr7\Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use GuzzleHttp\Psr7\ServerRequest;
0 ignored issues
show
Bug introduced by
The type GuzzleHttp\Psr7\ServerRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Lcobucci\JWT\Parser;
0 ignored issues
show
Bug introduced by
The type Lcobucci\JWT\Parser was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use League\OAuth2\Server\AuthorizationServer;
0 ignored issues
show
Bug introduced by
The type League\OAuth2\Server\AuthorizationServer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use League\OAuth2\Server\CryptTrait;
0 ignored issues
show
Bug introduced by
The type League\OAuth2\Server\CryptTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
0 ignored issues
show
Bug introduced by
The type League\OAuth2\Server\Grant\ClientCredentialsGrant was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use League\OAuth2\Server\Grant\PasswordGrant;
0 ignored issues
show
Bug introduced by
The type League\OAuth2\Server\Grant\PasswordGrant was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Riddler7\Oauth2GraphQL\Controller;
21
use Riddler7\Oauth2GraphQL\Helpers\OauthContext;
22
use Riddler7\Oauth2GraphQL\Tests\BlankMutation;
23
use Riddler7\Oauth2GraphQL\Tests\BlankQuery;
24
use Riddler7\Oauth2GraphQL\Tests\BlankType;
25
use SilverStripe\Control\HTTPRequest;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Control\HTTPRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use SilverStripe\Core\Config\Config;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Core\Config\Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use SilverStripe\Core\Environment;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Core\Environment was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use SilverStripe\GraphQL\Manager;
0 ignored issues
show
Bug introduced by
The type SilverStripe\GraphQL\Manager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use SilverStripe\Dev\SapphireTest;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Dev\SapphireTest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use SilverStripe\Security\Member;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Security\Member was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use SilverStripe\Security\Security;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Security\Security was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use function file_get_contents;
33
use function file_put_contents;
34
use function sys_get_temp_dir;
35
36
class GraphqlTest extends SapphireTest
37
{
38
    use CryptTrait, OauthContext;
39
40
    protected static $fixture_file = 'tests/OAuthFixture.yml';
41
42
    protected static $privateKeyFile = 'private.key';
43
44
    protected static $publicKeyFile = 'public.key';
45
46
    /**
47
     * Setup test environment.
48
     */
49
    public function setUp()
50
    {
51
        parent::setUp();
52
53
        // copy private key so we can set correct permissions, file gets removed when tests finish
54
        $path = $this->getPrivateKeyPath();
55
        file_put_contents($path, file_get_contents(__DIR__ . '/' . self::$privateKeyFile));
56
        chmod($path, 0660);
57
        Environment::setEnv('OAUTH_PRIVATE_KEY_PATH', $path);
58
59
        // copy public key
60
        $path = $this->getPublicKeyPath();
61
        file_put_contents($path, file_get_contents(__DIR__ . '/' . self::$publicKeyFile));
62
        chmod($path, 0660);
63
        Environment::setEnv('OAUTH_PUBLIC_KEY_PATH', $path);
64
65
        Security::force_database_is_ready(true);
66
67
        $this->setEncryptionKey('lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen');
68
    }
69
70
    public function testGraphQLMember()
71
    {
72
        $userRepository = new UserRepository();
73
        $refreshRepository = new RefreshTokenRepository();
74
75
        $server = $this->getAuthorisationServer();
76
        $server->enableGrantType(
77
            new PasswordGrant($userRepository, $refreshRepository),
78
            new \DateInterval('PT1H')
79
        );
80
81
        $client = $this->objFromFixture(Client::class, 'webapp');
82
        $member = $this->objFromFixture(Member::class, 'member1');
83
84
        $request = (new ServerRequest(
85
            'POST',
86
            '',
87
            ['Content-Type' => 'application/json']
88
        ))->withParsedBody([
89
            'grant_type' => 'password',
90
            'client_id' => $client->Identifier,
91
            'client_secret' => $client->Secret,
92
            'scope' => 'members',
93
            'username' => $member->Email,
94
            'password' => 'password1'
95
        ]);
96
97
        $response = new Response();
98
        $response = $server->respondToAccessTokenRequest($request, $response);
99
100
        $data = json_decode((string)$response->getBody(), true);
101
        $token = $data['access_token'];
102
103
        // check for fn/ln
104
        $decoded = (new Parser())->parse($token);
105
106
        $this->assertEquals('My', $decoded->getClaim('fn'), 'First name should be correctly set');
107
        $this->assertEquals('Test', $decoded->getClaim('ln'), 'Last name should be correctly set');
108
109
        // create request
110
        $request = new HTTPRequest('GET', '/');
111
        $request->addHeader('authorization', 'Bearer ' . $token);
112
        // fake server port
113
        $_SERVER['SERVER_PORT'] = 443;
114
115
        $authMember = (new \Riddler7\Oauth2GraphQL\Authenticator())->authenticate($request);
116
117
        $this->assertEquals($member->ID, $authMember->ID, 'Member should exist in DB');
118
    }
119
120
    public function testGraphQLContexts()
121
    {
122
        $userRepository = new UserRepository();
123
        $refreshRepository = new RefreshTokenRepository();
124
125
        $server = $this->getAuthorisationServer();
126
        $server->enableGrantType(
127
            new PasswordGrant($userRepository, $refreshRepository),
128
            new \DateInterval('PT1H')
129
        );
130
131
        $client = $this->objFromFixture(Client::class, 'webapp');
132
        $member = $this->objFromFixture(Member::class, 'member1');
133
134
        $request = (new ServerRequest(
135
            'POST',
136
            '',
137
            ['Content-Type' => 'application/json']
138
        ))->withParsedBody([
139
            'grant_type' => 'password',
140
            'client_id' => $client->Identifier,
141
            'client_secret' => $client->Secret,
142
            'scope' => 'members',
143
            'username' => $member->Email,
144
            'password' => 'password1'
145
        ]);
146
147
        $response = new Response();
148
        $response = $server->respondToAccessTokenRequest($request, $response);
149
150
        $data = json_decode((string)$response->getBody(), true);
151
        $token = $data['access_token'];
152
153
        // create request
154
        $request = new HTTPRequest('GET', '/grqphql');
155
        $request->addHeader('authorization', 'Bearer ' . $token);
156
        // fake server port
157
        $_SERVER['SERVER_PORT'] = 443;
158
159
        // var to store context
160
        $context = [];
161
162
        // setup blank schema
163
        Config::modify()->set(Manager::class, 'schemas', [
164
            'myschema' => [
165
                'types' => [
166
                    'Blank' => BlankType::class
167
                ],
168
                'queries' => [
169
                    'BlankQuery' => BlankQuery::class
170
                ],
171
                'mutations' => [
172
                    'BlankMutation' => BlankMutation::class
173
                ]
174
            ]
175
        ]);
176
177
        $manager = new Manager('myschema');
178
179
        // extract the context
180
        $manager->addMiddleware(new GraphQLSchemaExtractor(function ($currentContext) use (&$context) {
181
            $context = $currentContext;
182
        }));
183
184
        $controller = new Controller($manager);
185
        $response = $controller->index($request);
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
186
187
        $this->assertEquals($client->Identifier, $context['oauthClientIdentifier']);
188
        $this->assertEquals(1, count($context['oauthScopes']));
189
        $this->assertEquals('members', $context['oauthScopes'][0]);
190
191
        // test the context helper
192
        $this->assertEquals(
193
            true,
194
            $this->hasOauthClient($context),
195
            'Context should contain a client'
196
        );
197
        $this->assertEquals(
198
            true,
199
            $this->hasScope($context, 'members'),
200
            'Context should have a \'members\' scope'
201
        );
202
        $this->assertEquals(
203
            false,
204
            $this->hasScope($context, 'admin'),
205
            'Context should not have an \'admin\' scope'
206
        );
207
        $this->assertEquals(
208
            true,
209
            $this->hasScopes($context,
210
                ['members'])
211
        );
212
        $this->assertEquals(
213
            false,
214
            $this->hasScopes($context,
215
                ['admin'])
216
        );
217
        $this->assertEquals(
218
            $client->ID,
219
            $this->getOauthClient($context)->ID,
220
            'The ids for the Oauth Client should match'
221
        );
222
    }
223
224
    /**
225
     * Setup the Authorization Server.
226
     *
227
     * @return AuthorizationServer
228
     */
229
    protected function getAuthorisationServer()
230
    {
231
        // Init our repositories
232
        $clientRepository = new ClientRepository(); // instance of ClientRepositoryInterface
233
        $scopeRepository = new ScopeRepository(); // instance of ScopeRepositoryInterface
234
        $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
235
236
        // Path to public and private keys
237
        $privateKey = $this->getPrivateKeyPath();
238
        $encryptionKey = $this->encryptionKey;
239
240
        // Setup the authorization server
241
        $server = new AuthorizationServer(
242
            $clientRepository,
243
            $accessTokenRepository,
244
            $scopeRepository,
245
            $privateKey,
246
            $encryptionKey
247
        );
248
249
        return $server;
250
    }
251
252
    /**
253
     * Get the resource server.
254
     *
255
     * @return \League\OAuth2\Server\ResourceServer
256
     */
257
    protected function getResourceServer()
258
    {
259
        // Init our repositories
260
        $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
261
262
        // Path to authorization server's public key
263
        $publicKeyPath = $this->getPublicKeyPath();
264
265
        // Setup the authorization server
266
        $server = new \League\OAuth2\Server\ResourceServer(
0 ignored issues
show
Bug introduced by
The type League\OAuth2\Server\ResourceServer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
267
            $accessTokenRepository,
268
            $publicKeyPath
269
        );
270
271
        return $server;
272
    }
273
274
    /**
275
     * Get the full path the private key.
276
     *
277
     * @return string
278
     */
279
    protected function getPrivateKeyPath()
280
    {
281
        return sys_get_temp_dir() . '/' . self::$privateKeyFile;
282
    }
283
284
    /**
285
     * Get the full path the public key.
286
     *
287
     * @return string
288
     */
289
    protected function getPublicKeyPath()
290
    {
291
        return sys_get_temp_dir() . '/' . self::$publicKeyFile;
292
    }
293
294
    /**
295
     * Cleanup test environment.
296
     */
297
    protected function tearDown()
298
    {
299
        parent::tearDown();
300
        // remove private key after tests have finished
301
        unlink($this->getPrivateKeyPath());
302
        // remove public key after tests have finished
303
        unlink($this->getPublicKeyPath());
304
    }
305
306
    /**
307
     * Generates a response with an access token using the client grant.
308
     *
309
     * @return \Psr\Http\Message\ResponseInterface
0 ignored issues
show
Bug introduced by
The type Psr\Http\Message\ResponseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
310
     */
311
    protected function generateClientAccessToken()
312
    {
313
        $server = $this->getAuthorisationServer();
314
        // Enable the client credentials grant on the server
315
        $server->enableGrantType(
316
            new ClientCredentialsGrant(),
317
            new \DateInterval('PT1H') // access tokens will expire after 1 hour
318
        );
319
320
        $client = $this->objFromFixture(Client::class, 'webapp');
321
322
        $request = $this->getClientRequest($client);
323
324
        $response = new Response();
325
        return $server->respondToAccessTokenRequest($request, $response);
326
    }
327
328
    /**
329
     * Get PSR7 request object to be used for a client grant.
330
     *
331
     * @param Client $client
332
     *
333
     * @return ServerRequest
334
     */
335
    protected function getClientRequest(Client $client)
336
    {
337
        // setup server vars
338
        $_SERVER['SERVER_PORT'] = 80;
339
        $_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
340
341
        return (new ServerRequest(
342
            'POST',
343
            '',
344
            ['Content-Type' => 'application/json']
345
        ))->withParsedBody([
346
            'grant_type' => 'client_credentials',
347
            'client_id' => $client->Identifier,
348
            'client_secret' => $client->Secret,
349
            'scope' => 'members'
350
        ]);
351
    }
352
353
}
354