Skip to content
Merged
15 changes: 8 additions & 7 deletions inc/Loader/Git.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
* @since 4.0.0
*
* @param string $branch Name of the Git branch to clone. Empty string clones the default branch.
* @param \Required\Traduttore\Repository $repository Full repository instance.
*/
$branch = apply_filters( 'traduttore.git_clone_branch', '' );
$branch = apply_filters( 'traduttore.git_clone_branch', '', $this->repository );
if ( '' !== $branch ) {
$cmd .= ' --branch ' . escapeshellarg( $branch );
}
Expand All @@ -78,12 +79,12 @@
*
* @since 3.0.0
*
* @param bool $use_https Whether to use HTTPS instead of SSH for
* cloning repositories.
* Defaults to true for public repositories.
* @param \Required\Traduttore\Repository $repository The current repository.
* @param bool $use_https Whether to use HTTPS instead of SSH for
* cloning repositories.
* Defaults to true for public repositories.
* @param \Required\Traduttore\Loader\Repository $repository The current repository.
*/
$use_https = apply_filters( 'traduttore.git_clone_use_https', $this->repository->is_public(), $this->repository );

Check failure on line 87 in inc/Loader/Git.php

View workflow job for this annotation

GitHub Actions / Lint

@param Required\Traduttore\Loader\Repository $repository does not accept actual type of parameter: Required\Traduttore\Repository.

Check failure on line 87 in inc/Loader/Git.php

View workflow job for this annotation

GitHub Actions / Lint

@param Required\Traduttore\Loader\Repository $repository does not accept actual type of parameter: Required\Traduttore\Repository.

$clone_url = $this->repository->get_ssh_url();

Expand All @@ -96,9 +97,9 @@
*
* @since 3.0.0
*
* @param string $clone_url The URL to clone a Git repository.
* @param \Required\Traduttore\Repository $repository The current repository.
* @param string $clone_url The URL to clone a Git repository.
* @param \Required\Traduttore\Loader\Repository $repository The current repository.
*/
return apply_filters( 'traduttore.git_clone_url', (string) $clone_url, $this->repository );

Check failure on line 103 in inc/Loader/Git.php

View workflow job for this annotation

GitHub Actions / Lint

@param Required\Traduttore\Loader\Repository $repository does not accept actual type of parameter: Required\Traduttore\Repository.

Check failure on line 103 in inc/Loader/Git.php

View workflow job for this annotation

GitHub Actions / Lint

@param Required\Traduttore\Loader\Repository $repository does not accept actual type of parameter: Required\Traduttore\Repository.
}
}
32 changes: 32 additions & 0 deletions inc/WebhookHandler/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
namespace Required\Traduttore\WebhookHandler;

use Required\Traduttore\Project;
use Required\Traduttore\ProjectLocator;
use Required\Traduttore\WebhookHandler;
use WP_REST_Request;
use WP_REST_Response;

/**
* Base webhook handler class.
Expand Down Expand Up @@ -85,4 +87,34 @@ protected function get_secret( ?Project $project = null ): ?string {
*/
return apply_filters( 'traduttore.webhook_secret', $secret, $this, $project );
}

/**
* Return a valid project or errors. Allows to customize the pulled branch.
*
* @param string $repository Metadata to find a GlotPress project.
* @param string $default_branch Name of the repository's default branch.
* @param string $ref Name of the received branch through the webhook.
* @return \Required\Traduttore\Project|\WP_REST_Response|\WP_Error
*/
protected function resolve_project( string $repository, string $default_branch = '', string $ref = '' ): Project|WP_REST_Response|\WP_Error {
$locator = new ProjectLocator( $repository );
$project = $locator->get_project();

if ( ! $project ) {
return new \WP_Error( '404', 'Could not find project for this repository', [ 'status' => 404 ] );
}

if ( empty( $default_branch ) || empty( $ref ) ) {
return $project;
}

$branch = 'refs/heads/' . (string) apply_filters( 'traduttore.git_clone_branch', $default_branch, $project->get_repository_name() );

// We only care about the default or custom branch but don't want to send an error still.
if ( $branch !== $ref ) {
return new WP_REST_Response( [ 'result' => 'Not the default or custom branch' ] );
}

return $project;
}
}
11 changes: 6 additions & 5 deletions inc/WebhookHandler/Bitbucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Required\Traduttore\WebhookHandler;

use Required\Traduttore\Project;
use Required\Traduttore\ProjectLocator;
use Required\Traduttore\Repository;
use Required\Traduttore\Updater;
Expand Down Expand Up @@ -79,20 +80,20 @@ public function callback(): \WP_Error|\WP_REST_Response {
* @var array{repository: array{scm: string, full_name: string, links: array{html: array{href: string}}, is_private: bool}} $params
*/
$params = $this->request->get_params();
$href = (string) $params['repository']['links']['html']['href'];

$locator = new ProjectLocator( $params['repository']['links']['html']['href'] );
$project = $locator->get_project();
$project = $this->resolve_project( $href );

if ( ! $project ) {
return new \WP_Error( '404', 'Could not find project for this repository' );
if ( ! $project instanceof Project ) {
return $project;
}

if ( ! $project->get_repository_vcs_type() ) {
$project->set_repository_vcs_type( 'git' === $params['repository']['scm'] ? Repository::VCS_TYPE_GIT : Repository::VCS_TYPE_HG );
}

$project->set_repository_name( $params['repository']['full_name'] );
$project->set_repository_url( $params['repository']['links']['html']['href'] );
$project->set_repository_url( $href );

$ssh_url = sprintf( 'git@bitbucket.org:%s.git', $project->get_repository_name() );
$https_url = sprintf( 'https://bitbucket.org/%s.git', $project->get_repository_name() );
Expand Down
24 changes: 13 additions & 11 deletions inc/WebhookHandler/GitHub.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Required\Traduttore\WebhookHandler;

use Required\Traduttore\Project;
use Required\Traduttore\ProjectLocator;
use Required\Traduttore\Repository;
use Required\Traduttore\Updater;
Expand Down Expand Up @@ -117,24 +118,25 @@ public function callback(): \WP_Error|\WP_REST_Response {
* @var array{repository: array{ default_branch?: string, html_url: string, full_name: string, ssh_url: string, clone_url: string, private: bool }, ref: string } $params
*/

if ( ! isset( $params['repository']['default_branch'] ) ) {
return new \WP_Error( '400', 'Request incomplete', [ 'status' => 400 ] );
}
Comment thread
swissspidy marked this conversation as resolved.
$default_branch = (string) ( $params['repository']['default_branch'] ?? '' );
$html_url = (string) $params['repository']['html_url'];
$ref = (string) $params['ref'];

// We only care about the default branch but don't want to send an error still.
if ( 'refs/heads/' . $params['repository']['default_branch'] !== $params['ref'] ) {
return new WP_REST_Response( [ 'result' => 'Not the default branch' ] );
if ( '' === $default_branch
| '' === $html_url
| '' === $ref
) {
return new \WP_Error( '400', 'Request incomplete', [ 'status' => 400 ] );
}

$locator = new ProjectLocator( $params['repository']['html_url'] );
$project = $locator->get_project();
$project = $this->resolve_project( $html_url, $default_branch, $ref );

if ( ! $project ) {
return new \WP_Error( '404', 'Could not find project for this repository', [ 'status' => 404 ] );
if ( ! $project instanceof Project ) {
return $project;
}

$project->set_repository_name( $params['repository']['full_name'] );
$project->set_repository_url( $params['repository']['html_url'] );
$project->set_repository_url( $html_url );
$project->set_repository_ssh_url( $params['repository']['ssh_url'] );
$project->set_repository_https_url( $params['repository']['clone_url'] );
$project->set_repository_visibility( false === $params['repository']['private'] ? 'public' : 'private' );
Expand Down
25 changes: 15 additions & 10 deletions inc/WebhookHandler/GitLab.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Required\Traduttore\WebhookHandler;

use Required\Traduttore\Project;
use Required\Traduttore\ProjectLocator;
use Required\Traduttore\Repository;
use Required\Traduttore\Updater;
Expand Down Expand Up @@ -77,22 +78,26 @@ public function callback(): \WP_Error|\WP_REST_Response {
*
* @var array{project: array{default_branch: string, homepage: string, path_with_namespace: string, ssh_url: string, http_url: string, visibility_level: int}, ref: string} $params
*/
$params = $this->request->get_params();

// We only care about the default branch but don't want to send an error still.
if ( 'refs/heads/' . $params['project']['default_branch'] !== $params['ref'] ) {
return new WP_REST_Response( [ 'result' => 'Not the default branch' ] );
$params = $this->request->get_params();
$default_branch = (string) $params['project']['default_branch'];
$homepage = (string) $params['project']['homepage'];
$ref = (string) $params['ref'];

if ( '' === $default_branch
| '' === $homepage
| '' === $ref
) {
return new \WP_Error( '400', 'Request incomplete', [ 'status' => 400 ] );
}

$locator = new ProjectLocator( $params['project']['homepage'] );
$project = $locator->get_project();
$project = $this->resolve_project( $homepage, $default_branch, $ref );

if ( ! $project ) {
return new \WP_Error( '404', 'Could not find project for this repository' );
if ( ! $project instanceof Project ) {
return $project;
}

$project->set_repository_name( $params['project']['path_with_namespace'] );
$project->set_repository_url( $params['project']['homepage'] );
$project->set_repository_url( $homepage );
$project->set_repository_ssh_url( $params['project']['ssh_url'] );
$project->set_repository_https_url( $params['project']['http_url'] );
$project->set_repository_visibility( 20 === $params['project']['visibility_level'] ? 'public' : 'private' );
Expand Down
2 changes: 1 addition & 1 deletion tests/phpunit/tests/WebhookHandler/GitHub.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function test_invalid_branch(): void {
$response = rest_get_server()->dispatch( $request );

$this->assertSame( 200, $response->get_status() );
$this->assertSame( [ 'result' => 'Not the default branch' ], $response->get_data() );
$this->assertSame( [ 'result' => 'Not the default or custom branch' ], $response->get_data() );
}

public function test_invalid_project(): void {
Expand Down
24 changes: 23 additions & 1 deletion tests/phpunit/tests/WebhookHandler/GitLab.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function test_invalid_branch(): void {
$response = rest_get_server()->dispatch( $request );

$this->assertSame( 200, $response->get_status() );
$this->assertSame( [ 'result' => 'Not the default branch' ], $response->get_data() );
$this->assertSame( [ 'result' => 'Not the default or custom branch' ], $response->get_data() );
}

public function test_invalid_project(): void {
Expand All @@ -106,6 +106,28 @@ public function test_invalid_project(): void {
$this->assertErrorResponse( 404, $response );
}

public function test_request_incomplete(): void {
$request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' );
$request->set_body_params(
[
'ref' => '',
'project' => [
'default_branch' => 'master',
'path_with_namespace' => 'wearerequired/traduttore',
'homepage' => 'https://gitlab.com/wearerequired/traduttore',
'http_url' => 'https://gitlab.com/wearerequired/traduttore.git',
'ssh_url' => 'git@gitlab.com/wearerequired/traduttore.git',
'visibility_level' => 20,
],
]
);
$request->add_header( 'x-gitlab-event', 'Push Hook' );
$request->add_header( 'x-gitlab-token', 'traduttore-test' );
$response = rest_get_server()->dispatch( $request );

$this->assertErrorResponse( 400, $response );
}

public function test_valid_project(): void {
$request = new WP_REST_Request( 'POST', '/traduttore/v1/incoming-webhook' );
$request->set_body_params(
Expand Down
2 changes: 1 addition & 1 deletion tests/phpunit/tests/WebhookHandler/LegacyGitHub.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public function test_invalid_branch(): void {
$response = rest_get_server()->dispatch( $request );

$this->assertSame( 200, $response->get_status() );
$this->assertSame( [ 'result' => 'Not the default branch' ], $response->get_data() );
$this->assertSame( [ 'result' => 'Not the default or custom branch' ], $response->get_data() );
}

public function test_invalid_project(): void {
Expand Down
Loading