Merge pull request #450 from abf/rosa-build:446-change_alias_abilities
#446 Only admin can share a project
This commit is contained in:
commit
481662b9f9
|
@ -0,0 +1,12 @@
|
||||||
|
table.table.blame
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
padding-top: 0
|
||||||
|
padding-bottom: 0
|
||||||
|
|
||||||
|
pre
|
||||||
|
margin-bottom: 0
|
||||||
|
border: 0
|
||||||
|
.highlight
|
||||||
|
pre
|
||||||
|
background: none
|
|
@ -114,11 +114,10 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
redirect_to @project.owner
|
redirect_to @project.owner
|
||||||
end
|
end
|
||||||
|
|
||||||
def fork
|
def fork(is_alias = false)
|
||||||
owner = (Group.find params[:group] if params[:group].present?) || current_user
|
owner = (Group.find params[:group] if params[:group].present?) || current_user
|
||||||
authorize! :write, owner if owner.class == Group
|
authorize! :write, owner if owner.class == Group
|
||||||
|
|
||||||
is_alias = params[:alias] == 'true'
|
|
||||||
if forked = @project.fork(owner, new_name: params[:fork_name], is_alias: is_alias) and forked.valid?
|
if forked = @project.fork(owner, new_name: params[:fork_name], is_alias: is_alias) and forked.valid?
|
||||||
redirect_to forked, notice: t("flash.project.forked")
|
redirect_to forked, notice: t("flash.project.forked")
|
||||||
else
|
else
|
||||||
|
@ -128,6 +127,10 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def alias
|
||||||
|
fork(true)
|
||||||
|
end
|
||||||
|
|
||||||
def possible_forks
|
def possible_forks
|
||||||
render partial: 'projects/git/base/forks', layout: false,
|
render partial: 'projects/git/base/forks', layout: false,
|
||||||
locals: { owner: current_user, name: (params[:name].presence || @project.name) }
|
locals: { owner: current_user, name: (params[:name].presence || @project.name) }
|
||||||
|
|
|
@ -72,8 +72,10 @@ class Ability
|
||||||
can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_member, :remove_members, :update_member, :members, :schedule], Project do |project|
|
can [:update, :sections, :manage_collaborators, :autocomplete_maintainers, :add_member, :remove_member, :remove_members, :update_member, :members, :schedule], Project do |project|
|
||||||
local_admin? project
|
local_admin? project
|
||||||
end
|
end
|
||||||
|
|
||||||
can(:fork, Project) {|project| can? :read, project}
|
can(:fork, Project) {|project| can? :read, project}
|
||||||
can(:fork, Project) {|project| project.owner_type == 'Group' and can? :update, project.owner}
|
can(:alias, Project) {|project| local_admin?(project) }
|
||||||
|
|
||||||
can(:destroy, Project) {|project| owner? project}
|
can(:destroy, Project) {|project| owner? project}
|
||||||
can(:destroy, Project) {|project| project.owner_type == 'Group' and project.owner.actors.exists?(actor_type: 'User', actor_id: user.id, role: 'admin')}
|
can(:destroy, Project) {|project| project.owner_type == 'Group' and project.owner.actors.exists?(actor_type: 'User', actor_id: user.id, role: 'admin')}
|
||||||
can :remove_user, Project
|
can :remove_user, Project
|
||||||
|
|
|
@ -9,14 +9,18 @@
|
||||||
= form_for @project, url: fork_project_path(@project), html: { class: :form, multipart: true, method: :post } do |f|
|
= form_for @project, url: fork_project_path(@project), html: { class: :form, multipart: true, method: :post } do |f|
|
||||||
= hidden_field_tag :group, owner.id if owner.class == Group
|
= hidden_field_tag :group, owner.id if owner.class == Group
|
||||||
= hidden_field_tag :fork_name, name, name: 'fork_name'
|
= hidden_field_tag :fork_name, name, name: 'fork_name'
|
||||||
= hidden_field_tag :alias, '{{create_alias}}'
|
.btn-group.btn-group-justified
|
||||||
.btn-group.btn-group-justified ng-init='create_alias = false'
|
|
||||||
.btn-group
|
.btn-group
|
||||||
= f.submit t('layout.projects.fork_to', to: full_name),
|
= f.submit t('layout.projects.fork_to', to: full_name),
|
||||||
class: 'btn btn-primary center-block',
|
class: 'btn btn-primary center-block',
|
||||||
'data-loading-text' => t('layout.processing'), id: 'create_fork'
|
'data-loading-text' => t('layout.processing'), id: 'create_fork'
|
||||||
.btn-group
|
|
||||||
= f.submit t('layout.projects.create_alias_for', for: full_name),
|
- if can? :alias, @project
|
||||||
class: 'btn btn-primary center-block',
|
= form_for @project, url: alias_project_path(@project), html: { class: :form, multipart: true, method: :post } do |f|
|
||||||
ng_click: 'create_alias = true',
|
= hidden_field_tag :group, owner.id if owner.class == Group
|
||||||
'data-loading-text' => t('layout.processing'), id: 'create_fork'
|
= hidden_field_tag :fork_name, name, name: 'fork_name'
|
||||||
|
.btn-group.btn-group-justified.offset5
|
||||||
|
.btn-group
|
||||||
|
= f.submit t('layout.projects.create_alias_for', for: full_name),
|
||||||
|
class: 'btn btn-primary center-block',
|
||||||
|
'data-loading-text' => t('layout.processing'), id: 'create_fork'
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
h3= t("layout.projects.files_in_project")
|
||||||
|
.files
|
||||||
|
.pull-left== render 'whereami'
|
||||||
|
.pull-right== render 'fork'
|
||||||
|
.clearfix
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-heading== render 'top'
|
||||||
|
|
||||||
|
#output.formatted== render 'blame_table' if @blame.first.first.present?
|
|
@ -15,7 +15,7 @@
|
||||||
%span.message{title: elem[0].message}= short_message(elem[0].message)
|
%span.message{title: elem[0].message}= short_message(elem[0].message)
|
||||||
|
|
||||||
%td.lines
|
%td.lines
|
||||||
= index
|
%pre= index
|
||||||
- index += 1
|
- index += 1
|
||||||
|
|
||||||
%td.code.formatted
|
%td.code.formatted
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
- elem[1][1..-1].each do |line|
|
- elem[1][1..-1].each do |line|
|
||||||
%tr
|
%tr
|
||||||
%td.lines
|
%td.lines
|
||||||
= index
|
%pre= index
|
||||||
- index += 1
|
- index += 1
|
||||||
%td.code.formatted
|
%td.code.formatted
|
||||||
= preserve do
|
= preserve do
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
= javascript_include_tag 'codemirror_editor'
|
|
||||||
= stylesheet_link_tag 'codemirror_editor'
|
|
||||||
|
|
||||||
%h3= t("layout.projects.files_in_project")
|
|
||||||
.files
|
|
||||||
.l= render 'whereami'
|
|
||||||
= render 'fork'
|
|
||||||
.both
|
|
||||||
|
|
||||||
= form_tag edit_blob_path(@project, @treeish, @path), name: 'blob-editor', method: :put do
|
|
||||||
.file-editor= text_area_tag :content, @blob.data, id: 'code'
|
|
||||||
|
|
||||||
.both
|
|
||||||
= t("layout.enter_commit_message")
|
|
||||||
= text_area_tag :message, "Updated #{@blob.name}", class: 'commit-message'
|
|
||||||
|
|
||||||
%br
|
|
||||||
%br
|
|
||||||
= submit_tag t('layout.save'), title: t('layout.save'), data: {'disable-with' => t('layout.saving')}
|
|
||||||
= t("layout.or")
|
|
||||||
= link_to t("layout.cancel"), blob_path(@project, @treeish, @path), class: 'button'
|
|
||||||
|
|
||||||
:javascript
|
|
||||||
$(function() {
|
|
||||||
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
|
|
||||||
lineNumbers: true,
|
|
||||||
mode: '#{@blob.raw_mime_type}'
|
|
||||||
});
|
|
||||||
$(".CodeMirror").resizable({
|
|
||||||
stop: function() { editor.refresh(); },
|
|
||||||
resize: function() {
|
|
||||||
$(".CodeMirror-scroll").height($(this).height());
|
|
||||||
$(".CodeMirror-scroll").width($(this).width());
|
|
||||||
editor.refresh();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
= javascript_include_tag 'codemirror_editor'
|
||||||
|
= stylesheet_link_tag 'codemirror_editor'
|
||||||
|
|
||||||
|
h3= t("layout.projects.files_in_project")
|
||||||
|
.files
|
||||||
|
.pull-left= render 'whereami'
|
||||||
|
.pull-right= render 'fork'
|
||||||
|
.clearfix
|
||||||
|
|
||||||
|
= form_tag edit_blob_path(@project, @treeish, @path), name: 'blob-editor', method: :put do
|
||||||
|
.form-group
|
||||||
|
.file-editor= text_area_tag :content, @blob.data, id: 'code'
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
label[ for = :message ]= t("layout.enter_commit_message")
|
||||||
|
= text_area_tag :message, "Updated #{@blob.name}", class: 'form-control'
|
||||||
|
|
||||||
|
=> submit_tag t('layout.save'), title: t('layout.save'),
|
||||||
|
data: {'disable-with' => t('layout.saving')},
|
||||||
|
class: 'btn btn-primary'
|
||||||
|
=> t("layout.or")
|
||||||
|
= link_to t("layout.cancel"), blob_path(@project, @treeish, @path), class: 'btn btn-default'
|
||||||
|
|
||||||
|
- content_for :additional_scripts do
|
||||||
|
javascript:
|
||||||
|
$(function() {
|
||||||
|
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: '#{@blob.raw_mime_type}'
|
||||||
|
});
|
||||||
|
$(".CodeMirror").resizable({
|
||||||
|
stop: function() { editor.refresh(); },
|
||||||
|
resize: function() {
|
||||||
|
$(".CodeMirror-scroll").height($(this).height());
|
||||||
|
$(".CodeMirror-scroll").width($(this).width());
|
||||||
|
editor.refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,9 +0,0 @@
|
||||||
%h3= t("layout.projects.files_in_project")
|
|
||||||
.files
|
|
||||||
.pull-left= render 'whereami'
|
|
||||||
.pull-right= render 'fork'
|
|
||||||
.clearfix
|
|
||||||
.panel.panel-default
|
|
||||||
.panel-heading= render 'top'
|
|
||||||
|
|
||||||
= render "render_as_#{@blob.render_as}"
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
h3= t("layout.projects.files_in_project")
|
||||||
|
.files
|
||||||
|
.pull-left== render 'whereami'
|
||||||
|
.pull-right== render 'fork'
|
||||||
|
.clearfix
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-heading== render 'top'
|
||||||
|
|
||||||
|
== render "render_as_#{@blob.render_as}"
|
|
@ -1,8 +0,0 @@
|
||||||
%ol.breadcrumb
|
|
||||||
%li= link_to @project.name, tree_path(@project, treeish: @treeish)
|
|
||||||
- if @path.present?
|
|
||||||
- paths = File.split(@path)
|
|
||||||
- if paths.size > 1 and paths.first != '.'
|
|
||||||
- iterate_path(paths.first).each do |el|
|
|
||||||
%li= link_to(el.last, tree_path(@project, "#{@treeish}/#{el.first}"))
|
|
||||||
%li.active= paths.last
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
ol.breadcrumb
|
||||||
|
li= link_to @project.name, tree_path(@project, treeish: @treeish)
|
||||||
|
- if @path.present?
|
||||||
|
- paths = File.split(@path)
|
||||||
|
- if paths.size > 1 and paths.first != '.'
|
||||||
|
- iterate_path(paths.first).each do |el|
|
||||||
|
li= link_to(el.last, tree_path(@project, "#{@treeish}/#{el.first}"))
|
||||||
|
li.active= paths.last
|
|
@ -1,21 +0,0 @@
|
||||||
-set_meta_tags title: "#{title_object @project} #{t('at') if @branch} #{@branch.try :name}"
|
|
||||||
= render 'submenu'
|
|
||||||
= render 'repo_block', project: @project
|
|
||||||
= render 'about_block', project: @project
|
|
||||||
|
|
||||||
|
|
||||||
%h3= t("layout.projects.last_commit")
|
|
||||||
- GitPresenters::CommitAsMessagePresenter.present(@commit, project: @project) do |presenter|
|
|
||||||
= render 'shared/feed_message', presenter: presenter, item_no: 1
|
|
||||||
|
|
||||||
.both
|
|
||||||
|
|
||||||
#repo-wrapper
|
|
||||||
%h3= t("layout.projects.files_in_project")
|
|
||||||
.files
|
|
||||||
.l= render 'whereami'
|
|
||||||
.both
|
|
||||||
|
|
||||||
.file
|
|
||||||
.top= render 'top'
|
|
||||||
.blame_data= render 'blame_table' if @blame.first.first.present?
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-set_meta_tags title: "#{title_object @project} #{t('at') if @branch} #{@branch.try :name}"
|
||||||
|
== render partial: "blame", layout: 'layout'
|
|
@ -1,2 +1,2 @@
|
||||||
-set_meta_tags title: [title_object(@project), "#{t :title_editing} #{@project.name}/#{@path} #{t('at') if @branch} #{@branch.try :name}"]
|
-set_meta_tags title: [title_object(@project), "#{t :title_editing} #{@project.name}/#{@path} #{t('at') if @branch} #{@branch.try :name}"]
|
||||||
= render partial: "editor", layout: 'layout'
|
== render partial: "editor", layout: 'layout'
|
|
@ -1,2 +1,2 @@
|
||||||
-set_meta_tags title: [title_object(@project), "#{@project.name}/#{@path} #{t('at') if @branch} #{@branch.try :name}"]
|
-set_meta_tags title: [title_object(@project), "#{@project.name}/#{@path} #{t('at') if @branch} #{@branch.try :name}"]
|
||||||
= render partial: "show", layout: 'layout'
|
== render partial: "show", layout: 'layout'
|
|
@ -4,6 +4,7 @@
|
||||||
.files
|
.files
|
||||||
.pull-left= render 'whereami'
|
.pull-left= render 'whereami'
|
||||||
.pull-right= render 'fork'
|
.pull-right= render 'fork'
|
||||||
|
.clearfix
|
||||||
%table.table.table-hover
|
%table.table.table-hover
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
-set_meta_tags title: "#{title_object @project} #{t('at') if @branch} #{@branch.try :name}"
|
-set_meta_tags title: "#{title_object @project} #{t('at') if @branch} #{@branch.try :name}"
|
||||||
= render partial: "show", layout: 'layout'
|
== render partial: "show", layout: 'layout'
|
|
@ -355,7 +355,8 @@ Rosa::Application.routes.draw do
|
||||||
patch '/' => 'projects#update'
|
patch '/' => 'projects#update'
|
||||||
delete '/' => 'projects#destroy'
|
delete '/' => 'projects#destroy'
|
||||||
# Member
|
# Member
|
||||||
post '/fork' => 'projects#fork', as: :fork_project
|
post '/fork' => 'projects#fork', as: :fork_project
|
||||||
|
post '/alias' => 'projects#alias', as: :alias_project
|
||||||
get '/possible_forks' => 'projects#possible_forks', as: :possible_forks_project
|
get '/possible_forks' => 'projects#possible_forks', as: :possible_forks_project
|
||||||
get '/sections' => 'projects#sections', as: :sections_project
|
get '/sections' => 'projects#sections', as: :sections_project
|
||||||
patch '/sections' => 'projects#sections'
|
patch '/sections' => 'projects#sections'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
ARCHES = %w(i386 i586 x86_64)
|
ARCHES = %w(i386 i586 x86_64)
|
||||||
ARCHES.each do |arch|
|
ARCHES.each do |arch|
|
||||||
Arch.find_or_create_by_name arch
|
Arch.find_or_create_by(name: arch)
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(rosa_system iso_worker_1 file_store).each do |uname|
|
%w(rosa_system iso_worker_1 file_store).each do |uname|
|
||||||
|
|
|
@ -35,6 +35,16 @@ shared_examples_for 'projects user with project admin rights' do
|
||||||
put :schedule, { name_with_owner: @project.name_with_owner }.merge(repository_id: @project.repositories.first.id)
|
put :schedule, { name_with_owner: @project.name_with_owner }.merge(repository_id: @project.repositories.first.id)
|
||||||
response.should be_success
|
response.should be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should be able to create alias for a project' do
|
||||||
|
post :alias, name_with_owner: @project.name_with_owner, fork_name: (@project.name + '_new')
|
||||||
|
response.should redirect_to(project_path(Project.last))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create alias for a project' do
|
||||||
|
lambda { post :alias, name_with_owner: @project.name_with_owner,
|
||||||
|
fork_name: (@project.name + '_new') }.should change{ Project.count }.by(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples_for 'user with destroy rights' do
|
shared_examples_for 'user with destroy rights' do
|
||||||
|
@ -94,6 +104,16 @@ shared_examples_for 'projects user without project admin rights' do
|
||||||
create_actor_relation(group, @user, 'reader')
|
create_actor_relation(group, @user, 'reader')
|
||||||
lambda {post :create, @create_params.merge(who_owns: 'group', owner_id: group.id)}.should change{ Project.count }.by(0)
|
lambda {post :create, @create_params.merge(who_owns: 'group', owner_id: group.id)}.should change{ Project.count }.by(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not be able to create alias for a project' do
|
||||||
|
post :alias, name_with_owner: @project.name_with_owner
|
||||||
|
response.should redirect_to(forbidden_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not create alias for a project' do
|
||||||
|
lambda { post :alias, name_with_owner: @project.name_with_owner,
|
||||||
|
fork_name: (@project.name + '_new') }.should change{ Project.count }.by(0)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Projects::ProjectsController do
|
describe Projects::ProjectsController do
|
||||||
|
|
Loading…
Reference in New Issue