MediaWiki  master
BotPasswordSessionProvider.php
Go to the documentation of this file.
1 <?php
25 
26 use BotPassword;
27 use User;
28 use WebRequest;
29 
35 
42  public function __construct( array $params = [] ) {
43  if ( !isset( $params['sessionCookieName'] ) ) {
44  $params['sessionCookieName'] = '_BPsession';
45  }
46  parent::__construct( $params );
47 
48  if ( !isset( $params['priority'] ) ) {
49  throw new \InvalidArgumentException( __METHOD__ . ': priority must be specified' );
50  }
51  if ( $params['priority'] < SessionInfo::MIN_PRIORITY ||
52  $params['priority'] > SessionInfo::MAX_PRIORITY
53  ) {
54  throw new \InvalidArgumentException( __METHOD__ . ': Invalid priority' );
55  }
56 
57  $this->priority = $params['priority'];
58  }
59 
60  public function provideSessionInfo( WebRequest $request ) {
61  // Only relevant for the API
62  if ( !defined( 'MW_API' ) ) {
63  return null;
64  }
65 
66  // Enabled?
67  if ( !$this->config->get( 'EnableBotPasswords' ) ) {
68  return null;
69  }
70 
71  // Have a session ID?
72  $id = $this->getSessionIdFromCookie( $request );
73  if ( $id === null ) {
74  return null;
75  }
76 
77  return new SessionInfo( $this->priority, [
78  'provider' => $this,
79  'id' => $id,
80  'persisted' => true
81  ] );
82  }
83 
84  public function newSessionInfo( $id = null ) {
85  // We don't activate by default
86  return null;
87  }
88 
96  public function newSessionForRequest( User $user, BotPassword $bp, WebRequest $request ) {
97  $id = $this->getSessionIdFromCookie( $request );
99  'provider' => $this,
100  'id' => $id,
101  'userInfo' => UserInfo::newFromUser( $user, true ),
102  'persisted' => $id !== null,
103  'metadata' => [
104  'centralId' => $bp->getUserCentralId(),
105  'appId' => $bp->getAppId(),
106  'token' => $bp->getToken(),
107  'rights' => \MWGrants::getGrantRights( $bp->getGrants() ),
108  ],
109  ] );
110  $session = $this->getManager()->getSessionFromInfo( $info, $request );
111  $session->persist();
112  return $session;
113  }
114 
115  public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) {
116  $missingKeys = array_diff(
117  [ 'centralId', 'appId', 'token' ],
118  array_keys( $metadata )
119  );
120  if ( $missingKeys ) {
121  $this->logger->info( 'Session "{session}": Missing metadata: {missing}', [
122  'session' => $info,
123  'missing' => implode( ', ', $missingKeys ),
124  ] );
125  return false;
126  }
127 
128  $bp = BotPassword::newFromCentralId( $metadata['centralId'], $metadata['appId'] );
129  if ( !$bp ) {
130  $this->logger->info(
131  'Session "{session}": No BotPassword for {centralId} {appId}',
132  [
133  'session' => $info,
134  'centralId' => $metadata['centralId'],
135  'appId' => $metadata['appId'],
136  ] );
137  return false;
138  }
139 
140  if ( !hash_equals( $metadata['token'], $bp->getToken() ) ) {
141  $this->logger->info( 'Session "{session}": BotPassword token check failed', [
142  'session' => $info,
143  'centralId' => $metadata['centralId'],
144  'appId' => $metadata['appId'],
145  ] );
146  return false;
147  }
148 
149  $status = $bp->getRestrictions()->check( $request );
150  if ( !$status->isOK() ) {
151  $this->logger->info(
152  'Session "{session}": Restrictions check failed',
153  [
154  'session' => $info,
155  'restrictions' => $status->getValue(),
156  'centralId' => $metadata['centralId'],
157  'appId' => $metadata['appId'],
158  ] );
159  return false;
160  }
161 
162  // Update saved rights
163  $metadata['rights'] = \MWGrants::getGrantRights( $bp->getGrants() );
164 
165  return true;
166  }
167 
172  public function preventSessionsForUser( $username ) {
174  }
175 
176  public function getAllowedUserRights( SessionBackend $backend ) {
177  if ( $backend->getProvider() !== $this ) {
178  throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' );
179  }
180  $data = $backend->getProviderMetadata();
181  if ( $data && isset( $data['rights'] ) && is_array( $data['rights'] ) ) {
182  return $data['rights'];
183  }
184 
185  // Should never happen
186  $this->logger->debug( __METHOD__ . ': No provider metadata, returning no rights allowed' );
187  return [];
188  }
189 }
const MIN_PRIORITY
Minimum allowed priority.
Definition: SessionInfo.php:36
This is the actual workhorse for Session.
getProviderMetadata()
Fetch provider metadata.
getProvider()
Fetch the SessionProvider for this session.
getUserCentralId()
Get the central user ID.
newSessionForRequest(User $user, BotPassword $bp, WebRequest $request)
Create a new session for a request.
static newFromUser(User $user, $verified=false)
Create an instance from an existing User object.
Definition: UserInfo.php:117
getToken()
Get the token.
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
getAppId()
Get the app ID.
getManager()
Get the session manager.
An ImmutableSessionProviderWithCookie doesn&#39;t persist the user, but optionally can use a cookie to su...
const MAX_PRIORITY
Maximum allowed priority.
Definition: SessionInfo.php:39
static newFromCentralId( $centralId, $appId, $flags=self::READ_NORMAL)
Load a BotPassword from the database.
refreshSessionInfo(SessionInfo $info, WebRequest $request, &$metadata)
getSessionIdFromCookie(WebRequest $request)
Get the session ID from the cookie, if any.
getGrants()
Get the grants.
static removeAllPasswordsForUser( $username)
Remove all passwords for a user, by name.
Value object returned by SessionProvider.
Definition: SessionInfo.php:34
static getGrantRights( $grants)
Fetch the rights allowed by a set of grants.
Definition: MWGrants.php:105