diff --git a/app/assets/stylesheets/design/build_lists_monitoring.scss b/app/assets/stylesheets/design/build_lists_monitoring.scss index 4b1192ff0..6ff2fa878 100644 --- a/app/assets/stylesheets/design/build_lists_monitoring.scss +++ b/app/assets/stylesheets/design/build_lists_monitoring.scss @@ -120,9 +120,7 @@ article .all .top form .floatright a img { padding: 4px 12px; margin-bottom: 0; line-height: 20px; - color: #333333; text-align: center; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; cursor: pointer; background-color: #f5f5f5; @@ -148,7 +146,6 @@ article .all .top form .floatright a img { /* bootstrap 3190*/ .btn:hover, .btn:active, .btn.active, .btn.disabled, .btn[disabled] { - color: #333333; background-color: #e6e6e6; } diff --git a/app/controllers/api/v1/projects_controller.rb b/app/controllers/api/v1/projects_controller.rb index 927a35bed..01e891cca 100644 --- a/app/controllers/api/v1/projects_controller.rb +++ b/app/controllers/api/v1/projects_controller.rb @@ -42,7 +42,7 @@ class Api::V1::ProjectsController < Api::V1::BaseController else @project.owner = nil end - authorize! :update, @project.owner if @project.owner != current_user + authorize! :write, @project.owner if @project.owner != current_user create_subject @project end @@ -63,8 +63,8 @@ class Api::V1::ProjectsController < Api::V1::BaseController end def fork - owner = (Group.find params[:group_id] if params[:group].present?) || current_user - authorize! :update, owner if owner.class == Group + owner = (Group.find params[:group_id] if params[:group_id].present?) || current_user + authorize! :write, owner if owner.class == Group if forked = @project.fork(owner) and forked.valid? render_json_response forked, 'Project has been forked successfully' else diff --git a/app/controllers/projects/projects_controller.rb b/app/controllers/projects/projects_controller.rb index 23ff01ec9..5119b5def 100644 --- a/app/controllers/projects/projects_controller.rb +++ b/app/controllers/projects/projects_controller.rb @@ -34,7 +34,7 @@ class Projects::ProjectsController < Projects::BaseController @project = Project.new params[:project] @project.owner = choose_owner @who_owns = (@project.owner_type == 'User' ? :me : :group) - authorize! :update, @project.owner if @project.owner.class == Group + authorize! :write, @project.owner if @project.owner.class == Group if @project.save flash[:notice] = t('flash.project.saved') @@ -67,7 +67,7 @@ class Projects::ProjectsController < Projects::BaseController def fork owner = (Group.find params[:group] if params[:group].present?) || current_user - authorize! :update, owner if owner.class == Group + authorize! :write, owner if owner.class == Group if forked = @project.fork(owner) and forked.valid? redirect_to forked, :notice => t("flash.project.forked") else diff --git a/app/helpers/build_lists_helper.rb b/app/helpers/build_lists_helper.rb index b6a27cbb1..0601636ae 100644 --- a/app/helpers/build_lists_helper.rb +++ b/app/helpers/build_lists_helper.rb @@ -77,12 +77,10 @@ module BuildListsHelper end end - def container_url(full_path = true, build_list = @build_list) - p = '' - p << "http://#{request.host_with_port}" if full_path - p << "/downloads/#{build_list.save_to_platform.name}/container/#{build_list.id}" - p << "/#{build_list.arch.name}/#{build_list.save_to_repository.name}/release" if full_path && build_list.build_for_platform.distrib_type == 'mdv' - p.html_safe + def container_url(build_list = @build_list) + url = "#{APP_CONFIG['downloads_url']}/#{build_list.save_to_platform.name}/container/#{build_list.id}" + url << "/#{build_list.arch.name}/#{build_list.save_to_repository.name}/release" if build_list.build_for_platform.distrib_type == 'mdv' + url.html_safe end def can_publish_in_future?(bl) diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb index 62e0ff19d..6cfaf5244 100644 --- a/app/helpers/git_helper.rb +++ b/app/helpers/git_helper.rb @@ -74,12 +74,12 @@ module GitHelper if params[:treeish].present? && !project.repo.branches_and_tags.map(&:name).include?(params[:treeish]) res << [I18n.t('layout.git.repositories.commits'), [params[:treeish].truncate(20)]] end - linking = Proc.new {|t| [t.name.truncate(20), url_for(p.merge :treeish => t.name).split('?', 2).first]} - res << [I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&linking)] + linking = Proc.new {|name| [name.truncate(20), url_for(p.merge :treeish => name).split('?', 2).first]} + res << [I18n.t('layout.git.repositories.branches'), project.repo.branches.map(&:name).sort.map(&linking)] if tag_enabled - res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&linking)] + res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&:name).sort.map(&linking)] else - res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map {|t| [t.name.truncate(20), {:disabled => true}]}] + res << [I18n.t('layout.git.repositories.tags'), project.repo.tags.map(&:name).sort.map {|name| [name.truncate(20), {:disabled => true}]}] end grouped_options_for_select(res, current) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 845d834f8..e7e535d0d 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -53,6 +53,9 @@ class Ability can [:update, :manage_members, :members, :add_member, :remove_member, :update_member], Group do |group| group.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => 'admin') # or group.owner_id = user.id end + can :write, Group do |group| + group.actors.exists?(:actor_type => 'User', :actor_id => user.id, :role => ['writer', 'admin']) + end can :destroy, Group, :owner_id => user.id can :remove_user, Group diff --git a/app/models/build_list.rb b/app/models/build_list.rb index 0abd4e7fb..132050a34 100644 --- a/app/models/build_list.rb +++ b/app/models/build_list.rb @@ -406,16 +406,13 @@ class BuildList < ActiveRecord::Base end def abf_worker_args - # TODO: remove when this will be not necessary - # "rosa2012.1/main" repository should be used in "conectiva" platform repos = include_repos - repos |= ['146'] if build_for_platform_id == 376 include_repos_hash = {}.tap do |h| Repository.where(:id => (repos | (extra_repositories || [])) ).each do |repo| - path = repo.platform.public_downloads_url(nil, arch.name, repo.name) + path = repo.platform.public_downloads_url(arch.name, repo.name) # path.gsub!(/^http:\/\/(0\.0\.0\.0|localhost)\:[\d]+/, 'https://abf.rosalinux.ru') unless Rails.env.production? # Path looks like: - # http://abf.rosalinux.ru/downloads/rosa-server2012/repository/x86_64/base/ + # http://abf-downloads.rosalinux.ru/rosa-server2012/repository/x86_64/base/ # so, we should append: # - release # - updates @@ -425,7 +422,7 @@ class BuildList < ActiveRecord::Base end host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host] BuildList.where(:id => extra_build_lists).each do |bl| - path = "http://#{host}/downloads/#{bl.save_to_platform.name}/container/" + path = "#{APP_CONFIG['downloads_url']}/#{bl.save_to_platform.name}/container/" path << "#{bl.id}/#{bl.arch.name}/#{bl.save_to_repository.name}/release" include_repos_hash["container_#{bl.id}"] = path end diff --git a/app/models/comment.rb b/app/models/comment.rb index 88913e613..36ba75e71 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -22,9 +22,7 @@ class Comment < ActiveRecord::Base attr_accessible :body, :data def commentable - # raise commentable_id.inspect - # raise commentable_id.to_s(16).inspect - commit_comment? ? project.repo.commit(commentable_id.to_s(16)) : super # TODO leading zero problem + commit_comment? ? project.repo.commit(Comment.hex_to_commit_hash commentable_id) : super end def commentable=(c) @@ -185,6 +183,12 @@ class Comment < ActiveRecord::Base end end + def self.hex_to_commit_hash hex + # '079d'.hex.to_s(16) => "79d" + t = hex.to_s(16) + '0'*(40-t.length) << t # commit hash has 40-character + end + protected def subscribe_on_reply diff --git a/app/models/group.rb b/app/models/group.rb index 6eb0ce1c4..497b9b3cd 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -19,6 +19,7 @@ class Group < Avatar scope :opened, where('1=1') scope :by_owner, lambda {|owner| where(:owner_id => owner.id)} scope :by_admin, lambda {|admin| joins(:actors).where(:'relations.role' => 'admin', :'relations.actor_id' => admin.id, :'relations.actor_type' => 'User')} + scope :by_admin_and_writer, lambda {|actor| joins(:actors).where(:'relations.role' => ['admin', 'writer'], :'relations.actor_id' => actor.id, :'relations.actor_type' => 'User')} attr_accessible :uname, :description attr_readonly :uname @@ -32,7 +33,7 @@ class Group < Avatar # include Modules::Models::Owner def self.can_own_project(user) - (by_owner(user) | by_admin(user)) + (by_owner(user) | by_admin_and_writer(user)) end def name diff --git a/app/models/platform.rb b/app/models/platform.rb index 7c4d425be..f642fd1e6 100644 --- a/app/models/platform.rb +++ b/app/models/platform.rb @@ -1,6 +1,6 @@ # -*- encoding : utf-8 -*- class Platform < ActiveRecord::Base - VISIBILITIES = ['open', 'hidden'] + VISIBILITIES = ['open']#, 'hidden'] # Disable support hidden platforms. belongs_to :parent, :class_name => 'Platform', :foreign_key => 'parent_platform_id' belongs_to :owner, :polymorphic => true @@ -57,20 +57,17 @@ class Platform < ActiveRecord::Base def urpmi_list(host = nil, pair = nil, add_commands = true, repository_name = 'main') host ||= default_host - blank_pair = {:login => 'login', :pass => 'password'} - pair = blank_pair if pair.blank? urpmi_commands = ActiveSupport::OrderedHash.new # TODO: rename method or create separate methods for mdv and rhel # Platform.main.opened.where(:distrib_type => APP_CONFIG['distr_types'].first).each do |pl| Platform.main.opened.each do |pl| urpmi_commands[pl.name] = {} - local_pair = pl.id != self.id ? blank_pair : pair - head = hidden? ? "http://#{local_pair[:login]}@#{local_pair[:pass]}:#{host}/private/" : "http://#{host}/downloads/" + # FIXME should support restricting access to the hidden platform Arch.all.each do |arch| tail = "/#{arch.name}/#{repository_name}/release" command = add_commands ? "urpmi.addmedia #{name} " : '' - command << "#{head}#{name}/repository/#{pl.name}#{tail}" + command << "#{APP_CONFIG['downloads_url']}/#{name}/repository/#{pl.name}#{tail}" urpmi_commands[pl.name][arch.name] = command end end @@ -94,21 +91,8 @@ class Platform < ActiveRecord::Base Rails.root.join("public", "downloads", name) end - def prefix_url(pub, options = {}) - options[:host] ||= default_host - pub ? "http://#{options[:host]}/downloads" : "http://#{options[:login]}:#{options[:password]}@#{options[:host]}/private" - end - - def public_downloads_url(host = nil, arch = nil, repo = nil, suffix = nil) - downloads_url prefix_url(true, :host => host), arch, repo, suffix - end - - def private_downloads_url(login, password, host = nil, arch = nil, repo = nil, suffix = nil) - downloads_url prefix_url(false, :host => host, :login => login, :password => password), arch, repo, suffix - end - - def downloads_url(prefix, arch = nil, repo = nil, suffix = nil) - "#{prefix}/#{name}/repository/".tap do |url| + def public_downloads_url(arch = nil, repo = nil, suffix = nil) + "#{APP_CONFIG['downloads_url']}/#{name}/repository/".tap do |url| url << "#{arch}/" if arch.present? url << "#{repo}/" if repo.present? url << "#{suffix}/" if suffix.present? diff --git a/app/models/product_build_list.rb b/app/models/product_build_list.rb index cb595b664..08cc79bb7 100644 --- a/app/models/product_build_list.rb +++ b/app/models/product_build_list.rb @@ -119,10 +119,6 @@ class ProductBuildList < ActiveRecord::Base [BUILD_STARTED, BUILD_PENDING].include? status end - def container_path - "/downloads/#{product.platform.name}/product/#{id}/" - end - def event_log_message {:product => product.name}.inspect end diff --git a/app/models/repository.rb b/app/models/repository.rb index 5a7968cab..f3cbb71c5 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -67,6 +67,7 @@ class Repository < ActiveRecord::Base protected def detele_directory + return unless platform repository_path = platform.path << '/repository' if platform.personal? Platform.main.pluck(:name).each do |main_platform_name| diff --git a/app/presenters/git_presenters/commit_as_message_presenter.rb b/app/presenters/git_presenters/commit_as_message_presenter.rb index a982e46c8..b44f31478 100644 --- a/app/presenters/git_presenters/commit_as_message_presenter.rb +++ b/app/presenters/git_presenters/commit_as_message_presenter.rb @@ -14,7 +14,7 @@ class GitPresenters::CommitAsMessagePresenter < ApplicationPresenter else opts[:project] end - commit = commit || @project.repo.commit(comment.created_from_commit_hash.to_s(16)) if @project + commit = commit || @project.repo.commit(Comment.hex_to_commit_hash comment.created_from_commit_hash) if @project if @project && commit @committer = User.where(:email => commit.committer.email).first || commit.committer @@ -23,7 +23,7 @@ class GitPresenters::CommitAsMessagePresenter < ApplicationPresenter @commit_message = commit.message else @committer = t('layout.commits.unknown_committer') - @commit_hash = comment.created_from_commit_hash.to_s(16) + @commit_hash = Comment.hex_to_commit_hash comment.created_from_commit_hash @committed_date = @authored_date = comment.created_at @commit_message = t('layout.commits.deleted') end diff --git a/app/views/api/v1/build_lists/show.json.jbuilder b/app/views/api/v1/build_lists/show.json.jbuilder index a108c7f76..61a08bd0c 100644 --- a/app/views/api/v1/build_lists/show.json.jbuilder +++ b/app/views/api/v1/build_lists/show.json.jbuilder @@ -6,7 +6,7 @@ json.build_list do |json| json.build_log_url log_build_list_path(@build_list) if @build_list.container_published? - json.container_path container_url(false) + json.container_path container_url else json.container_path '' end @@ -65,7 +65,7 @@ json.build_list do |json| extra_build_lists = BuildList.where(:id => @build_list.extra_build_lists) json.extra_build_lists extra_build_lists do |json_extra_build_lists, bl| json_extra_build_lists.(bl, :id, :status) - json_extra_build_lists.container_path container_url(false, bl) + json_extra_build_lists.container_path container_url(bl) json_extra_build_lists.url api_v1_build_list_path(bl, :format => :json) end diff --git a/app/views/projects/build_lists/new.html.haml b/app/views/projects/build_lists/new.html.haml index 94b5aa3c3..d70375241 100644 --- a/app/views/projects/build_lists/new.html.haml +++ b/app/views/projects/build_lists/new.html.haml @@ -18,7 +18,7 @@ %h3= t("activerecord.attributes.build_list.arch") - Arch.recent.each do |arch| .both - = check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s) || controller.action_name == 'new', :id => "arches_#{arch.id}" + = check_box_tag "arches[]", arch.id, (params[:arches]||[]).include?(arch.id.to_s) || (controller.action_name == 'new' && %w(i586 x86_64).include?(arch.name)), :id => "arches_#{arch.id}" = label_tag "arches_#{arch.id}", arch.name %h3= t("activerecord.attributes.build_list.update_type") .lineForm= f.select :update_type, BuildList::UPDATE_TYPES diff --git a/app/views/projects/build_lists/show.html.haml b/app/views/projects/build_lists/show.html.haml index 94f8bcdcb..6f19555e1 100644 --- a/app/views/projects/build_lists/show.html.haml +++ b/app/views/projects/build_lists/show.html.haml @@ -8,12 +8,9 @@ %h3= t("layout.build_lists.main_data") .leftlist= t("activerecord.attributes.build_list.container_path") .rightlist - - if @build_list.build_published? - = raw "%s %s" % [t("layout.build_lists.container_published"), - link_to("#{@build_list.save_to_platform.name}/#{@build_list.save_to_repository.name}", - [@build_list.save_to_platform, @build_list.save_to_repository])] - if @build_list.container_published? - = link_to container_url, container_url + -url = container_url + = link_to url, url - elsif @build_list.container_publish? = t("layout.build_lists.creating") .both diff --git a/config/application.yml.sample b/config/application.yml.sample index 91347d7d9..c38ed919a 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -21,7 +21,7 @@ common: &common facebook: id: 'APP_ID' secret: 'APP_SECRET' - + downloads_url: 'http://abf-downloads.rosalinux.ru' wiki_formats: markdown: "Markdown" textile: "Textile" diff --git a/config/initializers/a_app_config.rb b/config/initializers/a_app_config.rb index 071ccb537..04cb06bb5 100644 --- a/config/initializers/a_app_config.rb +++ b/config/initializers/a_app_config.rb @@ -1,2 +1,4 @@ # -*- encoding : utf-8 -*- -APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env] \ No newline at end of file +APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env] +# Remove '/' from the end of url +APP_CONFIG.keys.select {|key| key =~ /_url\Z/}.each {|key| APP_CONFIG[key] = APP_CONFIG[key].chomp('/') if APP_CONFIG[key].respond_to?(:chomp)} diff --git a/lib/ext/rails/reserved_name_validator.rb b/lib/ext/rails/reserved_name_validator.rb index 408c8b05f..cfc1a1a5e 100644 --- a/lib/ext/rails/reserved_name_validator.rb +++ b/lib/ext/rails/reserved_name_validator.rb @@ -4,7 +4,7 @@ class ReservedNameValidator < ActiveModel::EachValidator app apps archive archives auth blog config connect contact create commit commits - dashboard delete direct_messages downloads + dashboard delete direct_messages download downloads edit email faq favorites feed feeds follow followers following help home @@ -20,7 +20,7 @@ class ReservedNameValidator < ActiveModel::EachValidator signup sign-up sign_up signin sign-in sign_in signout sign-out sign_out sitemap ssl subscribe teams terms test tour trends tree - unfollow unsubscribe url user + unfollow unsubscribe upload uploads url user widget widgets wiki xfn xmpp } diff --git a/spec/controllers/api/v1/projects_controller_spec.rb b/spec/controllers/api/v1/projects_controller_spec.rb index 012437bc1..b7991fab6 100644 --- a/spec/controllers/api/v1/projects_controller_spec.rb +++ b/spec/controllers/api/v1/projects_controller_spec.rb @@ -236,7 +236,6 @@ shared_examples_for 'api projects user without admin rights' do @project.members.should include(member) end end - end shared_examples_for 'api projects user with owner rights' do @@ -314,6 +313,18 @@ describe Api::V1::ProjectsController do it 'ensures that project has been created' do lambda { post :create, params, :format => :json }.should change{ Project.count }.by(1) end + + it 'writer group should be able to create project for their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer') + lambda { post :create, params.deep_merge({:project => {:owner_type => 'Group', :owner_id => group.id}})}.should change{ Project.count }.by(1) + end + + it 'reader group should not be able to create project for their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') + lambda { post :create, params.deep_merge({:project => {:owner_type => 'Group', :owner_id => group.id}})}.should change{ Project.count }.by(0) + end end it_should_behave_like 'api projects user with reader rights' @@ -322,6 +333,18 @@ describe Api::V1::ProjectsController do it_should_behave_like 'api projects user without fork rights for hidden project' it_should_behave_like 'api projects user without admin rights' it_should_behave_like 'api projects user without owner rights' + + it 'group writer should be able to fork project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer') + lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(1) + end + + it 'group reader should not be able to fork project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') + lambda {post :fork, :id => @project.id, :group_id => group.id}.should change{ Project.count }.by(0) + end end context 'for admin' do diff --git a/spec/controllers/projects/projects_controller_spec.rb b/spec/controllers/projects/projects_controller_spec.rb index f6ef63456..07b57bb46 100644 --- a/spec/controllers/projects/projects_controller_spec.rb +++ b/spec/controllers/projects/projects_controller_spec.rb @@ -61,6 +61,32 @@ shared_examples_for 'projects user without project admin rights' do @project.reload.has_issues.should == has_issues response.should redirect_to(forbidden_path) end + + it 'writer group should be able to fork project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer') + lambda {post :fork, :owner_name => @project.owner.uname, :project_name => @project.name, + :group => group.id}.should change{ Project.count }.by(1) + end + + it 'reader group should not be able to fork project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') + lambda {post :fork, :owner_name => @project.owner.uname, :project_name => @project.name, + :group => group.id}.should change{ Project.count }.by(0) + end + + it 'writer group should be able to create project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'writer') + lambda {post :create, @create_params.merge(:who_owns => 'group', :owner_id => group.id)}.should change{ Project.count }.by(1) + end + + it 'reader group should not be able to create project to their group' do + group = FactoryGirl.create(:group) + group.actors.create(:actor_type => 'User', :actor_id => @user.id, :role => 'reader') + lambda {post :create, @create_params.merge(:who_owns => 'group', :owner_id => group.id)}.should change{ Project.count }.by(0) + end end describe Projects::ProjectsController do @@ -77,7 +103,7 @@ describe Projects::ProjectsController do set_session_for(@user) end - context 'for system users' do + context 'for users' do context 'guest' do @@ -138,11 +164,10 @@ describe Projects::ProjectsController do group = FactoryGirl.create(:group, :owner => @user) lambda { post :create, @create_params.merge({:who_owns => 'group', :owner_id => group.id})}.should change{ Project.count }.by(1) end - end end # context 'registered user' - end # context 'for system users' + end # context 'for users' context 'for project members' do diff --git a/spec/models/cancan_spec.rb b/spec/models/cancan_spec.rb index 1a5053937..0a0230107 100644 --- a/spec/models/cancan_spec.rb +++ b/spec/models/cancan_spec.rb @@ -49,7 +49,6 @@ describe CanCan do end context 'Site guest' do - let(:hidden_platform) { FactoryGirl.create(:platform, :visibility => 'hidden') } let(:register_request) { FactoryGirl.create(:register_request) } before(:each) do @@ -60,10 +59,6 @@ describe CanCan do @ability.should_not be_able_to(:read, open_platform) end - it 'should not be able to read hidden platform' do - @ability.should_not be_able_to(:read, hidden_platform) - end - [:publish, :cancel, :reject_publish, :create_container].each do |action| it "should not be able to #{ action } build list" do @ability.should_not be_able_to(action, BuildList)