MediaWiki REL1_39
BotPasswordSessionProvider.php
Go to the documentation of this file.
1<?php
25
26use BotPassword;
29use User;
30use WebRequest;
31
38 private $grantsInfo;
39
47 public function __construct( GrantsInfo $grantsInfo, array $params = [] ) {
48 if ( !isset( $params['sessionCookieName'] ) ) {
49 $params['sessionCookieName'] = '_BPsession';
50 }
51 parent::__construct( $params );
52
53 if ( !isset( $params['priority'] ) ) {
54 throw new \InvalidArgumentException( __METHOD__ . ': priority must be specified' );
55 }
56 if ( $params['priority'] < SessionInfo::MIN_PRIORITY ||
57 $params['priority'] > SessionInfo::MAX_PRIORITY
58 ) {
59 throw new \InvalidArgumentException( __METHOD__ . ': Invalid priority' );
60 }
61
62 $this->priority = $params['priority'];
63
64 $this->grantsInfo = $grantsInfo;
65 }
66
67 public function provideSessionInfo( WebRequest $request ) {
68 // Only relevant for the (Action or REST) API
69 if ( !defined( 'MW_API' ) && !defined( 'MW_REST_API' ) ) {
70 return null;
71 }
72
73 // Enabled?
74 if ( !$this->getConfig()->get( MainConfigNames::EnableBotPasswords ) ) {
75 return null;
76 }
77
78 // Have a session ID?
79 $id = $this->getSessionIdFromCookie( $request );
80 if ( $id === null ) {
81 return null;
82 }
83
84 return new SessionInfo( $this->priority, [
85 'provider' => $this,
86 'id' => $id,
87 'persisted' => true
88 ] );
89 }
90
91 public function newSessionInfo( $id = null ) {
92 // We don't activate by default
93 return null;
94 }
95
103 public function newSessionForRequest( User $user, BotPassword $bp, WebRequest $request ) {
104 $id = $this->getSessionIdFromCookie( $request );
106 'provider' => $this,
107 'id' => $id,
108 'userInfo' => UserInfo::newFromUser( $user, true ),
109 'persisted' => $id !== null,
110 'metadata' => [
111 'centralId' => $bp->getUserCentralId(),
112 'appId' => $bp->getAppId(),
113 'token' => $bp->getToken(),
114 'rights' => $this->grantsInfo->getGrantRights( $bp->getGrants() ),
115 ],
116 ] );
117 $session = $this->getManager()->getSessionFromInfo( $info, $request );
118 $session->persist();
119 return $session;
120 }
121
126 public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) {
127 $missingKeys = array_diff(
128 [ 'centralId', 'appId', 'token' ],
129 array_keys( $metadata )
130 );
131 if ( $missingKeys ) {
132 $this->logger->info( 'Session "{session}": Missing metadata: {missing}', [
133 'session' => $info->__toString(),
134 'missing' => implode( ', ', $missingKeys ),
135 ] );
136 return false;
137 }
138
139 $bp = BotPassword::newFromCentralId( $metadata['centralId'], $metadata['appId'] );
140 if ( !$bp ) {
141 $this->logger->info(
142 'Session "{session}": No BotPassword for {centralId} {appId}',
143 [
144 'session' => $info->__toString(),
145 'centralId' => $metadata['centralId'],
146 'appId' => $metadata['appId'],
147 ] );
148 return false;
149 }
150
151 if ( !hash_equals( $metadata['token'], $bp->getToken() ) ) {
152 $this->logger->info( 'Session "{session}": BotPassword token check failed', [
153 'session' => $info->__toString(),
154 'centralId' => $metadata['centralId'],
155 'appId' => $metadata['appId'],
156 ] );
157 return false;
158 }
159
160 $status = $bp->getRestrictions()->check( $request );
161 if ( !$status->isOK() ) {
162 $this->logger->info(
163 'Session "{session}": Restrictions check failed',
164 [
165 'session' => $info->__toString(),
166 'restrictions' => $status->getValue(),
167 'centralId' => $metadata['centralId'],
168 'appId' => $metadata['appId'],
169 ] );
170 return false;
171 }
172
173 // Update saved rights
174 $metadata['rights'] = $this->grantsInfo->getGrantRights( $bp->getGrants() );
175
176 return true;
177 }
178
183 public function preventSessionsForUser( $username ) {
184 BotPassword::removeAllPasswordsForUser( $username );
185 }
186
187 public function getAllowedUserRights( SessionBackend $backend ) {
188 if ( $backend->getProvider() !== $this ) {
189 throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' );
190 }
191 $data = $backend->getProviderMetadata();
192 if ( $data && isset( $data['rights'] ) && is_array( $data['rights'] ) ) {
193 return $data['rights'];
194 }
195
196 // Should never happen
197 $this->logger->debug( __METHOD__ . ': No provider metadata, returning no rights allowed' );
198 return [];
199 }
200}
Utility class for bot passwords.
getUserCentralId()
Get the central user ID.
A class containing constants representing the names of configuration variables.
const EnableBotPasswords
Name constant for the EnableBotPasswords setting, for use with Config::get()
Users can authorize applications to use their account via OAuth.
newSessionForRequest(User $user, BotPassword $bp, WebRequest $request)
Create a new session for a request.
provideSessionInfo(WebRequest $request)
Provide session info for a request.
__construct(GrantsInfo $grantsInfo, array $params=[])
preventSessionsForUser( $username)
Prevent future sessions for the user.If the provider is capable of returning a SessionInfo with a ver...
getAllowedUserRights(SessionBackend $backend)
Fetch the rights allowed the user when the specified session is active.
newSessionInfo( $id=null)
Provide session info for a new, empty session.
refreshSessionInfo(SessionInfo $info, WebRequest $request, &$metadata)
Validate a loaded SessionInfo and refresh provider metadata.This is similar in purpose to the 'Sessio...
An ImmutableSessionProviderWithCookie doesn't persist the user, but optionally can use a cookie to su...
getSessionIdFromCookie(WebRequest $request)
Get the session ID from the cookie, if any.
This is the actual workhorse for Session.
getProviderMetadata()
Fetch provider metadata.
getProvider()
Fetch the SessionProvider for this session.
Value object returned by SessionProvider.
const MIN_PRIORITY
Minimum allowed priority.
const MAX_PRIORITY
Maximum allowed priority.
getManager()
Get the session manager.
static newFromUser(User $user, $verified=false)
Create an instance from an existing User object.
Definition UserInfo.php:123
internal since 1.36
Definition User.php:70
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...