MediaWiki  master
BotPasswordSessionProvider.php
Go to the documentation of this file.
1 <?php
25 
26 use BotPassword;
29 use User;
30 use 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 API
69  if ( !defined( 'MW_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 );
105  $info = new SessionInfo( SessionInfo::MAX_PRIORITY, [
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 ) {
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.
Definition: BotPassword.php:34
getUserCentralId()
Get the central user ID.
static newFromCentralId( $centralId, $appId, $flags=self::READ_NORMAL)
Load a BotPassword from the database.
static removeAllPasswordsForUser( $username)
Remove all passwords for a user, by name.
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.
Definition: GrantsInfo.php:33
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.
Definition: SessionInfo.php:37
const MIN_PRIORITY
Minimum allowed priority.
Definition: SessionInfo.php:39
const MAX_PRIORITY
Maximum allowed priority.
Definition: SessionInfo.php:42
getManager()
Get the session manager.
static newFromUser(User $user, $verified=false)
Create an instance from an existing User object.
Definition: UserInfo.php:123
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:69
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:43