MediaWiki REL1_40
BotPasswordSessionProvider.php
Go to the documentation of this file.
1<?php
25
26use BotPassword;
29use User;
30use WebRequest;
31
38 private $grantsInfo;
39
41 private $isApiRequest;
42
51 public function __construct( GrantsInfo $grantsInfo, array $params = [] ) {
52 if ( !isset( $params['sessionCookieName'] ) ) {
53 $params['sessionCookieName'] = '_BPsession';
54 }
55 parent::__construct( $params );
56
57 if ( !isset( $params['priority'] ) ) {
58 throw new \InvalidArgumentException( __METHOD__ . ': priority must be specified' );
59 }
60 if ( $params['priority'] < SessionInfo::MIN_PRIORITY ||
61 $params['priority'] > SessionInfo::MAX_PRIORITY
62 ) {
63 throw new \InvalidArgumentException( __METHOD__ . ': Invalid priority' );
64 }
65
66 $this->priority = $params['priority'];
67
68 $this->grantsInfo = $grantsInfo;
69
70 $this->isApiRequest = $params['isApiRequest']
71 ?? ( defined( 'MW_API' ) || defined( 'MW_REST_API' ) );
72 }
73
74 public function provideSessionInfo( WebRequest $request ) {
75 // Only relevant for the (Action or REST) API
76 if ( !$this->isApiRequest ) {
77 return null;
78 }
79
80 // Enabled?
81 if ( !$this->getConfig()->get( MainConfigNames::EnableBotPasswords ) ) {
82 return null;
83 }
84
85 // Have a session ID?
86 $id = $this->getSessionIdFromCookie( $request );
87 if ( $id === null ) {
88 return null;
89 }
90
91 return new SessionInfo( $this->priority, [
92 'provider' => $this,
93 'id' => $id,
94 'persisted' => true
95 ] );
96 }
97
98 public function newSessionInfo( $id = null ) {
99 // We don't activate by default
100 return null;
101 }
102
110 public function newSessionForRequest( User $user, BotPassword $bp, WebRequest $request ) {
111 $id = $this->getSessionIdFromCookie( $request );
113 'provider' => $this,
114 'id' => $id,
115 'userInfo' => UserInfo::newFromUser( $user, true ),
116 'persisted' => $id !== null,
117 'metadata' => [
118 'centralId' => $bp->getUserCentralId(),
119 'appId' => $bp->getAppId(),
120 'token' => $bp->getToken(),
121 'rights' => $this->grantsInfo->getGrantRights( $bp->getGrants() ),
122 ],
123 ] );
124 $session = $this->getManager()->getSessionFromInfo( $info, $request );
125 $session->persist();
126 return $session;
127 }
128
133 public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) {
134 $missingKeys = array_diff(
135 [ 'centralId', 'appId', 'token' ],
136 array_keys( $metadata )
137 );
138 if ( $missingKeys ) {
139 $this->logger->info( 'Session "{session}": Missing metadata: {missing}', [
140 'session' => $info->__toString(),
141 'missing' => implode( ', ', $missingKeys ),
142 ] );
143 return false;
144 }
145
146 $bp = BotPassword::newFromCentralId( $metadata['centralId'], $metadata['appId'] );
147 if ( !$bp ) {
148 $this->logger->info(
149 'Session "{session}": No BotPassword for {centralId} {appId}',
150 [
151 'session' => $info->__toString(),
152 'centralId' => $metadata['centralId'],
153 'appId' => $metadata['appId'],
154 ] );
155 return false;
156 }
157
158 if ( !hash_equals( $metadata['token'], $bp->getToken() ) ) {
159 $this->logger->info( 'Session "{session}": BotPassword token check failed', [
160 'session' => $info->__toString(),
161 'centralId' => $metadata['centralId'],
162 'appId' => $metadata['appId'],
163 ] );
164 return false;
165 }
166
167 $status = $bp->getRestrictions()->check( $request );
168 if ( !$status->isOK() ) {
169 $this->logger->info(
170 'Session "{session}": Restrictions check failed',
171 [
172 'session' => $info->__toString(),
173 'restrictions' => $status->getValue(),
174 'centralId' => $metadata['centralId'],
175 'appId' => $metadata['appId'],
176 ] );
177 return false;
178 }
179
180 // Update saved rights
181 $metadata['rights'] = $this->grantsInfo->getGrantRights( $bp->getGrants() );
182
183 return true;
184 }
185
190 public function preventSessionsForUser( $username ) {
191 BotPassword::removeAllPasswordsForUser( $username );
192 }
193
194 public function getAllowedUserRights( SessionBackend $backend ) {
195 if ( $backend->getProvider() !== $this ) {
196 throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' );
197 }
198 $data = $backend->getProviderMetadata();
199 if ( $data && isset( $data['rights'] ) && is_array( $data['rights'] ) ) {
200 return $data['rights'];
201 }
202
203 // Should never happen
204 $this->logger->debug( __METHOD__ . ': No provider metadata, returning no rights allowed' );
205 return [];
206 }
207}
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:71
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...