Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslateSandboxHookHandler
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 4
132
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onUserGetRights
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
 onGetPreferences
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 onApiCheckCanExecute
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorSandbox;
5
6use ApiMessage;
7use Config;
8use MediaWiki\Api\Hook\ApiCheckCanExecuteHook;
9use MediaWiki\Permissions\Hook\UserGetRightsHook;
10use MediaWiki\Preferences\Hook\GetPreferencesHook;
11
12/**
13 * Hook handler for the TranslateSandbox.
14 * @author Eugene Wang'ombe
15 * @license GPL-2.0-or-later
16 * @since 2023.12
17 */
18class TranslateSandboxHookHandler implements
19    GetPreferencesHook,
20    ApiCheckCanExecuteHook,
21    UserGetRightsHook
22{
23    private bool $isTranslateSandboxEnabled;
24
25    public function __construct( Config $config ) {
26        $this->isTranslateSandboxEnabled = $config->get( 'TranslateUseSandbox' );
27    }
28
29    /** @inheritDoc */
30    public function onUserGetRights( $user, &$rights ): bool {
31        if ( !$this->isTranslateSandboxEnabled ) {
32            return true;
33        }
34
35        if ( !TranslateSandbox::isSandboxed( $user ) ) {
36            return true;
37        }
38        // right-translate-sandboxaction action-translate-sandboxaction
39        $rights = [
40            'editmyoptions',
41            'editmyprivateinfo',
42            'read',
43            'readapi',
44            'translate-sandboxaction',
45            'viewmyprivateinfo',
46            'writeapi',
47        ];
48
49        // Do not let other hooks add more actions
50        return false;
51    }
52
53    /** @inheritDoc */
54    public function onGetPreferences( $user, &$preferences ): void {
55        if ( !$this->isTranslateSandboxEnabled ) {
56            return;
57        }
58
59        $preferences['translate-sandbox'] = $preferences['translate-sandbox-reminders'] =
60            [ 'type' => 'api' ];
61    }
62
63    /**
64     * Inclusion listing for certain API modules. See also onUserGetRights.
65     * @inheritDoc
66     */
67    public function onApiCheckCanExecute( $module, $user, &$message ): bool {
68        if ( !$this->isTranslateSandboxEnabled ) {
69            return true;
70        }
71
72        $inclusionList = [
73            // Obviously this is needed to get out of the sandbox
74            TranslationStashActionApi::class,
75            // Used by UniversalLanguageSelector for example
76            'ApiOptions'
77        ];
78
79        if ( TranslateSandbox::isSandboxed( $user ) ) {
80            $class = get_class( $module );
81            if ( $module->isWriteMode() && !in_array( $class, $inclusionList, true ) ) {
82                $message = ApiMessage::create( 'apierror-writeapidenied' );
83                return false;
84            }
85        }
86
87        return true;
88    }
89}