...
 
Commits (5)
  • Vivek Das Mohapatra's avatar
    Suppress a 500 error in the web-UI for project meta config · e220e271
    Vivek Das Mohapatra authored
    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.
    e220e271
  • Vivek Das Mohapatra's avatar
    Add a new none-or-some element <allowbuilddep> to project meta config · 309e5a9e
    Vivek Das Mohapatra authored
    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
    309e5a9e
  • Vivek Das Mohapatra's avatar
    Use the allowbuilddep in meta config to whitelist project access · 7bb95b09
    Vivek Das Mohapatra authored
    Allow projects mentioned as <allowbuilddep name="accessing-project"/>
    entries in the meta config of another project to fetch build
    dependencies from that project unconditionally.
    7bb95b09
  • Vivek Das Mohapatra's avatar
    Invalidate the rails cache for project meta xml in show_project_meta · 4a9a792c
    Vivek Das Mohapatra authored
    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.
    4a9a792c
  • Andrew Lee's avatar
    Merge branch 'acl-hacks' into 'collabora/master' · 2d3e28c3
    Andrew Lee authored
    Acl hacks
    
    See merge request !15
    2d3e28c3
......@@ -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">
......
......@@ -95,6 +95,10 @@
</element>
</optional>
<zeroOrMore>
<ref name="allowbuilddep-element"/>
</zeroOrMore>
<zeroOrMore>
<ref name="person-element"/>
</zeroOrMore>
......
......@@ -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
......
class Allowbuilddep < ActiveRecord::Base
belongs_to :project, foreign_key: :db_project_id, inverse_of: :allowbuilddeps
end
......@@ -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
......@@ -1719,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"
......
......@@ -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)
......@@ -62,10 +67,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
......
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
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');
......
......@@ -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.
......
......@@ -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' =>
......
......@@ -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'}) {
......