Add OBS ACL Support

For details, please see task: APERTIS-5645
Signed-off-by: Ritesh Raj Sarraf's avatarRitesh Raj Sarraf <ritesh.sarraf@collabora.com>
parent d217971c
From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= <vivek@collabora.com>
Date: Tue, 5 Nov 2019 18:09:28 +0000
Subject: Add a new none-or-some element <allowbuilddep> to project meta
config
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
These patches merely add the new element which has no effect as of
this commit.
The new element is added to:
the RNG xml declarations
BSXML.pm (which serves a similar purpose for the back end code)
bs_srcserver which supplies the parsed metadata to backend services
the database
◦ initial schema (structure.sql)
◦ migration file
the rails model(s)
◦ the project,rb model
◦ a new allowbuilddep.rb model for the element iteslf
◦ _project.xml.builder which generates XML from the database
---
docs/api/api/obs.rng | 8 ++++++++
docs/api/api/project.rng | 4 ++++
src/api/app/models/allowbuilddep.rb | 3 +++
src/api/app/models/project.rb | 10 ++++++++++
src/api/app/views/models/_project.xml.builder | 5 +++++
src/api/db/migrate/20191011000000_create_allowbuilddeps.rb | 13 +++++++++++++
src/api/db/structure.sql | 10 ++++++++++
src/backend/BSXML.pm | 6 ++++++
src/backend/bs_srcserver | 2 +-
9 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 src/api/app/models/allowbuilddep.rb
create mode 100644 src/api/db/migrate/20191011000000_create_allowbuilddeps.rb
diff --git a/docs/api/api/obs.rng b/docs/api/api/obs.rng
index 8e7cec8..9abc5bd 100644
--- a/docs/api/api/obs.rng
+++ b/docs/api/api/obs.rng
@@ -149,6 +149,14 @@
</element>
</define>
+ <define ns="" name="allowbuilddep-element">
+ <element name="allowbuilddep">
+ <attribute name="name">
+ <data type="string" />
+ </attribute>
+ </element>
+ </define>
+
<define ns="" name="group-element">
<element name="group">
<attribute name="groupid">
diff --git a/docs/api/api/project.rng b/docs/api/api/project.rng
index fd02c18..14e9016 100644
--- a/docs/api/api/project.rng
+++ b/docs/api/api/project.rng
@@ -95,6 +95,10 @@
</element>
</optional>
+ <zeroOrMore>
+ <ref name="allowbuilddep-element"/>
+ </zeroOrMore>
+
<zeroOrMore>
<ref name="person-element"/>
</zeroOrMore>
diff --git a/src/api/app/models/allowbuilddep.rb b/src/api/app/models/allowbuilddep.rb
new file mode 100644
index 0000000..c774b5e
--- /dev/null
+++ b/src/api/app/models/allowbuilddep.rb
@@ -0,0 +1,3 @@
+class Allowbuilddep < ActiveRecord::Base
+ belongs_to :project, foreign_key: :db_project_id, inverse_of: :allowbuilddeps
+end
diff --git a/src/api/app/models/project.rb b/src/api/app/models/project.rb
index bfcb1a1..9e5f5d7 100644
--- a/src/api/app/models/project.rb
+++ b/src/api/app/models/project.rb
@@ -51,6 +51,8 @@ class Project < ActiveRecord::Base
end
has_many :attribs, :dependent => :destroy
+ has_many :allowbuilddeps, :dependent => :destroy, foreign_key: :db_project_id
+
has_many :repositories, :dependent => :destroy, foreign_key: :db_project_id
has_many :repository_architectures, -> { order("position") }, through: :repositories
has_many :architectures, -> { order("position").distinct }, :through => :repository_architectures
@@ -575,6 +577,7 @@ class Project < ActiveRecord::Base
#--- update repositories ---#
update_repositories(xmlhash, force)
#--- end update repositories ---#
+ update_allowbuilddep_from_xml(xmlhash)
end
def update_from_xml(xmlhash, force = nil)
@@ -584,6 +587,13 @@ class Project < ActiveRecord::Base
{ error: e.message }
end
+ def update_allowbuilddep_from_xml(xmlhash)
+ self.allowbuilddeps.destroy_all
+ xmlhash.elements('allowbuilddep') do |abd|
+ self.allowbuilddeps.create(name: abd['name'])
+ end
+ end
+
def update_repositories(xmlhash, force)
fill_repo_cache
diff --git a/src/api/app/views/models/_project.xml.builder b/src/api/app/views/models/_project.xml.builder
index 5ceae74..1d566a7 100644
--- a/src/api/app/views/models/_project.xml.builder
+++ b/src/api/app/views/models/_project.xml.builder
@@ -20,6 +20,11 @@ xml.project(project_attributes) do
my_model.render_relationships(xml)
+ adbs = my_model.allowbuilddeps.sort { |a, b| b.name <=> a.name }
+ adbs.each do |adb|
+ xml.allowbuilddep(name: adb.name)
+ end
+
repos = my_model.repositories.not_remote.sort { |a, b| b.name <=> a.name }
FlagHelper.flag_types.each do |flag_name|
flaglist = my_model.type_flags(flag_name)
diff --git a/src/api/db/migrate/20191011000000_create_allowbuilddeps.rb b/src/api/db/migrate/20191011000000_create_allowbuilddeps.rb
new file mode 100644
index 0000000..f4de579
--- /dev/null
+++ b/src/api/db/migrate/20191011000000_create_allowbuilddeps.rb
@@ -0,0 +1,13 @@
+class CreateAllowbuilddeps < ActiveRecord::Migration
+ def self.up
+ create_table :allowbuilddeps do |t|
+ t.integer :db_project_id, :null => false
+ t.string :name, :null => false
+ t.index [ :db_project_id, :name ]
+ end
+ end
+
+ def self.down
+ drop_table :allowbuilddeps
+ end
+end
diff --git a/src/api/db/structure.sql b/src/api/db/structure.sql
index 88a174e..7d829d4 100644
--- a/src/api/db/structure.sql
+++ b/src/api/db/structure.sql
@@ -1,3 +1,11 @@
+CREATE TABLE `allowbuilddeps` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `db_project_id` int(11) NOT NULL,
+ `name` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `index_allowbuilddeps_on_db_project_id_and_name` (`db_project_id`,`name`(191))
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
CREATE TABLE `architectures` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
@@ -1682,6 +1690,8 @@ INSERT INTO schema_migrations (version) VALUES ('20160518105300');
INSERT INTO schema_migrations (version) VALUES ('20160824132643');
+INSERT INTO schema_migrations (version) VALUES ('20191011000000');
+
INSERT INTO schema_migrations (version) VALUES ('21');
INSERT INTO schema_migrations (version) VALUES ('22');
diff --git a/src/backend/BSXML.pm b/src/backend/BSXML.pm
index f9d296b..45ca785 100644
--- a/src/backend/BSXML.pm
+++ b/src/backend/BSXML.pm
@@ -115,6 +115,10 @@ our @flags = (
[ 'access' => @disableenable ],
);
+our @allowbuilddep = (
+ [[ 'allowbuilddep' => 'name' ]],
+);
+
our @roles = (
[[ 'person' =>
'userid',
@@ -151,6 +155,7 @@ our $proj = [
'project',
],
@roles,
+ @allowbuilddep,
$maintenance,
@flags,
[ $repo ],
@@ -292,6 +297,7 @@ our $projpack = [
[],
'title',
'description',
+ @allowbuilddep,
'config',
'patternmd5',
[[ 'link' =>
diff --git a/src/backend/bs_srcserver b/src/backend/bs_srcserver
index 383d600..72a05ec 100755
--- a/src/backend/bs_srcserver
+++ b/src/backend/bs_srcserver
@@ -3266,7 +3266,7 @@ sub getprojpack {
}
next if $repoids && !grep {$repoids->{$_->{'name'}}} @{$proj->{'repository'} || []};
next if $packids && !grep {$packids->{$_}} @packages;
- for (qw{title description build publish debuginfo useforbuild remoteurl remoteproject download link sourceaccess privacy access lock}) {
+ for (qw{title description build publish debuginfo useforbuild remoteurl remoteproject download link sourceaccess privacy access lock allowbuilddep}) {
$jinfo->{$_} = $proj->{$_} if exists $proj->{$_};
}
if ($proj->{'access'}) {
From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= <vivek@collabora.com>
Date: Thu, 14 Nov 2019 19:10:44 +0000
Subject: Invalidate the rails cache for project meta xml in show_project_meta
The project model code path for this invalidates the cache before
returning.
Users now have different views of project meta config (references to
inaccessible projects, which were not permitted at all before, are now
elided to "HIDDEN" for users with insufficient access): This means
that the code path which provides the meta config to osc must also
invalidate the cache.
It's not clear that this particular config should be cached at all.
Possibly it should include the user context in the cache key instead
but in any case this is the least invasive way to make sure osc
returns the correct information for now.
---
src/api/app/controllers/source_controller.rb | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/api/app/controllers/source_controller.rb b/src/api/app/controllers/source_controller.rb
index 2a2150b..e26a615 100644
--- a/src/api/app/controllers/source_controller.rb
+++ b/src/api/app/controllers/source_controller.rb
@@ -432,6 +432,13 @@ class SourceController < ApplicationController
else
# access check
prj = Project.get_by_name params[:project]
+ # since users may now see different versions of the
+ # project XML depending on their access permissions
+ # to linked projects, and the cache is global, we must
+ # invalidate the cache before reconstructing the xml.
+ if prj.id
+ Rails.cache.delete("xml_project_#{prj.id}")
+ end
render xml: prj.to_axml
end
end
From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= <vivek@collabora.com>
Date: Tue, 5 Nov 2019 17:57:50 +0000
Subject: Suppress a 500 error in the web-UI for project meta config
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
When a user tries to view a project's meta config, the rails
application actually recreates the XML from the database contents
using the project model.
It does this with the user id set in its context and applies normal
ACL rules.
This means that any data relating to a project the user does not have
at least read access to is missing from the model's internal data
structures, so <path…> elements that refer to unreadable projects
result in a method call on nil and a 500 error in the web UI.
This patch ameliorates that by checking that the relevant object
actually exists in the model before calling an accessor method on it,
and substituting 'HIDDEN' for the project's name if it does not.
This does mean that the user SHOULD NOT try and save said meta config
but that restriction is not enforced here.
---
src/api/app/views/models/_project.xml.builder | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/api/app/views/models/_project.xml.builder b/src/api/app/views/models/_project.xml.builder
index 530c7de..5ceae74 100644
--- a/src/api/app/views/models/_project.xml.builder
+++ b/src/api/app/views/models/_project.xml.builder
@@ -62,10 +62,13 @@ xml.project(project_attributes) do
repo.path_elements.includes(:link).each do |pe|
if pe.link.remote_project_name
project_name = pe.link.project.name+":"+pe.link.remote_project_name
- else
+ xml_repository.path(:project => project_name, :repository => pe.link.name)
+ elsif pe.link.project
project_name = pe.link.project.name
+ xml_repository.path(:project => project_name, :repository => pe.link.name)
+ else
+ xml_repository.path(:project => "HIDDEN", :repository => pe.link.name)
end
- xml_repository.path(:project => project_name, :repository => pe.link.name)
end
repo.repository_architectures.joins(:architecture).pluck("architectures.name").each do |arch|
xml_repository.arch arch
From: =?utf-8?q?Vivek_Das=C2=A0Mohapatra?= <vivek@collabora.com>
Date: Tue, 5 Nov 2019 18:52:48 +0000
Subject: Use the allowbuilddep in meta config to whitelist project access
Allow projects mentioned as <allowbuilddep name="accessing-project"/>
entries in the meta config of another project to fetch build
dependencies from that project unconditionally.
---
src/api/app/models/project.rb | 3 ++-
src/backend/BSSched/Access.pm | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/api/app/models/project.rb b/src/api/app/models/project.rb
index 9e5f5d7..f51a256 100644
--- a/src/api/app/models/project.rb
+++ b/src/api/app/models/project.rb
@@ -1729,7 +1729,8 @@ class Project < ActiveRecord::Base
target_project = Project.get_by_name(target_project_name)
# user can access tprj, but backend would refuse to take binaries from there
if target_project.class == Project && target_project.disabled_for?('access', nil, nil)
- return { error: "The current backend implementation is not using binaries from read access protected projects #{target_project_name}"}
+ # RBEI modification to ACL logic: upstream returns an { error: "… read access protected …" } here.
+ logger.info "Project #{project_name} depends on restricted project #{target_project_name}"
end
end
logger.debug "Project #{project_name} repository path checked against #{target_project_name} projects permission"
diff --git a/src/backend/BSSched/Access.pm b/src/backend/BSSched/Access.pm
index d4133b3..dc5ffaa 100644
--- a/src/backend/BSSched/Access.pm
+++ b/src/backend/BSSched/Access.pm
@@ -42,6 +42,19 @@ sub checkaccess {
return $access;
}
+sub checkbuilddepok {
+ my ($gctx, $projid, $aprojid) = @_;
+
+ my $adata = $gctx->{projpacks}->{$aprojid} || {};
+ my $allow = $adata->{allowbuilddep} || [];
+
+ foreach my $a ( grep { ref($_) eq 'HASH' } @$allow ) {
+ if( $a->{name} eq $projid ) { return 1; }
+ }
+
+ return 0;
+}
+
# check if every user from oprojid may access projid
sub checkroles {
my ($gctx, $type, $projid, $packid, $oprojid, $opackid) = @_;
@@ -101,6 +114,13 @@ sub checkprpaccess {
# ok if aprp is not protected
return 1 if checkaccess($gctx, 'access', $aprojid, undef, $arepoid);
my ($projid, $repoid) = split('/', $prp, 2);
+
+ #################################################################
+ # this is an RBEI modification
+ # ok if prp has access to aprp (via allowbuilddep in project meta):
+ return 1 if checkbuilddepok($gctx, $projid, $aprojid);
+ #################################################################
+
# not ok if prp is unprotected
return 0 if checkaccess($gctx, 'access', $projid, undef, $repoid);
# both prp and aprp are proteced.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment