web: require permissions for /api/push

This commit is contained in:
Pierre Bourdon 2024-08-27 02:57:16 +02:00
parent fd7fd0ad65
commit e5a8ee5c17
Signed by: delroth
GPG key ID: 6FB80DCD84DA0F1C
4 changed files with 51 additions and 19 deletions

View file

@ -242,23 +242,35 @@ sub push : Chained('api') PathPart('push') Args(0) {
$c->{stash}->{json}->{jobsetsTriggered} = [];
my $force = exists $c->request->query_params->{force};
my @jobsets = split /,/, ($c->request->query_params->{jobsets} // "");
foreach my $s (@jobsets) {
my @jobsetNames = split /,/, ($c->request->query_params->{jobsets} // "");
my @jobsets;
foreach my $s (@jobsetNames) {
my ($p, $j) = parseJobsetName($s);
my $jobset = $c->model('DB::Jobsets')->find($p, $j);
next unless defined $jobset && ($force || ($jobset->project->enabled && $jobset->enabled));
triggerJobset($self, $c, $jobset, $force);
push @jobsets, $jobset if defined $jobset;
}
my @repos = split /,/, ($c->request->query_params->{repos} // "");
foreach my $r (@repos) {
triggerJobset($self, $c, $_, $force) foreach $c->model('DB::Jobsets')->search(
foreach ($c->model('DB::Jobsets')->search(
{ 'project.enabled' => 1, 'me.enabled' => 1 },
{
join => 'project',
where => \ [ 'exists (select 1 from JobsetInputAlts where project = me.project and jobset = me.name and value = ?)', [ 'value', $r ] ],
order_by => 'me.id DESC'
});
})) {
push @jobsets, $_;
}
}
foreach my $jobset (@jobsets) {
requireRestartPrivileges($c, $jobset->project);
}
foreach my $jobset (@jobsets) {
next unless defined $jobset && ($force || ($jobset->project->enabled && $jobset->enabled));
triggerJobset($self, $c, $jobset, $force);
}
$self->status_ok(

View file

@ -35,6 +35,17 @@ my $queuedBuilds = $ctx->makeAndEvaluateJobset(
build => 0
);
# Login and save cookie for future requests
my $req = request(POST '/login',
Referer => 'http://localhost/',
Content => {
username => 'root',
password => 'rootPassword'
}
);
is($req->code, 302, "Logging in gets a 302");
my $cookie = $req->header("set-cookie");
subtest "/api/queue" => sub {
my $response = request(GET '/api/queue?nr=1');
ok($response->is_success, "The API enpdoint showing the queue returns 200.");
@ -102,7 +113,7 @@ subtest "/api/nrbuilds" => sub {
};
subtest "/api/push" => sub {
subtest "with a specific jobset" => sub {
subtest "without authentication" => sub {
my $build = $finishedBuilds->{"one_job"};
my $jobset = $build->jobset;
my $projectName = $jobset->project->name;
@ -110,6 +121,18 @@ subtest "/api/push" => sub {
is($jobset->forceeval, undef, "The existing jobset is not set to be forced to eval");
my $response = request(GET "/api/push?jobsets=$projectName:$jobsetName&force=1");
is($response->code, 403, "The API enpdoint for triggering jobsets requires authentication.");
};
subtest "with a specific jobset" => sub {
my $build = $finishedBuilds->{"one_job"};
my $jobset = $build->jobset;
my $projectName = $jobset->project->name;
my $jobsetName = $jobset->name;
is($jobset->forceeval, undef, "The existing jobset is not set to be forced to eval");
my $response = request(GET "/api/push?jobsets=$projectName:$jobsetName&force=1",
Cookie => $cookie);
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
my $data = is_json($response);
@ -128,7 +151,8 @@ subtest "/api/push" => sub {
print STDERR $repo;
my $response = request(GET "/api/push?repos=$repo&force=1");
my $response = request(GET "/api/push?repos=$repo&force=1",
Cookie => $cookie);
ok($response->is_success, "The API enpdoint for triggering jobsets returns 200.");
my $data = is_json($response);

View file

@ -11,20 +11,14 @@ my $ctx = test_context();
Catalyst::Test->import('Hydra');
my $user = $ctx->db()->resultset('Users')->create({
username => 'alice',
emailaddress => 'root@invalid.org',
password => '!'
});
$user->setPassword('foobar');
$user->userroles->update_or_create({ role => 'admin' });
$ctx->db(); # Ensure DB initialization.
# Login and save cookie for future requests
my $req = request(POST '/login',
Referer => 'http://localhost/',
Content => {
username => 'alice',
password => 'foobar'
username => 'root',
password => 'rootPassword'
}
);
is($req->code, 302, "Logging in gets a 302");

View file

@ -115,11 +115,13 @@ sub db {
$self->{_db} = Hydra::Model::DB->new();
if (!(defined $setup && $setup == 0)) {
$self->{_db}->resultset('Users')->create({
my $user = $self->{_db}->resultset('Users')->create({
username => "root",
emailaddress => 'root@invalid.org',
password => ''
password => '!'
});
$user->setPassword('rootPassword');
$user->userroles->update_or_create({ role => 'admin' });
}
}