Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
b959ae55
Commit
b959ae55
authored
Mar 18, 2016
by
Zeger-Jan van de Weg
Committed by
Felipe Artur
Mar 18, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve group visibility level feature
parent
0a7f7161
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
118 additions
and
115 deletions
+118
-115
app/controllers/groups/application_controller.rb
app/controllers/groups/application_controller.rb
+1
-1
app/controllers/groups_controller.rb
app/controllers/groups_controller.rb
+0
-11
app/helpers/visibility_level_helper.rb
app/helpers/visibility_level_helper.rb
+1
-2
app/models/ability.rb
app/models/ability.rb
+1
-1
app/models/group.rb
app/models/group.rb
+22
-0
app/models/project.rb
app/models/project.rb
+16
-4
app/services/groups/base_service.rb
app/services/groups/base_service.rb
+5
-10
app/services/groups/create_service.rb
app/services/groups/create_service.rb
+5
-3
app/services/groups/update_service.rb
app/services/groups/update_service.rb
+6
-11
app/services/projects/create_service.rb
app/services/projects/create_service.rb
+3
-10
app/views/groups/show.html.haml
app/views/groups/show.html.haml
+1
-2
lib/api/entities.rb
lib/api/entities.rb
+1
-1
lib/gitlab/visibility_level.rb
lib/gitlab/visibility_level.rb
+2
-2
spec/factories/groups.rb
spec/factories/groups.rb
+12
-0
spec/finders/groups_finder_spec.rb
spec/finders/groups_finder_spec.rb
+7
-6
spec/finders/personal_projects_finder_spec.rb
spec/finders/personal_projects_finder_spec.rb
+6
-13
spec/helpers/visibility_level_helper_spec.rb
spec/helpers/visibility_level_helper_spec.rb
+2
-7
spec/models/group_spec.rb
spec/models/group_spec.rb
+5
-5
spec/models/project_spec.rb
spec/models/project_spec.rb
+2
-6
spec/services/groups/create_service_spec.rb
spec/services/groups/create_service_spec.rb
+2
-2
spec/services/groups/update_service_spec.rb
spec/services/groups/update_service_spec.rb
+18
-18
No files found.
app/controllers/groups/application_controller.rb
View file @
b959ae55
...
...
@@ -9,7 +9,7 @@ class Groups::ApplicationController < ApplicationController
end
def
authorize_read_group!
unless
@group
and
can?
(
current_user
,
:read_group
,
@group
)
unless
@group
&&
can?
(
current_user
,
:read_group
,
@group
)
if
current_user
.
nil?
return
authenticate_user!
else
...
...
app/controllers/groups_controller.rb
View file @
b959ae55
...
...
@@ -105,17 +105,6 @@ class GroupsController < Groups::ApplicationController
@projects
||=
ProjectsFinder
.
new
.
execute
(
current_user
,
group:
group
).
sorted_by_activity
end
# Dont allow unauthorized access to group
def
authorize_read_group!
unless
can?
(
current_user
,
:read_group
,
@group
)
if
current_user
.
nil?
return
authenticate_user!
else
return
render_404
end
end
end
def
authorize_create_group!
unless
can?
(
current_user
,
:create_group
,
nil
)
return
render_404
...
...
app/helpers/visibility_level_helper.rb
View file @
b959ae55
...
...
@@ -85,7 +85,6 @@ module VisibilityLevelHelper
end
def
skip_level?
(
form_model
,
level
)
form_model
.
is_a?
(
Project
)
&&
!
form_model
.
visibility_level_allowed?
(
level
)
form_model
.
is_a?
(
Project
)
&&
!
form_model
.
visibility_level_allowed?
(
level
)
end
end
app/models/ability.rb
View file @
b959ae55
...
...
@@ -295,7 +295,7 @@ class Ability
end
def
can_read_group?
(
user
,
group
)
user
.
admin?
||
group
.
public?
||
(
group
.
internal?
&&
!
user
.
external?
)
||
group
.
users
.
include?
(
user
)
||
user
.
admin?
||
group
.
public?
||
(
group
.
internal?
&&
!
user
.
external?
)
||
group
.
users
.
include?
(
user
)
||
ProjectsFinder
.
new
.
execute
(
user
,
group:
group
).
any?
end
...
...
app/models/group.rb
View file @
b959ae55
...
...
@@ -29,6 +29,8 @@ class Group < Namespace
has_many
:shared_projects
,
through: :project_group_links
,
source: :project
validate
:avatar_type
,
if:
->
(
user
)
{
user
.
avatar
.
present?
&&
user
.
avatar_changed?
}
validate
:visibility_level_allowed_by_projects
validates
:avatar
,
file_size:
{
maximum:
200
.
kilobytes
.
to_i
}
mount_uploader
:avatar
,
AvatarUploader
...
...
@@ -80,6 +82,26 @@ class Group < Namespace
visibility_level
end
def
visibility_level_allowed_by_projects
unless
visibility_level_allowed?
level_name
=
Gitlab
::
VisibilityLevel
.
level_name
(
visibility_level
).
downcase
self
.
errors
.
add
(
:visibility_level
,
"
#{
level_name
}
is not allowed since there are projects with higher visibility."
)
end
end
def
visibility_level_allowed?
projects_visibility
=
self
.
projects
.
pluck
(
:visibility_level
)
allowed_by_projects
=
projects_visibility
.
none?
{
|
project_visibility
|
self
.
visibility_level
<
project_visibility
}
unless
allowed_by_projects
level_name
=
Gitlab
::
VisibilityLevel
.
level_name
(
visibility_level
).
downcase
self
.
errors
.
add
(
:visibility_level
,
"
#{
level_name
}
is not allowed since there are projects with higher visibility."
)
end
allowed_by_projects
end
def
avatar_url
(
size
=
nil
)
if
avatar
.
present?
[
gitlab_config
.
url
,
avatar
.
url
].
join
...
...
app/models/project.rb
View file @
b959ae55
...
...
@@ -73,7 +73,7 @@ class Project < ActiveRecord::Base
update_column
(
:last_activity_at
,
self
.
created_at
)
end
# update visibility_leve
t
of forks
# update visibility_leve
l
of forks
after_update
:update_forks_visibility_level
def
update_forks_visibility_level
return
unless
visibility_level
<
visibility_level_was
...
...
@@ -197,6 +197,7 @@ class Project < ActiveRecord::Base
validate
:avatar_type
,
if:
->
(
project
)
{
project
.
avatar
.
present?
&&
project
.
avatar_changed?
}
validates
:avatar
,
file_size:
{
maximum:
200
.
kilobytes
.
to_i
}
validate
:visibility_level_allowed_in_group
add_authentication_token_field
:runners_token
before_save
:ensure_runners_token
...
...
@@ -446,6 +447,12 @@ class Project < ActiveRecord::Base
errors
[
:base
]
<<
(
"Can't check your ability to create project"
)
end
def
visibility_level_allowed_in_group
unless
visibility_level_allowed?
self
.
errors
.
add
(
:visibility_level
,
"
#{
self
.
visibility_level
}
is not allowed in a
#{
self
.
group
.
visibility_level
}
group."
)
end
end
def
to_param
path
end
...
...
@@ -961,9 +968,14 @@ class Project < ActiveRecord::Base
issues
.
opened
.
count
end
def
visibility_level_allowed?
(
level
)
allowed_by_forks
=
forked?
?
Gitlab
::
VisibilityLevel
.
allowed_fork_levels
(
forked_from_project
.
visibility_level
).
include?
(
level
.
to_i
)
:
true
allowed_by_groups
=
group
.
present?
?
level
.
to_i
<=
group
.
visibility_level
:
true
def
visibility_level_allowed?
(
level
=
self
.
visibility_level
)
allowed_by_forks
=
if
forked?
Gitlab
::
VisibilityLevel
.
allowed_fork_levels
(
forked_from_project
.
visibility_level
).
include?
(
level
)
else
true
end
allowed_by_groups
=
group
.
present?
?
level
<=
group
.
visibility_level
:
true
allowed_by_forks
&&
allowed_by_groups
end
...
...
app/services/groups/base_service.rb
View file @
b959ae55
...
...
@@ -8,18 +8,13 @@ module Groups
private
def
visibility_allowed_for_user?
(
level
)
def
visibility_allowed_for_user?
level
=
group
.
visibility_level
allowed_by_user
=
Gitlab
::
VisibilityLevel
.
allowed_for?
(
current_user
,
level
)
@group
.
errors
.
add
(
:visibility_level
,
"You are not authorized to set this permission level."
)
unless
allowed_by_user
allowed_by_user
end
def
visibility_allowed_for_project?
(
level
)
projects_visibility
=
group
.
projects
.
pluck
(
:visibility_level
)
allowed_by_projects
=
!
projects_visibility
.
any?
{
|
project_visibility
|
level
.
to_i
<
project_visibility
}
@group
.
errors
.
add
(
:visibility_level
,
"Cannot be changed. There are projects with higher visibility permissions."
)
unless
allowed_by_projects
allowed_by_projects
group
.
errors
.
add
(
:visibility_level
,
"
#{
level
}
has been restricted by your GitLab administrator."
)
unless
allowed_by_user
allowed_by_user
end
end
end
app/services/groups/create_service.rb
View file @
b959ae55
...
...
@@ -2,14 +2,16 @@ module Groups
class
CreateService
<
Groups
::
BaseService
def
initialize
(
user
,
params
=
{})
@current_user
,
@params
=
user
,
params
.
dup
@group
=
Group
.
new
(
@params
)
end
def
execute
return
@group
unless
visibility_allowed_for_user?
(
@params
[
:visibility_level
])
@group
=
Group
.
new
(
params
)
return
@group
unless
visibility_allowed_for_user?
@group
.
name
=
@group
.
path
.
dup
unless
@group
.
name
@group
.
save
@group
.
add_owner
(
@
current_user
)
@group
.
add_owner
(
current_user
)
@group
end
end
...
...
app/services/groups/update_service.rb
View file @
b959ae55
#Checks visibility level permission check before updating a group
#Do not allow to put Group visibility level smaller than its projects
#Do not allow unauthorized permission levels
#
Checks visibility level permission check before updating a group
#
Do not allow to put Group visibility level smaller than its projects
#
Do not allow unauthorized permission levels
module
Groups
class
UpdateService
<
Groups
::
BaseService
def
execute
return
false
unless
visibility_level_allowed?
(
params
[
:visibility_level
])
group
.
update_attributes
(
params
)
end
private
group
.
assign_attributes
(
params
)
def
visibility_level_allowed?
(
level
)
return
true
unless
level
.
present?
return
false
unless
visibility_allowed_for_user?
visibility_allowed_for_project?
(
level
)
&&
visibility_allowed_for_user?
(
level
)
group
.
save
end
end
end
app/services/projects/create_service.rb
View file @
b959ae55
...
...
@@ -9,13 +9,8 @@ module Projects
@project
=
Project
.
new
(
params
)
# Make sure that the user is allowed to use the specified visibility
# level
unless
visibility_level_allowed?
deny_visibility_level
(
@project
)
return
@project
end
# Make sure that the user is allowed to use the specified visibility level
return
@project
unless
visibility_level_allowed?
# Set project name from path
if
@project
.
name
.
present?
&&
@project
.
path
.
present?
...
...
@@ -55,9 +50,7 @@ module Projects
@project
.
save
if
@project
.
persisted?
&&
!
@project
.
import?
unless
@project
.
create_repository
raise
'Failed to create repository'
end
raise
'Failed to create repository'
unless
@project
.
create_repository
end
end
...
...
app/views/groups/show.html.haml
View file @
b959ae55
...
...
@@ -17,8 +17,7 @@
.cover-title
%h1
=
@group
.
name
%span
.visibility-icon.has_tooltip
{
data:
{
container:
'body'
,
placement:
'left'
},
title:
"#{group_visibility_description(@group)}"
}
%span
.visibility-icon.has_tooltip
{
data:
{
container:
'body'
,
placement:
'left'
},
title:
group_visibility_description
(
@group
)
}
=
visibility_level_icon
(
@group
.
visibility_level
,
fw:
false
)
.cover-desc.username
...
...
lib/api/entities.rb
View file @
b959ae55
...
...
@@ -85,7 +85,7 @@ module API
end
class
Group
<
Grape
::
Entity
expose
:id
,
:name
,
:path
,
:description
expose
:id
,
:name
,
:path
,
:description
,
:visibility_level
expose
:avatar_url
expose
:web_url
do
|
group
,
options
|
...
...
lib/gitlab/visibility_level.rb
View file @
b959ae55
...
...
@@ -9,8 +9,8 @@ module Gitlab
extend
ActiveSupport
::
Concern
included
do
scope
:public_only
,
->
{
where
(
visibility_level:
PUBLIC
)
}
scope
:public_and_internal_only
,
->
{
where
(
visibility_level:
[
PUBLIC
,
INTERNAL
]
)
}
scope
:public_only
,
->
{
where
(
visibility_level:
PUBLIC
)
}
scope
:public_and_internal_only
,
->
{
where
(
visibility_level:
[
PUBLIC
,
INTERNAL
]
)
}
end
PRIVATE
=
0
unless
const_defined?
(
:PRIVATE
)
...
...
spec/factories/groups.rb
View file @
b959ae55
...
...
@@ -3,5 +3,17 @@ FactoryGirl.define do
sequence
(
:name
)
{
|
n
|
"group
#{
n
}
"
}
path
{
name
.
downcase
.
gsub
(
/\s/
,
'_'
)
}
type
'Group'
trait
:public
do
visibility_level
Gitlab
::
VisibilityLevel
::
PUBLIC
end
trait
:internal
do
visibility_level
Gitlab
::
VisibilityLevel
::
INTERNAL
end
trait
:private
do
visibility_level
Gitlab
::
VisibilityLevel
::
PRIVATE
end
end
end
spec/finders/groups_finder_spec.rb
View file @
b959ae55
...
...
@@ -2,11 +2,11 @@ require 'spec_helper'
describe
GroupsFinder
do
describe
'#execute'
do
let
(
:user
)
{
create
(
:user
)
}
let!
(
:private_group
)
{
create
(
:group
,
visibility_level:
0
)
}
let!
(
:internal_group
)
{
create
(
:group
,
visibility_level:
10
)
}
let!
(
:public_group
)
{
create
(
:group
,
visibility_level:
20
)
}
let
(
:finder
)
{
described_class
.
new
}
let
(
:user
)
{
create
(
:user
)
}
let!
(
:private_group
)
{
create
(
:group
,
:private
)
}
let!
(
:internal_group
)
{
create
(
:group
,
:internal
)
}
let!
(
:public_group
)
{
create
(
:group
,
:public
)
}
let
(
:finder
)
{
described_class
.
new
}
describe
'execute'
do
describe
'without a user'
do
...
...
@@ -23,7 +23,8 @@ describe GroupsFinder do
end
context
'external user'
do
before
{
user
.
update_attribute
(
external:
true
)
}
let
(
:user
)
{
create
(
:user
,
external:
true
)
}
it
{
is_expected
.
to
eq
([
public_group
])
}
end
end
...
...
spec/finders/personal_projects_finder_spec.rb
View file @
b959ae55
require
'spec_helper'
describe
PersonalProjectsFinder
do
let
(
:source_user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:finder
)
{
described_class
.
new
(
source_user
)
}
let!
(
:public_project
)
do
create
(
:project
,
:public
,
namespace:
source_user
.
namespace
,
name:
'A'
,
path:
'A'
)
end
let
(
:source_user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:finder
)
{
described_class
.
new
(
source_user
)
}
let!
(
:public_project
)
{
create
(
:project
,
:public
,
namespace:
source_user
.
namespace
)
}
let!
(
:private_project
)
do
create
(
:project
,
:private
,
namespace:
source_user
.
namespace
,
name:
'B'
,
path:
'B'
)
create
(
:project
,
:private
,
namespace:
source_user
.
namespace
,
path:
'mepmep'
)
end
let!
(
:internal_project
)
do
create
(
:project
,
:internal
,
namespace:
source_user
.
namespace
,
name:
'c'
,
path:
'C'
)
create
(
:project
,
:internal
,
namespace:
source_user
.
namespace
,
path:
'C'
)
end
before
do
...
...
spec/helpers/visibility_level_helper_spec.rb
View file @
b959ae55
...
...
@@ -66,13 +66,8 @@ describe VisibilityLevelHelper do
describe
"skip_level?"
do
describe
"forks"
do
let
(
:project
)
{
create
(
:project
,
:internal
)
}
let
(
:fork_project
)
{
create
(
:forked_project_with_submodules
)
}
before
do
fork_project
.
build_forked_project_link
(
forked_to_project_id:
fork_project
.
id
,
forked_from_project_id:
project
.
id
)
fork_project
.
save
end
let
(
:project
)
{
create
(
:project
,
:internal
)
}
let
(
:fork_project
)
{
create
(
:project
,
forked_from_project:
project
)
}
it
"skips levels"
do
expect
(
skip_level?
(
fork_project
,
Gitlab
::
VisibilityLevel
::
PUBLIC
)).
to
be_truthy
...
...
spec/models/group_spec.rb
View file @
b959ae55
...
...
@@ -57,18 +57,18 @@ describe Group, models: true do
end
describe
'scopes'
do
let!
(
:private_group
)
{
create
(
:group
,
visibility_level:
0
)
}
let!
(
:internal_group
)
{
create
(
:group
,
visibility_level:
10
)
}
let!
(
:public_group
)
{
create
(
:group
,
visibility_level:
20
)
}
let!
(
:private_group
)
{
create
(
:group
,
:private
)
}
let!
(
:internal_group
)
{
create
(
:group
,
:internal
)
}
let!
(
:public_group
)
{
create
(
:group
,
:public
)
}
describe
'public_only'
do
subject
{
described_class
.
public_only
}
subject
{
described_class
.
public_only
.
to_a
}
it
{
is_expected
.
to
eq
([
public_group
])
}
end
describe
'public_and_internal_only'
do
subject
{
described_class
.
public_and_internal_only
}
subject
{
described_class
.
public_and_internal_only
.
to_a
}
it
{
is_expected
.
to
eq
([
public_group
,
internal_group
])
}
end
...
...
spec/models/project_spec.rb
View file @
b959ae55
...
...
@@ -571,12 +571,8 @@ describe Project, models: true do
end
context
'when checking on forked project'
do
let
(
:forked_project
)
{
create
:forked_project_with_submodules
}
before
do
forked_project
.
build_forked_project_link
(
forked_to_project_id:
forked_project
.
id
,
forked_from_project_id:
project
.
id
)
forked_project
.
save
end
let
(
:project
)
{
create
(
:project
,
:internal
)
}
let
(
:forked_project
)
{
create
(
:project
,
forked_from_project:
project
)
}
it
{
expect
(
forked_project
.
visibility_level_allowed?
(
Gitlab
::
VisibilityLevel
::
PRIVATE
)).
to
be_truthy
}
it
{
expect
(
forked_project
.
visibility_level_allowed?
(
Gitlab
::
VisibilityLevel
::
INTERNAL
)).
to
be_truthy
}
...
...
spec/services/groups/create_service_spec.rb
View file @
b959ae55
require
'spec_helper'
describe
Groups
::
CreateService
,
services:
true
do
let!
(
:user
)
{
create
(
:user
)
}
let!
(
:group_params
)
{
{
path:
"group_path"
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
}
}
let!
(
:user
)
{
create
(
:user
)
}
let!
(
:group_params
)
{
{
path:
"group_path"
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
}
}
describe
"execute"
do
let!
(
:service
)
{
described_class
.
new
(
user
,
group_params
)
}
...
...
spec/services/groups/update_service_spec.rb
View file @
b959ae55
require
'spec_helper'
describe
Groups
::
UpdateService
,
services:
true
do
let!
(
:user
)
{
create
(
:user
)
}
let!
(
:private_group
)
{
create
(
:group
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
let!
(
:internal_group
)
{
create
(
:group
,
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
}
let!
(
:public_group
)
{
create
(
:group
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
}
let!
(
:user
)
{
create
(
:user
)
}
let!
(
:private_group
)
{
create
(
:group
,
:private
)
}
let!
(
:internal_group
)
{
create
(
:group
,
:internal
)
}
let!
(
:public_group
)
{
create
(
:group
,
:public
)
}
describe
"execute"
do
context
"project visibility_level validation"
do
...
...
@@ -14,28 +14,28 @@ describe Groups::UpdateService, services: true do
before
do
public_group
.
add_user
(
user
,
Gitlab
::
Access
::
MASTER
)
create
(
:project
,
:public
,
group:
public_group
,
name:
'B'
,
path:
'B'
)
create
(
:project
,
:public
,
group:
public_group
)
end
it
"cant downgrade permission level"
do
expect
(
service
.
execute
).
to
be_falsy
expect
(
public_group
.
errors
.
count
).
to
eq
(
1
)
expect
(
public_group
.
errors
.
count
).
to
eq
(
2
)
end
end
context
"internal group with internal project"
do
let!
(
:service
)
{
described_class
.
new
(
internal_group
,
user
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
before
do
internal_group
.
add_user
(
user
,
Gitlab
::
Access
::
MASTER
)
create
(
:project
,
:internal
,
group:
internal_group
,
name:
'B'
,
path:
'B'
)
context
"internal group with internal project"
do
let!
(
:service
)
{
described_class
.
new
(
internal_group
,
user
,
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
}
before
do
internal_group
.
add_user
(
user
,
Gitlab
::
Access
::
MASTER
)
create
(
:project
,
:internal
,
group:
internal_group
)
end
it
"cant downgrade permission level"
do
expect
(
service
.
execute
).
to
be_falsy
expect
(
internal_group
.
errors
.
count
).
to
eq
(
2
)
end
end
it
"cant downgrade permission level"
do
expect
(
service
.
execute
).
to
be_falsy
expect
(
internal_group
.
errors
.
count
).
to
eq
(
1
)
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment