Skip to content

Commit

Permalink
merged from AccessControl branch: bulk patch for AccessControl
Browse files Browse the repository at this point in the history
      added: privacy enforcement for package on flags privacy, readaccess and binarydownload
      added: new flag definitions
      fixed: acl DB migration class fixed, moved to newest migration
      fixed: missing places for new readaccess / privacy flags
      adding support for role="reader" with the new flags <readaccess> and <privacy>
  • Loading branch information
mmohring authored and Jan-Simon Möller committed May 11, 2010
1 parent c0c8f3c commit 1b7dbb2
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 18 deletions.
2 changes: 2 additions & 0 deletions docs/api/api/package.xsd
Expand Up @@ -152,6 +152,8 @@
<xs:element name="useforbuild" type="enable_list_type" minOccurs="0" />
<xs:element name="debuginfo" type="enable_list_type" minOccurs="0" />
<xs:element name="binarydownload" type="enable_list_type" minOccurs="0" />
<xs:element name="readaccess" type="enable_list_type" minOccurs="0" />
<xs:element name="privacy" type="enable_list_type" minOccurs="0" />
</xs:choice>
</xs:group>

Expand Down
2 changes: 2 additions & 0 deletions docs/api/api/project.xsd
Expand Up @@ -110,6 +110,8 @@
<xs:element name="useforbuild" type="enable_list_type" minOccurs="0" />
<xs:element name="debuginfo" type="enable_list_type" minOccurs="0" />
<xs:element name="binarydownload" type="enable_list_type" minOccurs="0" />
<xs:element name="readaccess" type="enable_list_type" minOccurs="0" />
<xs:element name="privacy" type="enable_list_type" minOccurs="0" />
</xs:choice>
</xs:group>

Expand Down
30 changes: 30 additions & 0 deletions src/api/app/controllers/build_controller.rb
Expand Up @@ -158,4 +158,34 @@ def file
forward_data path
end
end

def logfile
valid_http_methods :get
pkg = DbPackage.find_by_project_and_name params[:project], params[:package]
#logfile controled by binarydownload_flags and download_binary permission
if pkg and pkg.binarydownload_flags.disabled_for?(params[:repository], params[:arch]) and not @http_user.can_download_binaries?(pkg)
render_error :status => 403, :errorcode => "download_binary_no_permission",
:message => "No permission to download logfile for package #{params[:package]}, project #{params[:project]}"
return
end
forward_data
end

def result
valid_http_methods :get
prj = DbProject.find_by_name params[:project]
pkg = prj.find_package params[:package]
if prj and prj.privacy_flags.enabled_for?(params[:repository], params[:arch]) and not @http_user.can_private_view?(prj)
# render_error :status => 403, :errorcode => "private_view_no_permission",
# :message => "No permission to view project #{params[:project]}"
render_ok
return
end
if pkg and pkg.privacy_flags.enabled_for?(params[:repository], params[:arch]) and not @http_user.can_private_view?(pkg)
render_ok
return
end
forward_data
end

end
54 changes: 45 additions & 9 deletions src/api/app/controllers/source_controller.rb
Expand Up @@ -30,9 +30,12 @@ def index_project
end

if request.get?
@dir = Package.find :all, :project => project_name
render :text => @dir.dump_xml, :content_type => "text/xml"
return
if @http_user.can_private_view?(pro) or pro.privacy_flags.disabled_for?(params[:repository], params[:arch])
@dir = Package.find :all, :project => project_name
render :text => @dir.dump_xml, :content_type => "text/xml"
return
end
render_ok
elsif request.delete?
unless @http_user.can_modify_project?(pro)
logger.debug "No permission to delete project #{project_name}"
Expand Down Expand Up @@ -125,7 +128,26 @@ def index_package
package_name = params[:package]
cmd = params[:cmd]

pkg = DbPackage.find_by_project_and_name(project_name, package_name)
prj = DbProject.find_by_name(project_name)
unless prj
render_error :status => 404, :errorcode => "unknown_project",
:message => "unknown project '#{project_name}'"
return
end
pkg = prj.find_package(package_name)
if pkg and pkg.privacy_flags.enabled_for?(params[:repository], params[:arch]) and not @http_user.can_private_view?(pkg)
# render_error :status => 403, :errorcode => "private_view_no_permission",
# :message => "No permission to view package #{params[:package]}, project #{params[:project]}"
render_ok
return
end

# look also via linked projects, package source may come from another project
begin
rescue DbProject::CycleError => e
render_error :status => 400, :errorcode => 'project_cycle', :message => e.message
return
end
unless pkg or DbProject.find_remote_project(project_name)
render_error :status => 404, :errorcode => "unknown_package",
:message => "unknown package '#{package_name}' in project '#{project_name}'"
Expand Down Expand Up @@ -626,9 +648,27 @@ def file
project_name = params[:project]
package_name = params[:package]
file = params[:file]

path = "/source/#{project_name}/#{package_name}/#{file}"

return unless extract_user
params[:user] = @http_user.login

pack = DbPackage.find_by_project_and_name(project_name, package_name)
if pack.nil?
render_error :status => 403, :errorcode => 'not_found',
:message => "The given package #{package_name} does not exist in project #{project_name}"
return
end

if pack.readaccess_flags.disabled_for?(:nil, :nil)
# check reader role
unless @http_user.can_read_access?(pack)
render_error :status => 403, :errorcode => "read_access_no_permission",
:message => "user #{params[:user]} has no read access to package #{package_name}, project #{project_name}"
return
end
end

if request.get?
#get file size
fpath = "/source/#{project_name}/#{package_name}" + build_query_from_hash(params, [:rev])
Expand Down Expand Up @@ -663,10 +703,6 @@ def file
return
end

#authenticate
return unless extract_user

params[:user] = @http_user.login
if request.put?
path += build_query_from_hash(params, [:user, :comment, :rev, :linkrev, :keeplink])

Expand Down
8 changes: 5 additions & 3 deletions src/api/app/models/db_package.rb
Expand Up @@ -21,6 +21,8 @@ class CycleError < Exception; end
has_many :debuginfo_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :useforbuild_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :binarydownload_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :readaccess_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :privacy_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy

belongs_to :develpackage, :class_name => "DbPackage", :foreign_key => 'develpackage_id'
has_many :develpackages, :class_name => "DbPackage", :foreign_key => 'develpackage_id'
Expand Down Expand Up @@ -307,7 +309,7 @@ def store_axml( package )

#---begin enable / disable flags ---#
flag_compatibility_check( :package => package )
%w(build publish debuginfo useforbuild binarydownload).each do |flagtype|
%w(build publish debuginfo useforbuild binarydownload readaccess privacy).each do |flagtype|
update_flags( :package => package, :flagtype => flagtype )
end

Expand Down Expand Up @@ -617,7 +619,7 @@ def render_axml
package.group( :groupid => g.title, :role => g.role_name )
end

%w(build publish debuginfo useforbuild binarydownload).each do |flag_name|
%w(build publish debuginfo useforbuild binarydownload readaccess privacy readaccess privacy).each do |flag_name|
flaglist = __send__(flag_name+"_flags")
unless flaglist.empty?
package.__send__(flag_name) do
Expand Down Expand Up @@ -691,7 +693,7 @@ def update_flags( opts={} )
flag = nil

#translates the flag types as used in the xml to model name + s
if %w(build publish debuginfo useforbuild binarydownload).include? opts[:flagtype].to_s
if %w(build publish debuginfo useforbuild binarydownload readaccess privacy).include? opts[:flagtype].to_s
flagtype = opts[:flagtype].to_s + "_flags"
else
raise SaveError.new( "Error: unknown flag type '#{opts[:flagtype]}' not found." )
Expand Down
8 changes: 5 additions & 3 deletions src/api/app/models/db_project.rb
Expand Up @@ -25,6 +25,8 @@ class SaveError < Exception; end
has_many :debuginfo_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :useforbuild_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :binarydownload_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :readaccess_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy
has_many :privacy_flags, :order => :position, :extend => FlagExtension, :dependent => :destroy


def download_name
Expand Down Expand Up @@ -218,7 +220,7 @@ def store_axml( project, force=nil )
# and recreate the flag groups and flags again
flag_compatibility_check( :project => project )

%w(build publish debuginfo useforbuild binarydownload).each do |flagtype|
%w(build publish debuginfo useforbuild binarydownload readaccess privacy).each do |flagtype|
update_flags( :project => project, :flagtype => flagtype )
end

Expand Down Expand Up @@ -605,7 +607,7 @@ def render_axml
:mtype => dl.mtype, :arch => dl.architecture.name )
end

%w(build publish debuginfo useforbuild binarydownload).each do |flag_name|
%w(build publish debuginfo useforbuild binarydownload readaccess privacy).each do |flag_name|
flaglist = __send__(flag_name+"_flags")
unless flaglist.empty?
project.__send__(flag_name) do
Expand Down Expand Up @@ -694,7 +696,7 @@ def update_flags( opts={} )
flag = nil

#translate the flag types as used in the xml to model name + s
if %w(build publish debuginfo useforbuild binarydownload).include? opts[:flagtype].to_s
if %w(build publish debuginfo useforbuild binarydownload readaccess privacy).include? opts[:flagtype].to_s
flagtype = opts[:flagtype].to_s + "_flags"
else
raise SaveError.new( "Error: unknown flag type '#{opts[:flagtype]}' not found." )
Expand Down
2 changes: 1 addition & 1 deletion src/api/app/models/package.rb
Expand Up @@ -55,7 +55,7 @@ def set_devel( opt={} )
end

def remove_all_flags
%w(build publish debuginfo useforbuild).each do |flag|
%w(build publish debuginfo useforbuild readaccess privacy).each do |flag|
send('each_' + flag) do |e|
delete_element e
end
Expand Down
7 changes: 7 additions & 0 deletions src/api/app/models/privacy_flag.rb
@@ -0,0 +1,7 @@
class PrivacyFlag < Flag
belongs_to :db_project
belongs_to :db_package
belongs_to :architecture

default_state :disabled
end
7 changes: 7 additions & 0 deletions src/api/app/models/readaccess_flag.rb
@@ -0,0 +1,7 @@
class ReadaccessFlag < Flag
belongs_to :db_project
belongs_to :db_package
belongs_to :architecture

default_state :enabled
end
19 changes: 19 additions & 0 deletions src/api/app/models/user.rb
Expand Up @@ -253,6 +253,25 @@ def can_download_binaries?(package)
return false
end

def can_read_access?(package)
return true if has_global_permission? "read_access"

unless package.kind_of? DbPackage
raise ArgumentError, "illegal argument to can_read_access, DbPackage expected, got #{package.class.name}"
end

return true if has_local_permission?("read_access", package)
return false
end

def can_private_view?(parm)
return true if has_global_permission? "private_view"

return true if has_local_permission?("private_view", parm)

return false
end

# add deprecation warning to has_permission method
alias_method :has_global_permission?, :has_permission?
def has_permission?(*args)
Expand Down
4 changes: 2 additions & 2 deletions src/api/config/routes.rb
Expand Up @@ -209,7 +209,7 @@
map.connect 'build/:project/:repository/:arch/:package/_status',
:controller => "build", :action => "pass_to_source", :project => /[^\/]*/, :repository => /[^\/]*/, :package => /[^\/]*/
map.connect 'build/:project/:repository/:arch/:package/_log',
:controller => "build", :action => "pass_to_source", :project => /[^\/]*/, :repository => /[^\/]*/, :package => /[^\/]*/
:controller => "build", :action => "logfile", :project => /[^\/]*/, :repository => /[^\/]*/, :package => /[^\/]*/
map.connect 'build/:project/:repository/:arch/:package/_buildinfo',
:controller => "build", :action => "buildinfo", :project => /[^\/]*/, :repository => /[^\/]*/, :package => /[^\/]*/
map.connect 'build/:project/:repository/:arch/:package/_history',
Expand All @@ -225,7 +225,7 @@
map.connect 'build/:project/:repository/:arch',
:controller => "build", :action => "pass_to_source", :project => /[^\/]*/, :repository => /[^\/]*/
map.connect 'build/:project/_result',
:controller => "build", :action => "pass_to_source", :project => /[^\/]*/
:controller => "build", :action => "result", :project => /[^\/]*/
map.connect 'build/:project/:repository',
:controller => "build", :action => "pass_to_source", :project => /[^\/]*/, :repository => /[^\/]*/
# the web client does no longer use that route, but we keep it for backward compat
Expand Down
9 changes: 9 additions & 0 deletions src/api/db/migrate/20100302100000_add_reviewer_role.rb
@@ -0,0 +1,9 @@
class AddReviewerRole < ActiveRecord::Migration
def self.up
reviewer = Role.create :title => 'reviewer'
end

def self.down
Role.find_by_title('reviewer').destroy
end
end
24 changes: 24 additions & 0 deletions src/api/db/migrate/20100328100000_add_new_permissions_and_role.rb
@@ -0,0 +1,24 @@
class AddNewPermissionsAndRole < ActiveRecord::Migration
def self.up
readperm = StaticPermission.create :title => 'read_access'
privperm = StaticPermission.create :title => 'private_view'
reader = Role.create :title => 'reader'
maintainer = Role.find_by_title 'maintainer'

[maintainer,reader].each do |role|
role.static_permissions << readperm
end
maintainer.static_permissions << privperm
end

def self.down
perm = StaticPermission.find_by_title('read_access')
if perm
perm.destroy
end
perm = StaticPermission.find_by_title('private_view')
if perm
perm.destroy
end
end
end
2 changes: 2 additions & 0 deletions src/backend/BSXML.pm
Expand Up @@ -71,6 +71,8 @@ our @flags = (
[ 'debuginfo' => @disableenable ],
[ 'useforbuild' => @disableenable ],
[ 'binarydownload' => @disableenable ],
[ 'readaccess' => @disableenable ],
[ 'privacy' => @disableenable ],
);

our $download = [
Expand Down

0 comments on commit 1b7dbb2

Please sign in to comment.