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
|
<?php
namespace MediaWiki\Extensions\OAuth\Repository;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\ScopeEntityInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use MediaWiki\Extensions\OAuth\Backend\MWOAuthException;
use MediaWiki\Extensions\OAuth\Backend\Utils;
use MediaWiki\Extensions\OAuth\Entity\ClientEntity;
use MediaWiki\Extensions\OAuth\Entity\ScopeEntity;
use MediaWiki\Extensions\OAuth\Entity\UserEntity;
use MWGrants;
class ScopeRepository implements ScopeRepositoryInterface {
/**
* @var array
*/
protected $allowedScopes = [
'#default',
'mwoauth-authonly',
'mwoauth-authonlyprivate'
];
public function __construct() {
$this->allowedScopes = array_merge( $this->allowedScopes, MWGrants::getValidGrants() );
}
/**
* Return information about a scope.
*
* @param string $identifier The scope identifier
*
* @return ScopeEntityInterface|null
*/
public function getScopeEntityByIdentifier( $identifier ) {
if ( in_array( $identifier, $this->allowedScopes, true ) ) {
return new ScopeEntity( $identifier );
}
return null;
}
/**
* Given a client, grant type and optional user identifier
* validate the set of scopes requested are valid and optionally
* append additional scopes or remove requested scopes.
*
* @param ScopeEntityInterface[] $scopes
* @param string $grantType
* @param ClientEntityInterface|ClientEntity $clientEntity
* @param null|string $userIdentifier
*
* @return ScopeEntityInterface[]
*/
public function finalizeScopes( array $scopes, $grantType,
ClientEntityInterface $clientEntity, $userIdentifier = null ) {
$scopes = $this->replaceDefaultScope( $scopes, $clientEntity );
if ( $grantType !== 'authorization_code' ) {
// For grants that do not require approval,
// just filter out the scopes that are not allowed for the client
return array_filter(
$scopes,
function ( ScopeEntityInterface $scope ) use ( $clientEntity ) {
return in_array( $scope->getIdentifier(), $clientEntity->getGrants(), true );
}
);
}
if ( !is_numeric( $userIdentifier ) ) {
return [];
}
$mwUser = Utils::getLocalUserFromCentralId( $userIdentifier );
$userEntity = UserEntity::newFromMWUser( $mwUser );
if ( $userEntity === null ) {
return [];
}
// Filter out not approved scopes
try {
$approval = $clientEntity->getCurrentAuthorization( $mwUser, wfWikiID() );
$approvedScopeIds = $approval->getGrants();
} catch ( MWOAuthException $ex ) {
$approvedScopeIds = [];
}
return array_filter(
$scopes,
function ( ScopeEntityInterface $scope ) use ( $approvedScopeIds ) {
return in_array( $scope->getIdentifier(), $approvedScopeIds, true );
}
);
}
/**
* Detect "#default" scope and replace it with all client's allowed scopes
*
* @param array $scopes
* @param ClientEntityInterface|ClientEntity $client
* @return array
*/
private function replaceDefaultScope( array $scopes, ClientEntityInterface $client ) {
// Normally, #default scope would be an only scope set, but go through whole array in case
// someone explicitly made a request with that scope set
$index = array_search( '#default', array_map( function ( ScopeEntityInterface $scope ) {
return $scope->getIdentifier();
}, $scopes ) );
if ( $index === false ) {
return $scopes;
}
return $client->getScopes();
}
}
|