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
|
<?php
namespace MediaWiki\Extensions\OAuth;
use Config;
use MediaWiki\Extensions\OAuth\Backend\Consumer;
use MediaWiki\Extensions\OAuth\Backend\Utils;
use MediaWiki\MediaWikiServices;
use MWException;
use MWGrants;
use User;
class UserStatementProvider {
/** @var Config */
protected $config;
/** @var User */
protected $user;
/** @var Consumer */
protected $consumer;
/** @var array */
protected $grants;
/**
* @param User $user
* @param Consumer $consumer
* @param array $grants
* @return static
*/
public static function factory( User $user, Consumer $consumer, $grants = [] ) {
$mainConfig = MediaWikiServices::getInstance()->getMainConfig();
return new static( $mainConfig, $user, $consumer, $grants );
}
/**
* UserStatementProvider constructor.
* @param Config $config
* @param User $user
* @param Consumer $consumer
* @param array $grants
*/
protected function __construct( $config, $user, $consumer, $grants ) {
$this->config = $config;
$this->user = $user;
$this->consumer = $consumer;
$this->grants = $grants;
}
/**
* Retrieve user statement suitable for JWT encoding
*
* @return array
* @throws MWException
*/
public function getUserStatement() {
$statement = [];
// Include some of the OpenID Connect attributes
// http://openid.net/specs/openid-connect-core-1_0.html (draft 14)
// Issuer Identifier for the Issuer of the response.
$statement['iss'] = $this->config->get( 'CanonicalServer' );
// Subject identifier. A locally unique and never reassigned identifier.
// T264560: sub added via $this->getUserProfile()
// Audience(s) that this ID Token is intended for.
$statement['aud'] = $this->consumer->getConsumerKey();
// Expiration time on or after which the ID Token MUST NOT be accepted for processing.
$statement['exp'] = wfTimestamp() + 100;
// Time at which the JWT was issued.
$statement['iat'] = (int)wfTimestamp();
// TODO: Add auth_time, if we start tracking last login timestamp
$statement += $this->getUserProfile();
return $statement;
}
/**
* Retrieve user profile information
*
* @return array
*/
public function getUserProfile() {
$profile = [
'sub' => Utils::getCentralIdFromLocalUser( $this->user ),
];
// Include some MediaWiki info about the user
if ( !$this->user->isHidden() ) {
$profile['username'] = $this->user->getName();
$profile['editcount'] = intval( $this->user->getEditCount() );
$profile['confirmed_email'] = $this->user->isEmailConfirmed();
$profile['blocked'] = $this->user->getBlock() !== null;
$profile['registered'] = $this->user->getRegistration();
$profile['groups'] = $this->user->getEffectiveGroups();
$profile['rights'] = array_values( array_unique(
MediaWikiServices::getInstance()->getPermissionManager()->getUserPermissions( $this->user )
) );
$profile['grants'] = $this->grants;
if ( in_array( 'mwoauth-authonlyprivate', $this->grants ) ||
in_array( 'viewmyprivateinfo', MWGrants::getGrantRights( $profile['grants'] ) )
) {
// Paranoia - avoid showing the real name if the wiki is not configured to use
// it but it somehow exists (from past configuration, or some identity management
// extension). This is important as the viewmyprivateinfo grant is presented
// to the user differently when useRealNames() is false.
// Don't omit the field completely to avoid a breaking change.
$profile['realname'] = !in_array(
'realname', $this->config->get( 'HiddenPrefs' ), true
) ? $this->user->getRealName() : '';
$profile['email'] = $this->user->getEmail();
}
} else {
$profile['blocked'] = true;
}
return $profile;
}
}
|