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)  See merge request !3171
This commit is contained in:
commit
21af7459ab
|
|
@ -42,6 +42,7 @@ v 8.6.0 (unreleased)
|
|||
- 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
|
||||
- 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
|
||||
- User deletion is now done in the background so the request can not time out
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
:email, :remember_me, :bio, :name, :username,
|
||||
: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,
|
||||
:projects_limit, :can_create_group, :admin, :key_id
|
||||
:projects_limit, :can_create_group, :admin, :key_id, :external
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -40,25 +40,26 @@ class ProjectsFinder
|
|||
private
|
||||
|
||||
def group_projects(current_user, group)
|
||||
if current_user
|
||||
[
|
||||
group_projects_for_user(current_user, group),
|
||||
group.projects.public_and_internal_only,
|
||||
group.shared_projects.visible_to_user(current_user)
|
||||
]
|
||||
return [group.projects.public_only] unless current_user
|
||||
|
||||
user_group_projects = [
|
||||
group_projects_for_user(current_user, group),
|
||||
group.shared_projects.visible_to_user(current_user)
|
||||
]
|
||||
if current_user.external?
|
||||
user_group_projects << group.projects.public_only
|
||||
else
|
||||
[group.projects.public_only]
|
||||
user_group_projects << group.projects.public_and_internal_only
|
||||
end
|
||||
end
|
||||
|
||||
def all_projects(current_user)
|
||||
if current_user
|
||||
[
|
||||
current_user.authorized_projects,
|
||||
public_and_internal_projects
|
||||
]
|
||||
return [public_projects] unless current_user
|
||||
|
||||
if current_user.external?
|
||||
[current_user.authorized_projects, public_projects]
|
||||
else
|
||||
[Project.public_only]
|
||||
[current_user.authorized_projects, public_and_internal_projects]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -109,23 +109,10 @@ class Ability
|
|||
key = "/user/#{user.id}/project/#{project.id}"
|
||||
|
||||
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 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?
|
||||
if project.public? || (project.internal? && !user.external?)
|
||||
rules.push(*public_project_rules)
|
||||
|
||||
# Allow to read builds for internal projects
|
||||
|
|
@ -148,6 +135,19 @@ class Ability
|
|||
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
|
||||
@public_project_rules ||= project_guest_rules + [
|
||||
:download_code,
|
||||
|
|
@ -356,7 +356,7 @@ class Ability
|
|||
]
|
||||
end
|
||||
|
||||
if snippet.public? || snippet.internal?
|
||||
if snippet.public? || (snippet.internal? && !user.external?)
|
||||
rules << :read_personal_snippet
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -254,12 +254,6 @@ class Project < ActiveRecord::Base
|
|||
where('projects.last_activity_at < ?', 6.months.ago)
|
||||
end
|
||||
|
||||
def publicish(user)
|
||||
visibility_levels = [Project::PUBLIC]
|
||||
visibility_levels << Project::INTERNAL if user
|
||||
where(visibility_level: visibility_levels)
|
||||
end
|
||||
|
||||
def with_push
|
||||
joins(:events).where('events.action = ?', Event::PUSHED)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
# hide_project_limit :boolean default(FALSE)
|
||||
# unlock_token :string
|
||||
# otp_grace_period_started_at :datetime
|
||||
# external :boolean default(FALSE)
|
||||
#
|
||||
|
||||
require 'carrierwave/orm/activerecord'
|
||||
|
|
@ -77,6 +78,7 @@ class User < ActiveRecord::Base
|
|||
add_authentication_token_field :authentication_token
|
||||
|
||||
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_team, false
|
||||
default_value_for :hide_no_ssh_key, false
|
||||
|
|
@ -171,6 +173,7 @@ class User < ActiveRecord::Base
|
|||
|
||||
after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? }
|
||||
before_save :ensure_authentication_token
|
||||
before_save :ensure_external_user_rights
|
||||
after_save :ensure_namespace_correct
|
||||
after_initialize :set_projects_limit
|
||||
after_create :post_create_hook
|
||||
|
|
@ -218,6 +221,7 @@ class User < ActiveRecord::Base
|
|||
# Scopes
|
||||
scope :admins, -> { where(admin: true) }
|
||||
scope :blocked, -> { with_states(:blocked, :ldap_blocked) }
|
||||
scope :external, -> { where(external: true) }
|
||||
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 :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
|
||||
|
|
@ -273,6 +277,8 @@ class User < ActiveRecord::Base
|
|||
self.with_two_factor
|
||||
when 'wop'
|
||||
self.without_projects
|
||||
when 'external'
|
||||
self.external
|
||||
else
|
||||
self.active
|
||||
end
|
||||
|
|
@ -841,4 +847,11 @@ class User < ActiveRecord::Base
|
|||
def send_devise_notification(notification, *args)
|
||||
devise_mailer.send(notification, self, *args).deliver_later
|
||||
end
|
||||
|
||||
def ensure_external_user_rights
|
||||
return unless self.external?
|
||||
|
||||
self.can_create_group = false
|
||||
self.projects_limit = 0
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -58,9 +58,15 @@
|
|||
= f.label :admin, class: 'control-label'
|
||||
- if current_user == @user
|
||||
.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
|
||||
.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
|
||||
%legend Profile
|
||||
.form-group
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
= link_to admin_users_path(filter: 'two_factor_disabled') do
|
||||
2FA Disabled
|
||||
%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"}"}
|
||||
= link_to admin_users_path(filter: "blocked") do
|
||||
Blocked
|
||||
|
|
@ -70,12 +74,14 @@
|
|||
%li
|
||||
.list-item-name
|
||||
- if user.blocked?
|
||||
%i.fa.fa-lock.cred
|
||||
= icon("lock", class: "cred")
|
||||
- else
|
||||
%i.fa.fa-user.cgreen
|
||||
= icon("user", class: "cgreen")
|
||||
= link_to user.name, [:admin, user]
|
||||
- if user.admin?
|
||||
%strong.cred (Admin)
|
||||
- if user.external?
|
||||
%strong.cred (External)
|
||||
- if user == current_user
|
||||
%span.cred It's you!
|
||||
.pull-right
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@
|
|||
- else
|
||||
Disabled
|
||||
|
||||
%li
|
||||
%span.light External User:
|
||||
%strong
|
||||
= @user.external? ? "Yes" : "No"
|
||||
%li
|
||||
%span.light Can create groups:
|
||||
%strong
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- publicish_project_count = Project.publicish(current_user).count
|
||||
- publicish_project_count = ProjectsFinder.new.execute(current_user).count
|
||||
%h3.page-title Welcome to GitLab!
|
||||
%p.light Self hosted Git management application.
|
||||
%hr
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
- if current_user.can_create_project?
|
||||
.link_holder
|
||||
= link_to new_project_path, class: "btn btn-new" do
|
||||
%i.fa.fa-plus
|
||||
= icon('plus')
|
||||
New Project
|
||||
|
||||
- if current_user.can_create_group?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
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
|
|||
t.string "unlock_token"
|
||||
t.datetime "otp_grace_period_started_at"
|
||||
t.boolean "ldap_email", default: false, null: false
|
||||
t.boolean "external", default: false
|
||||
end
|
||||
|
||||
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
- [Importing to GitLab](workflow/importing/README.md).
|
||||
- [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
|
||||
- [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)
|
||||
- [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.
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ Parameters:
|
|||
- `admin` (optional) - User is admin - true or false (default)
|
||||
- `can_create_group` (optional) - User can create groups - true or false
|
||||
- `confirm` (optional) - Require confirmation - true (default) or false
|
||||
- `external` (optional) - Flags the user as external - true or false(default)
|
||||
|
||||
## User modification
|
||||
|
||||
|
|
@ -219,6 +220,7 @@ Parameters:
|
|||
- `bio` - User's biography
|
||||
- `admin` (optional) - User is admin - true or false (default)
|
||||
- `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,
|
||||
even in cases where a 409 (Conflict) would be more appropriate,
|
||||
|
|
|
|||
|
|
@ -71,3 +71,24 @@ Any user can remove themselves from a group, unless they are the last Owner of t
|
|||
| Create project in group | | | | ✓ | ✓ |
|
||||
| Manage group members | | | | | ✓ |
|
||||
| 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
|
|||
expose :can_create_group?, as: :can_create_group
|
||||
expose :can_create_project?, as: :can_create_project
|
||||
expose :two_factor_enabled
|
||||
expose :external
|
||||
end
|
||||
|
||||
class UserLogin < UserFull
|
||||
|
|
|
|||
|
|
@ -61,19 +61,20 @@ module API
|
|||
# admin - User is admin - true or false (default)
|
||||
# can_create_group - User can create groups - true or false
|
||||
# confirm - Require user confirmation - true (default) or false
|
||||
# external - Flags the user as external - true or false(default)
|
||||
# Example Request:
|
||||
# POST /users
|
||||
post do
|
||||
authenticated_as_admin!
|
||||
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)
|
||||
confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i))
|
||||
user = User.build_user(attrs)
|
||||
user.admin = admin unless admin.nil?
|
||||
user.skip_confirmation! unless confirm
|
||||
|
||||
identity_attrs = attributes_for_keys [:provider, :extern_uid]
|
||||
|
||||
if identity_attrs.any?
|
||||
user.identities.build(identity_attrs)
|
||||
end
|
||||
|
|
@ -107,12 +108,13 @@ module API
|
|||
# bio - Bio
|
||||
# admin - User is admin - true or false (default)
|
||||
# can_create_group - User can create groups - true or false
|
||||
# external - Flags the user as external - true or false(default)
|
||||
# Example Request:
|
||||
# PUT /users/:id
|
||||
put ":id" do
|
||||
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])
|
||||
not_found!('User') unless user
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ describe "Internal Project Access", feature: true do
|
|||
let(:master) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:external_team_member) { create(:user, external: true) }
|
||||
|
||||
before do
|
||||
# full access
|
||||
project.team << [master, :master]
|
||||
project.team << [external_team_member, :master]
|
||||
|
||||
# readonly
|
||||
project.team << [reporter, :reporter]
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -89,22 +101,23 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
describe "GET /:project_path/blob" do
|
||||
before do
|
||||
commit = project.repository.commit
|
||||
path = '.gitignore'
|
||||
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
|
||||
end
|
||||
let(:commit) { project.repository.commit }
|
||||
subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) }
|
||||
|
||||
it { expect(@blob_path).to be_allowed_for master }
|
||||
it { expect(@blob_path).to be_allowed_for reporter }
|
||||
it { expect(@blob_path).to be_allowed_for :admin }
|
||||
it { expect(@blob_path).to be_allowed_for guest }
|
||||
it { expect(@blob_path).to be_allowed_for :user }
|
||||
it { expect(@blob_path).to be_denied_for :visitor }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
describe "GET /:project_path/edit" 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_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -126,6 +141,8 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -149,6 +168,8 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -171,6 +194,8 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -193,6 +220,8 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -236,6 +269,8 @@ describe "Internal Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ describe "Private Project Access", feature: true do
|
|||
let(:master) { create(:user) }
|
||||
let(:guest) { create(:user) }
|
||||
let(:reporter) { create(:user) }
|
||||
let(:external_team_member) { create(:user, external: true) }
|
||||
|
||||
before do
|
||||
# full access
|
||||
project.team << [master, :master]
|
||||
project.team << [external_team_member, :master]
|
||||
|
||||
# readonly
|
||||
project.team << [reporter, :reporter]
|
||||
|
|
@ -34,6 +36,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -45,6 +49,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -56,6 +62,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -67,6 +75,7 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -78,6 +87,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -89,22 +100,23 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
describe "GET /:project_path/blob" do
|
||||
before do
|
||||
commit = project.repository.commit
|
||||
path = '.gitignore'
|
||||
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
|
||||
end
|
||||
let(:commit) { project.repository.commit }
|
||||
subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore'))}
|
||||
|
||||
it { expect(@blob_path).to be_allowed_for master }
|
||||
it { expect(@blob_path).to be_allowed_for reporter }
|
||||
it { expect(@blob_path).to be_allowed_for :admin }
|
||||
it { expect(@blob_path).to be_denied_for guest }
|
||||
it { expect(@blob_path).to be_denied_for :user }
|
||||
it { expect(@blob_path).to be_denied_for :visitor }
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
describe "GET /:project_path/edit" 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_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -126,6 +140,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -137,6 +153,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -149,6 +167,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -160,6 +180,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -171,6 +193,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -187,6 +211,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -203,6 +229,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
|
||||
|
|
@ -214,6 +242,8 @@ describe "Private Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
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 }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -93,6 +98,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -118,6 +125,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -146,23 +155,22 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /:project_path/blob" do
|
||||
before do
|
||||
commit = project.repository.commit
|
||||
path = '.gitignore'
|
||||
@blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path))
|
||||
end
|
||||
let(:commit) { project.repository.commit }
|
||||
|
||||
it { expect(@blob_path).to be_allowed_for master }
|
||||
it { expect(@blob_path).to be_allowed_for reporter }
|
||||
it { expect(@blob_path).to be_allowed_for :admin }
|
||||
it { expect(@blob_path).to be_allowed_for guest }
|
||||
it { expect(@blob_path).to be_allowed_for :user }
|
||||
it { expect(@blob_path).to be_allowed_for :visitor }
|
||||
subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) }
|
||||
|
||||
it { is_expected.to be_allowed_for master }
|
||||
it { is_expected.to be_allowed_for reporter }
|
||||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_allowed_for guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
describe "GET /:project_path/edit" 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_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -184,6 +193,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -207,6 +218,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -229,6 +242,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -251,6 +266,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -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 guest }
|
||||
it { is_expected.to be_allowed_for :user }
|
||||
it { is_expected.to be_allowed_for :external }
|
||||
it { is_expected.to be_allowed_for :visitor }
|
||||
end
|
||||
|
||||
|
|
@ -294,6 +312,7 @@ describe "Public Project Access", feature: true do
|
|||
it { is_expected.to be_allowed_for :admin }
|
||||
it { is_expected.to be_denied_for guest }
|
||||
it { is_expected.to be_denied_for :user }
|
||||
it { is_expected.to be_denied_for :external }
|
||||
it { is_expected.to be_denied_for :visitor }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -180,6 +180,20 @@ describe User, models: true do
|
|||
it { is_expected.to respond_to(:is_admin?) }
|
||||
it { is_expected.to respond_to(:name) }
|
||||
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
|
||||
|
||||
describe '#confirm' do
|
||||
|
|
@ -404,6 +418,7 @@ describe User, models: true do
|
|||
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.theme_id).to eq(Gitlab.config.gitlab.default_theme)
|
||||
expect(user.external).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,26 @@ describe API::API, api: true do
|
|||
expect(response.status).to eq(201)
|
||||
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
|
||||
post api('/users', admin),
|
||||
email: 'invalid email',
|
||||
|
|
@ -262,6 +282,13 @@ describe API::API, api: true do
|
|||
expect(user.reload.admin).to eq(true)
|
||||
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
|
||||
put api("/users/#{admin_user.id}", admin), { can_create_group: false }
|
||||
expect(response.status).to eq(200)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ module AccessMatchers
|
|||
logout
|
||||
when :admin
|
||||
login_as(create(:admin))
|
||||
when :external
|
||||
login_as(create(:user, external: true))
|
||||
when User
|
||||
login_as(user)
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue