Commit 21af7459 authored by Douwe Maan's avatar Douwe Maan

Merge branch '4009-external-users' into 'master'

External Users

The user has the rights of a public user execpt it can never create a project, group, or team. Also it cant view internal projects.

Partially fix for both #4009 and #13938 (except the LDAP sync or a pattern to detect external users)


![Screen_Shot_2016-03-14_at_22.02.52](/uploads/486a84ab3acb98c6cfb71a4ec7d268e2/Screen_Shot_2016-03-14_at_22.02.52.png)

See merge request !3171
parents cf2e3ff6 956e9143
...@@ -42,6 +42,7 @@ v 8.6.0 (unreleased) ...@@ -42,6 +42,7 @@ v 8.6.0 (unreleased)
- Add main language of a project in the list of projects (Tiago Botelho) - Add main language of a project in the list of projects (Tiago Botelho)
- Add ability to show archived projects on dashboard, explore and group pages - Add ability to show archived projects on dashboard, explore and group pages
- Move group activity to separate page - Move group activity to separate page
- Create external users which are excluded of internal and private projects unless access was explicitly granted
- Continue parameters are checked to ensure redirection goes to the same instance - Continue parameters are checked to ensure redirection goes to the same instance
- User deletion is now done in the background so the request can not time out - User deletion is now done in the background so the request can not time out
......
...@@ -150,7 +150,7 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -150,7 +150,7 @@ class Admin::UsersController < Admin::ApplicationController
:email, :remember_me, :bio, :name, :username, :email, :remember_me, :bio, :name, :username,
:skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password,
:extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, :hide_no_password, :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, :hide_no_password,
:projects_limit, :can_create_group, :admin, :key_id :projects_limit, :can_create_group, :admin, :key_id, :external
) )
end end
......
...@@ -40,25 +40,26 @@ class ProjectsFinder ...@@ -40,25 +40,26 @@ class ProjectsFinder
private private
def group_projects(current_user, group) def group_projects(current_user, group)
if current_user return [group.projects.public_only] unless current_user
[
group_projects_for_user(current_user, group), user_group_projects = [
group.projects.public_and_internal_only, group_projects_for_user(current_user, group),
group.shared_projects.visible_to_user(current_user) group.shared_projects.visible_to_user(current_user)
] ]
if current_user.external?
user_group_projects << group.projects.public_only
else else
[group.projects.public_only] user_group_projects << group.projects.public_and_internal_only
end end
end end
def all_projects(current_user) def all_projects(current_user)
if current_user return [public_projects] unless current_user
[
current_user.authorized_projects, if current_user.external?
public_and_internal_projects [current_user.authorized_projects, public_projects]
]
else else
[Project.public_only] [current_user.authorized_projects, public_and_internal_projects]
end end
end end
......
...@@ -109,23 +109,10 @@ class Ability ...@@ -109,23 +109,10 @@ class Ability
key = "/user/#{user.id}/project/#{project.id}" key = "/user/#{user.id}/project/#{project.id}"
RequestStore.store[key] ||= begin RequestStore.store[key] ||= begin
team = project.team # Push abilities on the users team role
rules.push(*project_team_rules(project.team, user))
# Rules based on role in project if project.public? || (project.internal? && !user.external?)
if team.master?(user)
rules.push(*project_master_rules)
elsif team.developer?(user)
rules.push(*project_dev_rules)
elsif team.reporter?(user)
rules.push(*project_report_rules)
elsif team.guest?(user)
rules.push(*project_guest_rules)
end
if project.public? || project.internal?
rules.push(*public_project_rules) rules.push(*public_project_rules)
# Allow to read builds for internal projects # Allow to read builds for internal projects
...@@ -148,6 +135,19 @@ class Ability ...@@ -148,6 +135,19 @@ class Ability
end end
end end
def project_team_rules(team, user)
# Rules based on role in project
if team.master?(user)
project_master_rules
elsif team.developer?(user)
project_dev_rules
elsif team.reporter?(user)
project_report_rules
elsif team.guest?(user)
project_guest_rules
end
end
def public_project_rules def public_project_rules
@public_project_rules ||= project_guest_rules + [ @public_project_rules ||= project_guest_rules + [
:download_code, :download_code,
...@@ -356,7 +356,7 @@ class Ability ...@@ -356,7 +356,7 @@ class Ability
] ]
end end
if snippet.public? || snippet.internal? if snippet.public? || (snippet.internal? && !user.external?)
rules << :read_personal_snippet rules << :read_personal_snippet
end end
......
...@@ -254,12 +254,6 @@ class Project < ActiveRecord::Base ...@@ -254,12 +254,6 @@ class Project < ActiveRecord::Base
where('projects.last_activity_at < ?', 6.months.ago) where('projects.last_activity_at < ?', 6.months.ago)
end end
def publicish(user)
visibility_levels = [Project::PUBLIC]
visibility_levels << Project::INTERNAL if user
where(visibility_level: visibility_levels)
end
def with_push def with_push
joins(:events).where('events.action = ?', Event::PUSHED) joins(:events).where('events.action = ?', Event::PUSHED)
end end
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
# hide_project_limit :boolean default(FALSE) # hide_project_limit :boolean default(FALSE)
# unlock_token :string # unlock_token :string
# otp_grace_period_started_at :datetime # otp_grace_period_started_at :datetime
# external :boolean default(FALSE)
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
...@@ -77,6 +78,7 @@ class User < ActiveRecord::Base ...@@ -77,6 +78,7 @@ class User < ActiveRecord::Base
add_authentication_token_field :authentication_token add_authentication_token_field :authentication_token
default_value_for :admin, false default_value_for :admin, false
default_value_for :external, false
default_value_for :can_create_group, gitlab_config.default_can_create_group default_value_for :can_create_group, gitlab_config.default_can_create_group
default_value_for :can_create_team, false default_value_for :can_create_team, false
default_value_for :hide_no_ssh_key, false default_value_for :hide_no_ssh_key, false
...@@ -171,6 +173,7 @@ class User < ActiveRecord::Base ...@@ -171,6 +173,7 @@ class User < ActiveRecord::Base
after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? } after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? }
before_save :ensure_authentication_token before_save :ensure_authentication_token
before_save :ensure_external_user_rights
after_save :ensure_namespace_correct after_save :ensure_namespace_correct
after_initialize :set_projects_limit after_initialize :set_projects_limit
after_create :post_create_hook after_create :post_create_hook
...@@ -218,6 +221,7 @@ class User < ActiveRecord::Base ...@@ -218,6 +221,7 @@ class User < ActiveRecord::Base
# Scopes # Scopes
scope :admins, -> { where(admin: true) } scope :admins, -> { where(admin: true) }
scope :blocked, -> { with_states(:blocked, :ldap_blocked) } scope :blocked, -> { with_states(:blocked, :ldap_blocked) }
scope :external, -> { where(external: true) }
scope :active, -> { with_state(:active) } scope :active, -> { with_state(:active) }
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
...@@ -273,6 +277,8 @@ class User < ActiveRecord::Base ...@@ -273,6 +277,8 @@ class User < ActiveRecord::Base
self.with_two_factor self.with_two_factor
when 'wop' when 'wop'
self.without_projects self.without_projects
when 'external'
self.external
else else
self.active self.active
end end
...@@ -841,4 +847,11 @@ class User < ActiveRecord::Base ...@@ -841,4 +847,11 @@ class User < ActiveRecord::Base
def send_devise_notification(notification, *args) def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later devise_mailer.send(notification, self, *args).deliver_later
end end
def ensure_external_user_rights
return unless self.external?
self.can_create_group = false
self.projects_limit = 0
end
end end
...@@ -58,9 +58,15 @@ ...@@ -58,9 +58,15 @@
= f.label :admin, class: 'control-label' = f.label :admin, class: 'control-label'
- if current_user == @user - if current_user == @user
.col-sm-10= f.check_box :admin, disabled: true .col-sm-10= f.check_box :admin, disabled: true
.col-sm-10 You cannot remove your own admin rights .col-sm-10 You cannot remove your own admin rights.
- else - else
.col-sm-10= f.check_box :admin .col-sm-10= f.check_box :admin
.form-group
= f.label :external, class: 'control-label'
.col-sm-10= f.check_box :external
.col-sm-10 External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects or groups.
%fieldset %fieldset
%legend Profile %legend Profile
.form-group .form-group
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
= link_to admin_users_path(filter: 'two_factor_disabled') do = link_to admin_users_path(filter: 'two_factor_disabled') do
2FA Disabled 2FA Disabled
%small.badge= number_with_delimiter(User.without_two_factor.count) %small.badge= number_with_delimiter(User.without_two_factor.count)
%li.filter-external{class: "#{'active' if params[:filter] == 'external'}"}
= link_to admin_users_path(filter: 'external') do
External
%small.badge= number_with_delimiter(User.external.count)
%li{class: "#{'active' if params[:filter] == "blocked"}"} %li{class: "#{'active' if params[:filter] == "blocked"}"}
= link_to admin_users_path(filter: "blocked") do = link_to admin_users_path(filter: "blocked") do
Blocked Blocked
...@@ -70,12 +74,14 @@ ...@@ -70,12 +74,14 @@
%li %li
.list-item-name .list-item-name
- if user.blocked? - if user.blocked?
%i.fa.fa-lock.cred = icon("lock", class: "cred")
- else - else
%i.fa.fa-user.cgreen = icon("user", class: "cgreen")
= link_to user.name, [:admin, user] = link_to user.name, [:admin, user]
- if user.admin? - if user.admin?
%strong.cred (Admin) %strong.cred (Admin)
- if user.external?
%strong.cred (External)
- if user == current_user - if user == current_user
%span.cred It's you! %span.cred It's you!
.pull-right .pull-right
......
...@@ -47,6 +47,10 @@ ...@@ -47,6 +47,10 @@
- else - else
Disabled Disabled
%li
%span.light External User:
%strong
= @user.external? ? "Yes" : "No"
%li %li
%span.light Can create groups: %span.light Can create groups:
%strong %strong
......
- publicish_project_count = Project.publicish(current_user).count - publicish_project_count = ProjectsFinder.new.execute(current_user).count
%h3.page-title Welcome to GitLab! %h3.page-title Welcome to GitLab!
%p.light Self hosted Git management application. %p.light Self hosted Git management application.
%hr %hr
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
- if current_user.can_create_project? - if current_user.can_create_project?
.link_holder .link_holder
= link_to new_project_path, class: "btn btn-new" do = link_to new_project_path, class: "btn btn-new" do
%i.fa.fa-plus = icon('plus')
New Project New Project
- if current_user.can_create_group? - if current_user.can_create_group?
......
class AddExternalFlagToUsers < ActiveRecord::Migration
def change
add_column :users, :external, :boolean, default: false
end
end
...@@ -940,6 +940,7 @@ ActiveRecord::Schema.define(version: 20160316123110) do ...@@ -940,6 +940,7 @@ ActiveRecord::Schema.define(version: 20160316123110) do
t.string "unlock_token" t.string "unlock_token"
t.datetime "otp_grace_period_started_at" t.datetime "otp_grace_period_started_at"
t.boolean "ldap_email", default: false, null: false t.boolean "ldap_email", default: false, null: false
t.boolean "external", default: false
end end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
- [Importing to GitLab](workflow/importing/README.md). - [Importing to GitLab](workflow/importing/README.md).
- [Markdown](markdown/markdown.md) GitLab's advanced formatting system. - [Markdown](markdown/markdown.md) GitLab's advanced formatting system.
- [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab - [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab
- [Permissions](permissions/permissions.md) Learn what each role in a project (guest/reporter/developer/master/owner) can do. - [Permissions](permissions/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do.
- [Profile Settings](profile/README.md) - [Profile Settings](profile/README.md)
- [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat. - [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat.
- [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. - [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects.
......
...@@ -194,6 +194,7 @@ Parameters: ...@@ -194,6 +194,7 @@ Parameters:
- `admin` (optional) - User is admin - true or false (default) - `admin` (optional) - User is admin - true or false (default)
- `can_create_group` (optional) - User can create groups - true or false - `can_create_group` (optional) - User can create groups - true or false
- `confirm` (optional) - Require confirmation - true (default) or false - `confirm` (optional) - Require confirmation - true (default) or false
- `external` (optional) - Flags the user as external - true or false(default)
## User modification ## User modification
...@@ -219,6 +220,7 @@ Parameters: ...@@ -219,6 +220,7 @@ Parameters:
- `bio` - User's biography - `bio` - User's biography
- `admin` (optional) - User is admin - true or false (default) - `admin` (optional) - User is admin - true or false (default)
- `can_create_group` (optional) - User can create groups - true or false - `can_create_group` (optional) - User can create groups - true or false
- `external` (optional) - Flags the user as external - true or false(default)
Note, at the moment this method does only return a 404 error, Note, at the moment this method does only return a 404 error,
even in cases where a 409 (Conflict) would be more appropriate, even in cases where a 409 (Conflict) would be more appropriate,
...@@ -560,7 +562,7 @@ Parameters: ...@@ -560,7 +562,7 @@ Parameters:
- `uid` (required) - id of specified user - `uid` (required) - id of specified user
Will return `200 OK` on success, `404 User Not Found` is user cannot be found or Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
`403 Forbidden` when trying to block an already blocked user by LDAP synchronization. `403 Forbidden` when trying to block an already blocked user by LDAP synchronization.
## Unblock user ## Unblock user
......
...@@ -71,3 +71,24 @@ Any user can remove themselves from a group, unless they are the last Owner of t ...@@ -71,3 +71,24 @@ Any user can remove themselves from a group, unless they are the last Owner of t
| Create project in group | | | | ✓ | ✓ | | Create project in group | | | | ✓ | ✓ |
| Manage group members | | | | | ✓ | | Manage group members | | | | | ✓ |
| Remove group | | | | | ✓ | | Remove group | | | | | ✓ |
## External Users
In cases where it is desired that a user has access only to some internal or
private projects, there is the option of creating **External Users**. This
feature may be useful when for example a contractor is working on a given
project and should only have access to that project.
External users can only access projects to which they are explicitly granted
access, thus hiding all other internal or private ones from them. Access can be
granted by adding the user as member to the project or group.
They will, like usual users, receive a role in the project or group with all
the abilities that are mentioned in the table above. They cannot however create
groups or projects, and they have the same access as logged out users in all
other cases.
An administrator can flag a user as external [through the API](../api/users.md)
or by checking the checkbox on the admin panel. As an administrator, navigate
to **Admin > Users** to create a new user or edit an existing one. There, you
will find the option to flag the user as external.
...@@ -31,6 +31,7 @@ module API ...@@ -31,6 +31,7 @@ module API
expose :can_create_group?, as: :can_create_group expose :can_create_group?, as: :can_create_group
expose :can_create_project?, as: :can_create_project expose :can_create_project?, as: :can_create_project
expose :two_factor_enabled expose :two_factor_enabled
expose :external
end end
class UserLogin < UserFull class UserLogin < UserFull
......
...@@ -61,19 +61,20 @@ module API ...@@ -61,19 +61,20 @@ module API
# admin - User is admin - true or false (default) # admin - User is admin - true or false (default)
# can_create_group - User can create groups - true or false # can_create_group - User can create groups - true or false
# confirm - Require user confirmation - true (default) or false # confirm - Require user confirmation - true (default) or false
# external - Flags the user as external - true or false(default)
# Example Request: # Example Request:
# POST /users # POST /users
post do post do
authenticated_as_admin! authenticated_as_admin!
required_attributes! [:email, :password, :name, :username] required_attributes! [:email, :password, :name, :username]
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :can_create_group, :admin, :confirm] attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :can_create_group, :admin, :confirm, :external]
admin = attrs.delete(:admin) admin = attrs.delete(:admin)
confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i)) confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i))
user = User.build_user(attrs) user = User.build_user(attrs)
user.admin = admin unless admin.nil? user.admin = admin unless admin.nil?
user.skip_confirmation! unless confirm user.skip_confirmation! unless confirm
identity_attrs = attributes_for_keys [:provider, :extern_uid] identity_attrs = attributes_for_keys [:provider, :extern_uid]
if identity_attrs.any? if identity_attrs.any?
user.identities.build(identity_attrs) user.identities.build(identity_attrs)
end end
...@@ -107,12 +108,13 @@ module API ...@@ -107,12 +108,13 @@ module API
# bio - Bio # bio - Bio
# admin - User is admin - true or false (default) # admin - User is admin - true or false (default)
# can_create_group - User can create groups - true or false # can_create_group - User can create groups - true or false
# external - Flags the user as external - true or false(default)
# Example Request: # Example Request:
# PUT /users/:id # PUT /users/:id
put ":id" do put ":id" do
authenticated_as_admin! authenticated_as_admin!
attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :bio, :can_create_group, :admin] attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :bio, :can_create_group, :admin, :external]
user = User.find(params[:id]) user = User.find(params[:id])
not_found!('User') unless user not_found!('User') unless user
......
...@@ -8,10 +8,12 @@ describe "Internal Project Access", feature: true do ...@@ -8,10 +8,12 @@ describe "Internal Project Access", feature: true do
let(:master) { create(:user) } let(:master) { create(:user) }
let(:guest) { create(:user) } let(:guest) { create(:user) }
let(:reporter) { create(:user) } let(:reporter) { create(:user) }
let(:external_team_member) { create(:user, external: true) }
before do before do
# full access # full access
project.team << [master, :master] project.team << [master, :master]
project.team << [external_team_member, :master]
# readonly # readonly
project.team << [reporter, :reporter] project.team << [reporter, :reporter]
...@@ -34,6 +36,8 @@ describe "Internal Project Access", feature: true do ...@@ -34,6 +36,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -45,6 +49,8 @@ describe "Internal Project Access", feature: true do ...@@ -45,6 +49,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -56,6 +62,8 @@ describe "Internal Project Access", feature: true do ...@@ -56,6 +62,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -67,6 +75,8 @@ describe "Internal Project Access", feature: true do ...@@ -67,6 +75,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -78,6 +88,8 @@ describe "Internal Project Access", feature: true do ...@@ -78,6 +88,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -89,22 +101,23 @@ describe "Internal Project Access", feature: true do ...@@ -89,22 +101,23 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
describe "GET /:project_path/blob" do describe "GET /:project_path/blob" do
before do let(:commit) { project.repository.commit }
commit = project.repository.commit subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) }
path = '.gitignore'
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
end
it { expect(@blob_path).to be_allowed_for master } it { is_expected.to be_allowed_for master }
it { expect(@blob_path).to be_allowed_for reporter } it { is_expected.to be_allowed_for reporter }
it { expect(@blob_path).to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { expect(@blob_path).to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { expect(@blob_path).to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { expect(@blob_path).to be_denied_for :visitor } it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor }
end end
describe "GET /:project_path/edit" do describe "GET /:project_path/edit" do
...@@ -115,6 +128,8 @@ describe "Internal Project Access", feature: true do ...@@ -115,6 +128,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -126,6 +141,8 @@ describe "Internal Project Access", feature: true do ...@@ -126,6 +141,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -137,6 +154,8 @@ describe "Internal Project Access", feature: true do ...@@ -137,6 +154,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -149,6 +168,8 @@ describe "Internal Project Access", feature: true do ...@@ -149,6 +168,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -160,6 +181,8 @@ describe "Internal Project Access", feature: true do ...@@ -160,6 +181,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -171,6 +194,8 @@ describe "Internal Project Access", feature: true do ...@@ -171,6 +194,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -182,6 +207,8 @@ describe "Internal Project Access", feature: true do ...@@ -182,6 +207,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -193,6 +220,8 @@ describe "Internal Project Access", feature: true do ...@@ -193,6 +220,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -209,6 +238,8 @@ describe "Internal Project Access", feature: true do ...@@ -209,6 +238,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -225,6 +256,8 @@ describe "Internal Project Access", feature: true do ...@@ -225,6 +256,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -236,6 +269,8 @@ describe "Internal Project Access", feature: true do ...@@ -236,6 +269,8 @@ describe "Internal Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
end end
...@@ -8,10 +8,12 @@ describe "Private Project Access", feature: true do ...@@ -8,10 +8,12 @@ describe "Private Project Access", feature: true do
let(:master) { create(:user) } let(:master) { create(:user) }
let(:guest) { create(:user) } let(:guest) { create(:user) }
let(:reporter) { create(:user) } let(:reporter) { create(:user) }
let(:external_team_member) { create(:user, external: true) }
before do before do
# full access # full access
project.team << [master, :master] project.team << [master, :master]
project.team << [external_team_member, :master]
# readonly # readonly
project.team << [reporter, :reporter] project.team << [reporter, :reporter]
...@@ -34,6 +36,8 @@ describe "Private Project Access", feature: true do ...@@ -34,6 +36,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -45,6 +49,8 @@ describe "Private Project Access", feature: true do ...@@ -45,6 +49,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -56,6 +62,8 @@ describe "Private Project Access", feature: true do ...@@ -56,6 +62,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -67,6 +75,7 @@ describe "Private Project Access", feature: true do ...@@ -67,6 +75,7 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -78,6 +87,8 @@ describe "Private Project Access", feature: true do ...@@ -78,6 +87,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -89,22 +100,23 @@ describe "Private Project Access", feature: true do ...@@ -89,22 +100,23 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
describe "GET /:project_path/blob" do describe "GET /:project_path/blob" do
before do let(:commit) { project.repository.commit }
commit = project.repository.commit subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore'))}
path = '.gitignore'
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
end
it { expect(@blob_path).to be_allowed_for master } it { is_expected.to be_allowed_for master }
it { expect(@blob_path).to be_allowed_for reporter } it { is_expected.to be_allowed_for reporter }
it { expect(@blob_path).to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { expect(@blob_path).to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { expect(@blob_path).to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { expect(@blob_path).to be_denied_for :visitor } it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor }
end end
describe "GET /:project_path/edit" do describe "GET /:project_path/edit" do
...@@ -115,6 +127,8 @@ describe "Private Project Access", feature: true do ...@@ -115,6 +127,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -126,6 +140,8 @@ describe "Private Project Access", feature: true do ...@@ -126,6 +140,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -137,6 +153,8 @@ describe "Private Project Access", feature: true do ...@@ -137,6 +153,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -149,6 +167,8 @@ describe "Private Project Access", feature: true do ...@@ -149,6 +167,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -160,6 +180,8 @@ describe "Private Project Access", feature: true do ...@@ -160,6 +180,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -171,6 +193,8 @@ describe "Private Project Access", feature: true do ...@@ -171,6 +193,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -187,6 +211,8 @@ describe "Private Project Access", feature: true do ...@@ -187,6 +211,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -203,6 +229,8 @@ describe "Private Project Access", feature: true do ...@@ -203,6 +229,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -214,6 +242,8 @@ describe "Private Project Access", feature: true do ...@@ -214,6 +242,8 @@ describe "Private Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_allowed_for external_team_member }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
end end
...@@ -38,6 +38,7 @@ describe "Public Project Access", feature: true do ...@@ -38,6 +38,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -49,6 +50,7 @@ describe "Public Project Access", feature: true do ...@@ -49,6 +50,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -60,6 +62,7 @@ describe "Public Project Access", feature: true do ...@@ -60,6 +62,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -71,6 +74,7 @@ describe "Public Project Access", feature: true do ...@@ -71,6 +74,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -82,6 +86,7 @@ describe "Public Project Access", feature: true do ...@@ -82,6 +86,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -93,6 +98,7 @@ describe "Public Project Access", feature: true do ...@@ -93,6 +98,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -107,6 +113,7 @@ describe "Public Project Access", feature: true do ...@@ -107,6 +113,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -118,6 +125,7 @@ describe "Public Project Access", feature: true do ...@@ -118,6 +125,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
end end
...@@ -135,6 +143,7 @@ describe "Public Project Access", feature: true do ...@@ -135,6 +143,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -146,23 +155,22 @@ describe "Public Project Access", feature: true do ...@@ -146,23 +155,22 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
end end
describe "GET /:project_path/blob" do describe "GET /:project_path/blob" do
before do let(:commit) { project.repository.commit }
commit = project.repository.commit
path = '.gitignore' subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) }
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
end
it { expect(@blob_path).to be_allowed_for master } it { is_expected.to be_allowed_for master }
it { expect(@blob_path).to be_allowed_for reporter } it { is_expected.to be_allowed_for reporter }
it { expect(@blob_path).to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { expect(@blob_path).to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { expect(@blob_path).to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { expect(@blob_path).to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
describe "GET /:project_path/edit" do describe "GET /:project_path/edit" do
...@@ -173,6 +181,7 @@ describe "Public Project Access", feature: true do ...@@ -173,6 +181,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -184,6 +193,7 @@ describe "Public Project Access", feature: true do ...@@ -184,6 +193,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -195,6 +205,7 @@ describe "Public Project Access", feature: true do ...@@ -195,6 +205,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -207,6 +218,7 @@ describe "Public Project Access", feature: true do ...@@ -207,6 +218,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -218,6 +230,7 @@ describe "Public Project Access", feature: true do ...@@ -218,6 +230,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -229,6 +242,7 @@ describe "Public Project Access", feature: true do ...@@ -229,6 +242,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -240,6 +254,7 @@ describe "Public Project Access", feature: true do ...@@ -240,6 +254,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -251,6 +266,7 @@ describe "Public Project Access", feature: true do ...@@ -251,6 +266,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
...@@ -267,6 +283,7 @@ describe "Public Project Access", feature: true do ...@@ -267,6 +283,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -283,6 +300,7 @@ describe "Public Project Access", feature: true do ...@@ -283,6 +300,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_allowed_for guest } it { is_expected.to be_allowed_for guest }
it { is_expected.to be_allowed_for :user } it { is_expected.to be_allowed_for :user }
it { is_expected.to be_allowed_for :external }
it { is_expected.to be_allowed_for :visitor } it { is_expected.to be_allowed_for :visitor }
end end
...@@ -294,6 +312,7 @@ describe "Public Project Access", feature: true do ...@@ -294,6 +312,7 @@ describe "Public Project Access", feature: true do
it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :admin }
it { is_expected.to be_denied_for guest } it { is_expected.to be_denied_for guest }
it { is_expected.to be_denied_for :user } it { is_expected.to be_denied_for :user }
it { is_expected.to be_denied_for :external }
it { is_expected.to be_denied_for :visitor } it { is_expected.to be_denied_for :visitor }
end end
end end
...@@ -180,6 +180,20 @@ describe User, models: true do ...@@ -180,6 +180,20 @@ describe User, models: true do
it { is_expected.to respond_to(:is_admin?) } it { is_expected.to respond_to(:is_admin?) }
it { is_expected.to respond_to(:name) } it { is_expected.to respond_to(:name) }
it { is_expected.to respond_to(:private_token) } it { is_expected.to respond_to(:private_token) }
it { is_expected.to respond_to(:external?) }
end
describe 'before save hook' do
context 'when saving an external user' do
let(:user) { create(:user) }
let(:external_user) { create(:user, external: true) }
it "sets other properties aswell" do
expect(external_user.can_create_team).to be_falsey
expect(external_user.can_create_group).to be_falsey
expect(external_user.projects_limit).to be 0
end
end
end end
describe '#confirm' do describe '#confirm' do
...@@ -404,6 +418,7 @@ describe User, models: true do ...@@ -404,6 +418,7 @@ describe User, models: true do
expect(user.projects_limit).to eq(Gitlab.config.gitlab.default_projects_limit) expect(user.projects_limit).to eq(Gitlab.config.gitlab.default_projects_limit)
expect(user.can_create_group).to eq(Gitlab.config.gitlab.default_can_create_group) expect(user.can_create_group).to eq(Gitlab.config.gitlab.default_can_create_group)
expect(user.theme_id).to eq(Gitlab.config.gitlab.default_theme) expect(user.theme_id).to eq(Gitlab.config.gitlab.default_theme)
expect(user.external).to be_falsey
end end
end end
......
...@@ -120,6 +120,26 @@ describe API::API, api: true do ...@@ -120,6 +120,26 @@ describe API::API, api: true do
expect(response.status).to eq(201) expect(response.status).to eq(201)
end end
it 'creates non-external users by default' do
post api("/users", admin), attributes_for(:user)
expect(response.status).to eq(201)
user_id = json_response['id']
new_user = User.find(user_id)
expect(new_user).not_to eq nil
expect(new_user.external).to be_falsy
end
it 'should allow an external user to be created' do
post api("/users", admin), attributes_for(:user, external: true)
expect(response.status).to eq(201)
user_id = json_response['id']
new_user = User.find(user_id)
expect(new_user).not_to eq nil
expect(new_user.external).to be_truthy
end
it "should not create user with invalid email" do it "should not create user with invalid email" do
post api('/users', admin), post api('/users', admin),
email: 'invalid email', email: 'invalid email',
...@@ -262,6 +282,13 @@ describe API::API, api: true do ...@@ -262,6 +282,13 @@ describe API::API, api: true do
expect(user.reload.admin).to eq(true) expect(user.reload.admin).to eq(true)
end end
it "should update external status" do
put api("/users/#{user.id}", admin), { external: true }
expect(response.status).to eq 200
expect(json_response['external']).to eq(true)
expect(user.reload.external?).to be_truthy
end
it "should not update admin status" do it "should not update admin status" do
put api("/users/#{admin_user.id}", admin), { can_create_group: false } put api("/users/#{admin_user.id}", admin), { can_create_group: false }
expect(response.status).to eq(200) expect(response.status).to eq(200)
......
...@@ -15,6 +15,8 @@ module AccessMatchers ...@@ -15,6 +15,8 @@ module AccessMatchers
logout logout
when :admin when :admin
login_as(create(:admin)) login_as(create(:admin))
when :external
login_as(create(:user, external: true))
when User when User
login_as(user) login_as(user)
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment