Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.23% |
51 / 53 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
UpdateGrantIdHandler | |
96.23% |
51 / 53 |
|
83.33% |
5 / 6 |
13 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
validate | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
run | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
3 | |||
getParamSettings | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getBodyParamSettings | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
tryUpdateGrantId | |
91.30% |
21 / 23 |
|
0.00% |
0 / 1 |
6.02 |
1 | <?php |
2 | |
3 | declare( strict_types=1 ); |
4 | |
5 | namespace MediaWiki\Extension\WikimediaCampaignEvents\Rest; |
6 | |
7 | use MediaWiki\Extension\CampaignEvents\Event\Store\IEventLookup; |
8 | use MediaWiki\Extension\CampaignEvents\MWEntity\MWAuthorityProxy; |
9 | use MediaWiki\Extension\CampaignEvents\Permissions\PermissionChecker; |
10 | use MediaWiki\Extension\CampaignEvents\Rest\EventIDParamTrait; |
11 | use MediaWiki\Extension\WikimediaCampaignEvents\Grants\Exception\FluxxRequestException; |
12 | use MediaWiki\Extension\WikimediaCampaignEvents\Grants\Exception\InvalidGrantIDException; |
13 | use MediaWiki\Extension\WikimediaCampaignEvents\Grants\GrantIDLookup; |
14 | use MediaWiki\Extension\WikimediaCampaignEvents\Grants\GrantsStore; |
15 | use MediaWiki\Rest\LocalizedHttpException; |
16 | use MediaWiki\Rest\Response; |
17 | use MediaWiki\Rest\SimpleHandler; |
18 | use MediaWiki\Rest\TokenAwareHandlerTrait; |
19 | use MediaWiki\Rest\Validator\Validator; |
20 | use RuntimeException; |
21 | use Wikimedia\Message\MessageValue; |
22 | use Wikimedia\ParamValidator\ParamValidator; |
23 | |
24 | class UpdateGrantIdHandler extends SimpleHandler { |
25 | use EventIDParamTrait; |
26 | use TokenAwareHandlerTrait; |
27 | |
28 | private IEventLookup $eventLookup; |
29 | private PermissionChecker $permissionChecker; |
30 | private GrantsStore $grantsStore; |
31 | private GrantIDLookup $grantIDLookup; |
32 | |
33 | public function __construct( |
34 | IEventLookup $eventLookup, |
35 | GrantIDLookup $grantIDLookup, |
36 | PermissionChecker $permissionChecker, |
37 | GrantsStore $grantsStore |
38 | ) { |
39 | $this->eventLookup = $eventLookup; |
40 | $this->grantIDLookup = $grantIDLookup; |
41 | $this->permissionChecker = $permissionChecker; |
42 | $this->grantsStore = $grantsStore; |
43 | } |
44 | |
45 | /** |
46 | * @inheritDoc |
47 | */ |
48 | public function validate( Validator $restValidator ): void { |
49 | parent::validate( $restValidator ); |
50 | $this->validateToken(); |
51 | } |
52 | |
53 | protected function run( int $eventID ): Response { |
54 | $registration = $this->getRegistrationOrThrow( $this->eventLookup, $eventID ); |
55 | |
56 | $body = $this->getValidatedBody(); |
57 | $grantID = $body['grant_id'] ?? null; |
58 | if ( !$grantID ) { |
59 | throw new LocalizedHttpException( |
60 | MessageValue::new( 'wikimediacampaignevents-rest-grant-id-edit-empty' ), |
61 | 400 |
62 | ); |
63 | } |
64 | |
65 | $performer = new MWAuthorityProxy( $this->getAuthority() ); |
66 | if ( !$this->permissionChecker->userCanEditRegistration( $performer, $registration ) ) { |
67 | throw new LocalizedHttpException( |
68 | MessageValue::new( 'wikimediacampaignevents-rest-grant-id-edit-permission-denied' ), |
69 | 403 |
70 | ); |
71 | } |
72 | |
73 | $this->tryUpdateGrantId( $grantID, $eventID ); |
74 | |
75 | return $this->getResponseFactory()->createNoContent(); |
76 | } |
77 | |
78 | /** |
79 | * @inheritDoc |
80 | */ |
81 | public function getParamSettings(): array { |
82 | return $this->getIDParamSetting(); |
83 | } |
84 | |
85 | /** |
86 | * @inheritDoc |
87 | */ |
88 | public function getBodyParamSettings(): array { |
89 | return [ |
90 | 'grant_id' => [ |
91 | ParamValidator::PARAM_REQUIRED => true, |
92 | ParamValidator::PARAM_TYPE => 'string', |
93 | static::PARAM_SOURCE => 'body' |
94 | ], |
95 | ] + $this->getTokenParamDefinition(); |
96 | } |
97 | |
98 | private function tryUpdateGrantId( string $grantID, int $eventID ): void { |
99 | // TODO Avoid duplicating EventRegistrationFormHandler. |
100 | $pattern = "/^\d+-\d+$/"; |
101 | if ( !preg_match( $pattern, $grantID ) ) { |
102 | throw new LocalizedHttpException( |
103 | MessageValue::new( 'wikimediacampaignevents-rest-grant-id-edit-invalid' ), |
104 | 400 |
105 | ); |
106 | } |
107 | |
108 | try { |
109 | $this->grantIDLookup->doLookup( $grantID ); |
110 | } catch ( InvalidGrantIDException $_ ) { |
111 | throw new LocalizedHttpException( |
112 | MessageValue::new( 'wikimediacampaignevents-rest-grant-id-edit-invalid' ), |
113 | 400 |
114 | ); |
115 | } catch ( FluxxRequestException $_ ) { |
116 | throw new LocalizedHttpException( |
117 | MessageValue::new( 'wikimediacampaignevents-rest-grant-id-edit-api-error' ), |
118 | 503 |
119 | ); |
120 | } |
121 | |
122 | $previousGrantID = $this->grantsStore->getGrantID( $eventID ); |
123 | if ( $grantID !== $previousGrantID ) { |
124 | try { |
125 | $grantAgreementAt = $this->grantIDLookup->getAgreementAt( $grantID ); |
126 | } catch ( FluxxRequestException | InvalidGrantIDException $e ) { |
127 | throw new RuntimeException( "Could not retrieve agreement_at: $e" ); |
128 | } |
129 | $this->grantsStore->updateGrantID( $grantID, $eventID, $grantAgreementAt ); |
130 | } |
131 | } |
132 | } |