diff --git a/src/Hydra/hydra.conf b/src/Hydra/hydra.conf
index ce065328..398ce61e 100644
--- a/src/Hydra/hydra.conf
+++ b/src/Hydra/hydra.conf
@@ -13,6 +13,8 @@ name Hydra
class DBIx::Class
user_class DB::Users
+ role_relation userroles
+ role_field role
diff --git a/src/Hydra/lib/Hydra.pm b/src/Hydra/lib/Hydra.pm
index 8728caab..d636d06e 100644
--- a/src/Hydra/lib/Hydra.pm
+++ b/src/Hydra/lib/Hydra.pm
@@ -11,6 +11,7 @@ use Catalyst qw/-Debug
Static::Simple
StackTrace
Authentication
+ Authorization::Roles
Session
Session::Store::FastMmap
Session::State::Cookie
diff --git a/src/Hydra/lib/Hydra/Controller/Root.pm b/src/Hydra/lib/Hydra/Controller/Root.pm
index 6707458b..4bfd92e1 100644
--- a/src/Hydra/lib/Hydra/Controller/Root.pm
+++ b/src/Hydra/lib/Hydra/Controller/Root.pm
@@ -74,7 +74,7 @@ sub login :Local {
? $c->flash->{afterLogin}
: $c->uri_for('/'));
return;
- }
+ }
$c->stash->{errorMsg} = "Bad username or password.";
}
@@ -98,7 +98,6 @@ sub requireLogin {
sub queue :Local {
my ($self, $c) = @_;
- return requireLogin($c) if !$c->user_exists;
$c->stash->{template} = 'queue.tt';
$c->stash->{queue} = [$c->model('DB::Builds')->search(
{finished => 0}, {join => 'schedulingInfo', order_by => ["priority DESC", "timestamp"]})];
@@ -118,6 +117,8 @@ sub updateProject {
$project->displayname($displayName);
$project->description(trim $c->request->params->{description});
$project->enabled(trim($c->request->params->{enabled}) eq "1" ? 1 : 0);
+ $project->owner(trim($c->request->params->{owner}))
+ if $c->check_user_roles('admin');
$project->update;
@@ -236,21 +237,35 @@ sub project :Local {
$subcommand = "" unless defined $subcommand;
- if ($subcommand eq "edit") {
- $c->stash->{edit} = 1;
- } elsif ($subcommand eq "submit" && $isPosted) {
- $c->model('DB')->schema->txn_do(sub {
- updateProject($c, $project);
- });
- return $c->res->redirect($c->uri_for("/project", trim $c->request->params->{name}));
- } elsif ($subcommand eq "delete" && $isPosted) {
- $c->model('DB')->schema->txn_do(sub {
- $project->delete;
- });
- return $c->res->redirect($c->uri_for("/"));
- } elsif ($subcommand eq "") {
- } else {
- return error($c, "Unknown subcommand $subcommand.");
+ if ($subcommand ne "") {
+
+ return requireLogin($c) if !$c->user_exists;
+
+ if (!$c->check_user_roles('admin') && $c->user->username ne $project->owner) {
+ return error($c, "Only the project owner or the administrator can perform this operation.");
+ }
+
+ if ($subcommand eq "edit") {
+ $c->stash->{edit} = 1;
+ }
+
+ elsif ($subcommand eq "submit" && $isPosted) {
+ $c->model('DB')->schema->txn_do(sub {
+ updateProject($c, $project);
+ });
+ return $c->res->redirect($c->uri_for("/project", trim $c->request->params->{name}));
+ }
+
+ elsif ($subcommand eq "delete" && $isPosted) {
+ $c->model('DB')->schema->txn_do(sub {
+ $project->delete;
+ });
+ return $c->res->redirect($c->uri_for("/"));
+ }
+
+ else {
+ return error($c, "Unknown subcommand $subcommand.");
+ }
}
$c->stash->{curProject} = $project;
@@ -283,6 +298,12 @@ sub project :Local {
sub createproject :Local {
my ($self, $c, $subcommand) = @_;
+ return requireLogin($c) if !$c->user_exists;
+
+ if (!$c->check_user_roles('admin')) {
+ return error($c, "Only administrators can create projects.");
+ }
+
if (defined $subcommand && $subcommand eq "submit") {
eval {
my $projectName = $c->request->params->{name};
diff --git a/src/Hydra/lib/Hydra/Schema.pm b/src/Hydra/lib/Hydra/Schema.pm
index 285200a0..6923ce88 100644
--- a/src/Hydra/lib/Hydra/Schema.pm
+++ b/src/Hydra/lib/Hydra/Schema.pm
@@ -8,8 +8,8 @@ use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes;
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jK/9VMZBot2RJwtlHA6QIg
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OcrPIHyQBUa+kF79Ltf95g
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Buildinputs.pm b/src/Hydra/lib/Hydra/Schema/Buildinputs.pm
index 3dee83d1..c92f6bae 100644
--- a/src/Hydra/lib/Hydra/Schema/Buildinputs.pm
+++ b/src/Hydra/lib/Hydra/Schema/Buildinputs.pm
@@ -36,8 +36,8 @@ __PACKAGE__->belongs_to("build", "Hydra::Schema::Builds", { id => "build" });
__PACKAGE__->belongs_to("dependency", "Hydra::Schema::Builds", { id => "dependency" });
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LRcAsbLWbetVw+DCDnv/9w
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BEl4PIMuykTwqyl7La0pKQ
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Buildproducts.pm b/src/Hydra/lib/Hydra/Schema/Buildproducts.pm
index 90bfab84..1e599127 100644
--- a/src/Hydra/lib/Hydra/Schema/Buildproducts.pm
+++ b/src/Hydra/lib/Hydra/Schema/Buildproducts.pm
@@ -33,8 +33,8 @@ __PACKAGE__->set_primary_key("build", "productnr");
__PACKAGE__->belongs_to("build", "Hydra::Schema::Builds", { id => "build" });
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Pu6gWxltfVJJ+9DBiC9bYg
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uEkpbb6hgGe47sDE7KtLDQ
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Buildresultinfo.pm b/src/Hydra/lib/Hydra/Schema/Buildresultinfo.pm
index 0a640825..e94cd7cd 100644
--- a/src/Hydra/lib/Hydra/Schema/Buildresultinfo.pm
+++ b/src/Hydra/lib/Hydra/Schema/Buildresultinfo.pm
@@ -29,8 +29,8 @@ __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:X5GXZRLAaCMl8OKBGjtztw
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CfJnTtjRXGV5dD/MWbrJxA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Builds.pm b/src/Hydra/lib/Hydra/Schema/Builds.pm
index 05537fd6..48f20263 100644
--- a/src/Hydra/lib/Hydra/Schema/Builds.pm
+++ b/src/Hydra/lib/Hydra/Schema/Builds.pm
@@ -70,8 +70,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:h32zqOEGcpXQy7pshiWVMA
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:AFGyXbj7hMxpQxjzgpvrCw
__PACKAGE__->has_many(dependents => 'Hydra::Schema::Buildinputs', 'dependency');
diff --git a/src/Hydra/lib/Hydra/Schema/Buildschedulinginfo.pm b/src/Hydra/lib/Hydra/Schema/Buildschedulinginfo.pm
index 3b4e4697..993090e3 100644
--- a/src/Hydra/lib/Hydra/Schema/Buildschedulinginfo.pm
+++ b/src/Hydra/lib/Hydra/Schema/Buildschedulinginfo.pm
@@ -23,8 +23,8 @@ __PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:egegc7kFKTt9cEGuomi0cQ
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:O6brsCdVF4TfvtmI9R+TOA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Buildsteps.pm b/src/Hydra/lib/Hydra/Schema/Buildsteps.pm
index 3818f0ab..16ea4f15 100644
--- a/src/Hydra/lib/Hydra/Schema/Buildsteps.pm
+++ b/src/Hydra/lib/Hydra/Schema/Buildsteps.pm
@@ -35,8 +35,8 @@ __PACKAGE__->set_primary_key("id", "stepnr");
__PACKAGE__->belongs_to("id", "Hydra::Schema::Builds", { id => "id" });
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kFD90OFRM1aqVVCBCh/geA
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:klPmbTcngdzKN+Dzhj8gvw
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Cachedpathinputs.pm b/src/Hydra/lib/Hydra/Schema/Cachedpathinputs.pm
index 030b8b70..11a0c7b4 100644
--- a/src/Hydra/lib/Hydra/Schema/Cachedpathinputs.pm
+++ b/src/Hydra/lib/Hydra/Schema/Cachedpathinputs.pm
@@ -22,8 +22,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("srcpath", "sha256hash");
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:r/3GaLIIWaX1fh8kfuQp+w
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:vGVYmR4k3kezEwiCGSXZWQ
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Cachedsubversioninputs.pm b/src/Hydra/lib/Hydra/Schema/Cachedsubversioninputs.pm
index 02f818bd..2d065cc1 100644
--- a/src/Hydra/lib/Hydra/Schema/Cachedsubversioninputs.pm
+++ b/src/Hydra/lib/Hydra/Schema/Cachedsubversioninputs.pm
@@ -20,8 +20,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("uri", "revision");
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yTp1XcBSQ+6OJvVLugRh1w
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ORooKeTpZBPOQCgosHLGeg
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Jobsetinputalts.pm b/src/Hydra/lib/Hydra/Schema/Jobsetinputalts.pm
index e9466924..c60d3110 100644
--- a/src/Hydra/lib/Hydra/Schema/Jobsetinputalts.pm
+++ b/src/Hydra/lib/Hydra/Schema/Jobsetinputalts.pm
@@ -33,8 +33,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lYdNLENxLW2mtZ2w+jou8w
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZeFpiIuYHvaFqRSppuUpoA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Jobsetinputs.pm b/src/Hydra/lib/Hydra/Schema/Jobsetinputs.pm
index 1e5d24ef..c1b7989d 100644
--- a/src/Hydra/lib/Hydra/Schema/Jobsetinputs.pm
+++ b/src/Hydra/lib/Hydra/Schema/Jobsetinputs.pm
@@ -43,8 +43,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Bk/vLWpBjR3ZU0p1KN7KfA
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/PmcpU0eiLZT+dlUZYyTaQ
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Jobsets.pm b/src/Hydra/lib/Hydra/Schema/Jobsets.pm
index a01e1843..d67bb916 100644
--- a/src/Hydra/lib/Hydra/Schema/Jobsets.pm
+++ b/src/Hydra/lib/Hydra/Schema/Jobsets.pm
@@ -50,8 +50,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9xvvQg/H0oibycB6B45V5A
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:EGgAWXbhcEC0uBobJMfpUw
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Projects.pm b/src/Hydra/lib/Hydra/Schema/Projects.pm
index 0c9ea455..58d66830 100644
--- a/src/Hydra/lib/Hydra/Schema/Projects.pm
+++ b/src/Hydra/lib/Hydra/Schema/Projects.pm
@@ -16,6 +16,8 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef },
"enabled",
{ data_type => "integer", is_nullable => 0, size => undef },
+ "owner",
+ { data_type => "text", is_nullable => 0, size => undef },
);
__PACKAGE__->set_primary_key("name");
__PACKAGE__->has_many(
@@ -30,8 +32,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3YMBhMqCjtpUjoTx4JLTOw
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jdyfk3vHisJRyE+VNR6dNA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Systemtypes.pm b/src/Hydra/lib/Hydra/Schema/Systemtypes.pm
index 78b0f262..361973d9 100644
--- a/src/Hydra/lib/Hydra/Schema/Systemtypes.pm
+++ b/src/Hydra/lib/Hydra/Schema/Systemtypes.pm
@@ -16,8 +16,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("system");
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SSKVFeg7ieeLJcF+s1uWWw
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:N/yG0cEhf0Y9Ve9YkdwRfA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/lib/Hydra/Schema/Userroles.pm b/src/Hydra/lib/Hydra/Schema/Userroles.pm
new file mode 100644
index 00000000..34eac4b1
--- /dev/null
+++ b/src/Hydra/lib/Hydra/Schema/Userroles.pm
@@ -0,0 +1,25 @@
+package Hydra::Schema::Userroles;
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class';
+
+__PACKAGE__->load_components("Core");
+__PACKAGE__->table("UserRoles");
+__PACKAGE__->add_columns(
+ "username",
+ { data_type => "text", is_nullable => 0, size => undef },
+ "role",
+ { data_type => "text", is_nullable => 0, size => undef },
+);
+__PACKAGE__->set_primary_key("username", "role");
+__PACKAGE__->belongs_to("username", "Hydra::Schema::Users", { username => "username" });
+
+
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:f16iU2I/Htdo7mXHvAdwyQ
+
+
+# You can replace this text with custom content, and it will be preserved on regeneration
+1;
diff --git a/src/Hydra/lib/Hydra/Schema/Users.pm b/src/Hydra/lib/Hydra/Schema/Users.pm
index 47df1922..db0f5a8a 100644
--- a/src/Hydra/lib/Hydra/Schema/Users.pm
+++ b/src/Hydra/lib/Hydra/Schema/Users.pm
@@ -18,10 +18,15 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef },
);
__PACKAGE__->set_primary_key("username");
+__PACKAGE__->has_many(
+ "userroles",
+ "Hydra::Schema::Userroles",
+ { "foreign.username" => "self.username" },
+);
-# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-26 20:02:52
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BgF6FK+9d7+cc72sp6pfCQ
+# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-27 00:07:44
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:wwRBfogrkKN2QdgmFjcUlA
# You can replace this text with custom content, and it will be preserved on regeneration
diff --git a/src/Hydra/root/login.tt b/src/Hydra/root/login.tt
new file mode 100644
index 00000000..81f5fd3a
--- /dev/null
+++ b/src/Hydra/root/login.tt
@@ -0,0 +1,39 @@
+[% WRAPPER layout.tt title="Login to Hydra" %]
+[% PROCESS common.tt %]
+
+
Login
+
+[% IF c.user_exists %]
+
+You are already logged in as [% c.user.username %].
+You can logout here.
+
+[% ELSE %]
+
+[% IF errorMsg %]
+Error: [% errorMsg %]
+[% END %]
+
+
+
+[% END %]
+
+[% END %]
diff --git a/src/Hydra/root/project.tt b/src/Hydra/root/project.tt
index 3c4398e1..04d9234e 100644
--- a/src/Hydra/root/project.tt
+++ b/src/Hydra/root/project.tt
@@ -163,6 +163,10 @@
Description: |
[% INCLUDE maybeEditString param="description" value=curProject.description %] |
+
+ Owner: |
+ [% INCLUDE maybeEditString param="owner" value=curProject.owner edit=(edit && c.check_user_roles('admin')) %] |
+
Enabled: |
diff --git a/src/hydra.sql b/src/hydra.sql
index d9a1c443..5982d35d 100644
--- a/src/hydra.sql
+++ b/src/hydra.sql
@@ -154,6 +154,8 @@ create table Projects (
displayName text not null, -- display name (e.g. "PatchELF")
description text,
enabled integer not null default 1
+ owner text not null,
+ foreign key (owner) references Users(userName) -- ignored by sqlite
);
@@ -269,3 +271,18 @@ create table Users (
emailAddress text not null,
password text not null -- sha256 hash
);
+
+
+create table UserRoles (
+ userName text not null,
+ role text not null,
+ primary key (userName, role),
+ foreign key (userName) references Users(userName) -- ignored by sqlite
+);
+
+
+create trigger cascadeUserDelete
+ before delete on Users
+ for each row begin
+ delete from UserRoles where userName = old.userName;
+ end;
|