Commit d9bb4230 authored by Jason Hollingsworth's avatar Jason Hollingsworth

Adding authenticated public mode (internal).

Added visibility_level icons to project view (rather than just text).
Added public projects to search results.
Added ability to restrict visibility levels standard users can set.
parent 51b5509b
......@@ -365,6 +365,10 @@ table {
&.input-large {
width: 210px;
}
&.input-clamp {
max-width: 100%;
}
}
.user-result {
......
......@@ -6,6 +6,7 @@
.cblue { color: #29A }
.cblack { color: #111 }
.cdark { color: #444 }
.camber { color: #ffc000 }
.cwhite { color: #fff!important }
.bgred { background: #F2DEDE!important }
......
......@@ -20,6 +20,15 @@
label { width: 110px; }
.controls { margin-left: 130px; }
.form-actions { padding-left: 130px; background: #fff }
.visibility-levels {
.controls {
margin-bottom: 9px;
}
i {
color: inherit;
}
}
}
.broadcast-messages {
......
......@@ -18,6 +18,12 @@
border-bottom: 1px solid #DDD;
padding-bottom: 25px;
margin-bottom: 30px;
&.empty-project {
border-bottom: 0px;
padding-bottom: 15px;
margin-bottom: 0px;
}
.project-home-title {
font-size: 18px;
......@@ -45,7 +51,7 @@
}
}
.public-label {
.visibility-level-label {
font-size: 14px;
background: #f1f1f1;
padding: 8px 10px;
......@@ -53,6 +59,10 @@
margin-left: 10px;
color: #888;
text-shadow: 0 1px 1px #FFF;
i {
color: inherit;
}
}
}
......@@ -87,9 +97,33 @@
}
}
.project-public-holder {
.help-inline {
padding-top: 7px;
.project-visibility-level-holder {
.controls {
padding-bottom: 9px;
}
.controls {
input {
float: left;
}
.descr {
display: block;
margin-left: 1.5em;
&.restricted {
color: #888;
}
}
.info {
display: block;
margin-top: 5px;
}
strong {
display: inline-block;
width: 4em;
}
}
i {
color: inherit;
}
}
......@@ -130,7 +164,8 @@ ul.nav.nav-projects-tabs {
margin: 0px;
}
.my-projects {
.my-projects,
.public-projects {
li {
.project-info {
margin-bottom: 10px;
......
......@@ -8,6 +8,11 @@ module Projects
# get namespace id
namespace_id = params.delete(:namespace_id)
# check that user is allowed to set specified visibility_level
unless Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level])
params.delete(:visibility_level)
end
# Load default feature settings
default_features = Gitlab.config.gitlab.default_projects_features
......@@ -17,7 +22,7 @@ module Projects
wall_enabled: default_features.wall,
snippets_enabled: default_features.snippets,
merge_requests_enabled: default_features.merge_requests,
public: default_features.public
visibility_level: default_features.visibility_level
}.stringify_keys
@project = Project.new(default_opts.merge(params))
......
......@@ -2,7 +2,11 @@ module Projects
class UpdateContext < BaseContext
def execute(role = :default)
params[:project].delete(:namespace_id)
params[:project].delete(:public) unless can?(current_user, :change_public_mode, project)
# check that user is allowed to set specified visibility_level
unless can?(current_user, :change_visibility_level, project) && Gitlab::VisibilityLevel.allowed_for?(current_user, params[:project][:visibility_level])
params[:project].delete(:visibility_level)
end
new_branch = params[:project].delete(:default_branch)
if project.repository.exists? && new_branch != project.repository.root_ref
......
class SearchContext
attr_accessor :project_ids, :params
attr_accessor :project_ids, :current_user, :params
def initialize(project_ids, params)
@project_ids, @params = project_ids, params.dup
def initialize(project_ids, user, params)
@project_ids, @current_user, @params = project_ids, user, params.dup
end
def execute
......@@ -10,7 +10,8 @@ class SearchContext
query = Shellwords.shellescape(query) if query.present?
return result unless query.present?
result[:projects] = Project.where("projects.id in (?) OR projects.public = true", project_ids).search(query).limit(20)
visibility_levels = @current_user ? [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ] : [ Gitlab::VisibilityLevel::PUBLIC ]
result[:projects] = Project.where("projects.id in (?) OR projects.visibility_level in (?)", project_ids, visibility_levels).search(query).limit(20)
# Search inside single project
single_project_search(Project.where(id: project_ids), query)
......
......@@ -8,7 +8,7 @@ class Admin::ProjectsController < Admin::ApplicationController
user = User.find_by_id(owner_id)
@projects = user ? user.owned_projects : Project.scoped
@projects = @projects.where(public: true) if params[:public_only].present?
@projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
@projects = @projects.with_push if params[:with_push].present?
@projects = @projects.abandoned if params[:abandoned].present?
@projects = @projects.search(params[:name]) if params[:name].present?
......
......@@ -102,7 +102,7 @@ class ApplicationController < ActionController::Base
end
def authorize_code_access!
return access_denied! unless can?(current_user, :download_code, project) or project.public?
return access_denied! unless can?(current_user, :download_code, project)
end
def authorize_push!
......
......@@ -10,7 +10,7 @@ class Projects::ApplicationController < ApplicationController
id = params[:project_id] || params[:id]
@project = Project.find_with_namespace(id)
return if @project && @project.public
return if @project && @project.public?
end
super
......
......@@ -55,7 +55,7 @@ class ProjectsController < ApplicationController
end
def show
return authenticate_user! unless @project.public || current_user
return authenticate_user! unless @project.public? || current_user
limit = (params[:limit] || 20).to_i
@events = @project.events.recent
......
......@@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController
layout 'public'
def index
@projects = Project.public_only
@projects = Project.public_or_internal_only(current_user)
@projects = @projects.search(params[:search]) if params[:search].present?
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
end
......
......@@ -14,7 +14,7 @@ class SearchController < ApplicationController
project_ids.select! { |id| id == project_id.to_i}
end
result = SearchContext.new(project_ids, params).execute
result = SearchContext.new(project_ids, current_user, params).execute
@projects = result[:projects]
@merge_requests = result[:merge_requests]
......
......@@ -11,6 +11,10 @@ module IconsHelper
content_tag :i, nil, class: 'icon-globe cblue'
end
def internal_icon
content_tag :i, nil, class: 'icon-shield camber'
end
def private_icon
content_tag :i, nil, class: 'icon-lock cgreen'
end
......
module SearchHelper
def search_autocomplete_source
return unless current_user
[
groups_autocomplete,
projects_autocomplete,
public_projects_autocomplete,
default_autocomplete,
project_autocomplete,
help_autocomplete
......@@ -75,4 +75,11 @@ module SearchHelper
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
end
end
# Autocomplete results for the current user's projects
def public_projects_autocomplete
Project.public_or_internal_only(current_user).map do |p|
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
end
end
end
module VisibilityLevelHelper
def visibility_level_color(level)
case level
when Gitlab::VisibilityLevel::PRIVATE
'cgreen'
when Gitlab::VisibilityLevel::INTERNAL
'camber'
when Gitlab::VisibilityLevel::PUBLIC
'cblue'
end
end
def visibility_level_description(level)
capture_haml do
haml_tag :span do
case level
when Gitlab::VisibilityLevel::PRIVATE
haml_concat "Project access must be granted explicitly for each user."
when Gitlab::VisibilityLevel::INTERNAL
haml_concat "The project can be cloned by"
haml_tag :em, "any logged in user."
haml_concat "It will also be listed on the #{link_to "public access directory", public_root_path} for logged in users."
haml_tag :em, "Any logged in user"
haml_concat "will have #{link_to "Guest", help_permissions_path} permissions on the repository."
when Gitlab::VisibilityLevel::PUBLIC
haml_concat "The project can be cloned"
haml_tag :em, "without any"
haml_concat "authentication."
haml_concat "It will also be listed on the #{link_to "public access directory", public_root_path}."
haml_tag :em, "Any logged in user"
haml_concat "will have #{link_to "Guest", help_permissions_path} permissions on the repository."
end
end
end
end
def visibility_level_icon(level)
case level
when Gitlab::VisibilityLevel::PRIVATE
private_icon
when Gitlab::VisibilityLevel::INTERNAL
internal_icon
when Gitlab::VisibilityLevel::PUBLIC
public_icon
end
end
def visibility_level_label(level)
Project.visibility_levels.key(level)
end
def restricted_visibility_levels
current_user.is_admin? ? [] : gitlab_config.restricted_visibility_levels
end
end
\ No newline at end of file
......@@ -29,7 +29,7 @@ class Ability
nil
end
if project && project.public
if project && project.public?
[
:read_project,
:read_wiki,
......@@ -71,7 +71,7 @@ class Ability
rules << project_guest_rules
end
if project.public?
if project.public? || project.internal?
rules << public_project_rules
end
......@@ -89,7 +89,7 @@ class Ability
def public_project_rules
project_guest_rules + [
:download_code,
:fork_project,
:fork_project
]
end
......@@ -145,7 +145,7 @@ class Ability
def project_admin_rules
project_master_rules + [
:change_namespace,
:change_public_mode,
:change_visibility_level,
:rename_project,
:remove_project
]
......
......@@ -14,24 +14,25 @@
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
# public :boolean default(FALSE), not null
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
# imported :boolean default(FALSE), not null
# import_url :string(255)
# visibility_level :integer default(0), not null
#
class Project < ActiveRecord::Base
include Gitlab::ShellAdapter
include Gitlab::VisibilityLevel
extend Enumerize
ActsAsTaggableOn.strict_case_match = true
attr_accessible :name, :path, :description, :issues_tracker, :label_list,
:issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
:wiki_enabled, :public, :import_url, :last_activity_at, as: [:default, :admin]
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, as: [:default, :admin]
attr_accessible :namespace_id, :creator_id, as: :admin
......@@ -108,7 +109,8 @@ class Project < ActiveRecord::Base
scope :sorted_by_activity, -> { reorder("projects.last_activity_at DESC") }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) }
scope :public_only, -> { where(public: true) }
scope :public_only, -> { where(visibility_level: PUBLIC) }
scope :public_or_internal_only, ->(user) { where("visibility_level IN (:levels)", levels: user ? [ INTERNAL, PUBLIC ] : [ PUBLIC ]) }
enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab
......@@ -140,6 +142,10 @@ class Project < ActiveRecord::Base
where(path: id, namespace_id: nil).last
end
end
def visibility_levels
Gitlab::VisibilityLevel.options
end
end
def team
......@@ -451,4 +457,8 @@ class Project < ActiveRecord::Base
def default_branch
@default_branch ||= repository.root_ref if repository.exists?
end
def visibility_level_field
visibility_level
end
end
......@@ -10,11 +10,15 @@
.control-group
= label_tag :owner_id, 'Owner:', class: 'control-label'
.controls
= users_select_tag :owner_id, selected: params[:owner_id], class: 'input-large'
.control-group
= label_tag :public_only, 'Public Only', class: 'control-label'
.controls
= check_box_tag :public_only, 1, params[:public_only]
= users_select_tag :owner_id, selected: params[:owner_id], class: 'input-large input-clamp'
.control-group.visibility-levels
= label_tag :visibility_level, 'Visibility Levels', class: 'control-label'
- Project.visibility_levels.each do |label, level|
.controls
= check_box_tag 'visibility_levels[]', level, params[:visibility_levels].present? && params[:visibility_levels].include?(level.to_s)
%span.descr
= visibility_level_icon(level)
= label
.control-group
= label_tag :with_push, 'Not empty', class: 'control-label'
.controls
......@@ -42,10 +46,7 @@
%ul.well-list
- @projects.each do |project|
%li
- if project.public
= public_icon
- else
= private_icon
= visibility_level_icon(project.visibility_level)
= link_to project.name_with_namespace, [:admin, project]
.pull-right
= link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
......
......@@ -66,14 +66,10 @@
%li
%span.light access:
%strong
- if @project.public
%span.cblue
%i.icon-share
Public
- else
%span.cgreen
%i.icon-lock
Private
%span{ class: visibility_level_color(@project.visibility_level) }
= visibility_level_icon(@project.visibility_level)
= visibility_level_label(@project.visibility_level)
.ui-box
.title
Transfer project
......@@ -88,9 +84,6 @@
.controls
= f.submit 'Transfer', class: 'btn btn-primary'
.span6
- if @group
.ui-box
......
......@@ -58,10 +58,10 @@
%h4.project-title
= link_to project_path(project), class: dom_class(project) do
= project.name_with_namespace
- if project.public
- unless project.private?
%small.access-icon
= public_icon
Public
= visibility_level_icon(project.visibility_level)
= visibility_level_label(project.visibility_level)
- if current_user.can_leave_project?(project)
.pull-right
......
......@@ -51,10 +51,7 @@
%ul.well-list
- @group.projects.each do |project|
%li
- if project.public
= public_icon
- else
= private_icon
= visibility_level_icon(project.visibility_level)
= link_to project.name_with_namespace, project
.pull-right
= link_to 'Members', project_team_index_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
......
......@@ -143,7 +143,7 @@
%td.permission-x &#10003;
%td.permission-x &#10003;
%tr
%td Switch public mode
%td Switch visibility level
%td
%td
%td
......
......@@ -2,14 +2,20 @@
%h3.page-title Public Access
%p
GitLab allows you to open selected projects to be accessed publicly.
These projects will be cloneable
GitLab allows you to open selected projects to be accessed publicly or internally.
Projects with either of these visibility levels will be listed in the #{link_to "public access directory", public_root_path}. Internal projects will only be available to authenticated users.
%p
= public_icon
Public projects will be cloneable
%em without any
authentication.
Also they will be listed on the #{link_to "public access directory", public_root_path}.
%p
= internal_icon
Internal projects will be cloneable by
%em any authenticated user.
%ol
%li Go to your project dashboard
%li Click on the "Edit" tab
%li Select "Public clone access"
%li Change "Visibility Level"
- empty_repo = @project.empty_repo?
.project-home-panel{:class => ("empty-project" if empty_repo)}
.row
.span5
%h4.project-home-title
= @project.name_with_namespace
%span.visibility-level-label
= visibility_level_icon(@project.visibility_level)
= visibility_level_label(@project.visibility_level)
.span7
- unless empty_repo
.project-home-dropdown
= render "dropdown"
.form-horizontal
= render "shared/clone_panel"
.project-home-extra.clearfix
.project-home-desc
- if @project.description.present?
= @project.description
- if can?(current_user, :admin_project, @project)
&ndash;
%strong= link_to 'Edit', edit_project_path
- unless empty_repo
.project-home-links
= link_to pluralize(@repository.round_commit_count, 'commit'), project_commits_path(@project, @ref || @repository.root_ref)
= link_to pluralize(@repository.branch_names.count, 'branch'), project_branches_path(@project)
= link_to pluralize(@repository.tag_names.count, 'tag'), project_tags_path(@project)
%span.light.prepend-left-20= repository_size
\ No newline at end of file
.control-group.project-visibility-level-holder
= f.label :visibility_level, "Visibility Level"
- if can_change_visibility_level
- Gitlab::VisibilityLevel.values.each do |level|
- restricted = restricted_visibility_levels.include?(level)
.controls
= f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted
%span.descr{:class => ("restricted" if restricted)}
= visibility_level_icon(level)
%strong
= visibility_level_label(level)
= visibility_level_description(level)
- unless restricted_visibility_levels.empty?
.controls
%span.info
Some visibility level settings have been restricted by the administrator.
- else
.controls
%span.info
= visibility_level_icon(visibility_level)
%strong
= visibility_level_label(visibility_level)
= visibility_level_description(visibility_level)
\ No newline at end of file
......@@ -29,22 +29,7 @@
.controls= f.select(:default_branch, @repository.branch_names, {}, {class: 'chosen'})
- if can?(current_user, :change_public_mode, @project)
%fieldset.public-mode
%legend
Public mode:
.control-group
= f.label :public, class: 'control-label' do
%span Public access
.controls
= f.check_box :public
%span.descr
If checked, this project can be cloned
%em without any
authentication.
It will also be listed on the #{link_to "public access directory", public_root_path}.
%em Any
user will have #{link_to "Guest", help_permissions_path} permissions on the repository.
= render "visibility_level", f: f, visibility_level: @project.visibility_level, can_change_visibility_level: can?(current_user, :change_visibility_level, @project)
%fieldset.features
%legend
......
%h3.page-title
= @project.name_with_namespace
.form-horizontal.pull-right
= render "shared/clone_panel"
= render "home_panel"
- if @project.import? && !@project.imported
.save-project-loader
......
......@@ -47,12 +47,7 @@
%span.light (optional)
.controls
= f.text_area :description, placeholder: "Awesome project", class: "input-xlarge", rows: 3, maxlength: 250, tabindex: 3
.control-group.project-public-holder
= f.label :public do
%span Public project
.controls
= f.check_box :public, { checked: gitlab_config.default_projects_features.public }, true, false
%span.help-inline Make project visible to everyone
= render "visibility_level", f: f, visibility_level: gitlab_config.default_projects_features.visibility_level, can_change_visibility_level: true
.form-actions
= f.submit 'Create project', class: "btn btn-create project-submit", tabindex: 4
......
.project-home-panel
.row
.span5
%h4.project-home-title
= @project.name_with_namespace
- if @project.public
%span.public-label Public
- else
%span.public-label Private
.span7
.project-home-dropdown
= render "dropdown"
.form-horizontal
= render "shared/clone_panel"
.project-home-extra.clearfix
.project-home-desc
- if @project.description.present?
= @project.description
- if can?(current_user, :admin_project, @project)
&ndash;
%strong= link_to 'Edit', edit_project_path
.project-home-links
= link_to pluralize(@repository.round_commit_count, 'commit'), project_commits_path(@project, @ref || @repository.root_ref)
= link_to pluralize(@repository.branch_names.count, 'branch'), project_branches_path(@project)
= link_to pluralize(@repository.tag_names.count, 'tag'), project_tags_path(@project)
%span.light.prepend-left-20= repository_size
= render "home_panel"
.row
.span9
......
......@@ -19,6 +19,10 @@
%h4
= link_to project_path(project) do
= project.name_with_namespace
- if project.internal?
%small.access-icon
= internal_icon
Internal
.pull-right
%pre.public-clone git clone #{project.http_url_to_repo}
......
......@@ -55,6 +55,10 @@ production: &base
# default: false - Account passwords are not sent via the email if signup is enabled.
# signup_enabled: true
# Restrict setting visibility levels for non-admin users.
# The default is to allow all levels.
#restricted_visibility_levels: [ "public" ]
## Automatic issue closing
# If a commit message matches this regular expression, all issues referenced from the matched text will be closed.
# This happens when the commit is pushed or merged into the default branch of a project.
......@@ -68,7 +72,7 @@ production: &base
wiki: true
wall: false
snippets: false
public: false
visibility_level: "private" # can be "private" | "internal" | "public"
## External issues trackers
issues_tracker:
......
......@@ -30,6 +30,29 @@ class Settings < Settingslogic
gitlab.relative_url_root
].join('')
end
# check that values in `current` (string or integer) is a contant in `modul`.
def verify_constant_array(modul, current, default)
values = default || []
if !current.nil?
values = []
current.each do |constant|
values.push(verify_constant(modul, constant, nil))
end
values.delete_if { |value| value.nil? }
end
values
end
# check that `current` (string or integer) is a contant in `modul`.
def verify_constant(modul, current, default)
constant = modul.constants.find{ |name| modul.const_get(name) == current }
value = constant.nil? ? default : modul.const_get(constant)
if current.is_a? String
value = modul.const_get(current.upcase) rescue default
end
value
end
end
end
......@@ -68,6 +91,7 @@ rescue ArgumentError # no user configured
'/home/' + Settings.gitlab['user']
end
Settings.gitlab['signup_enabled'] ||= false
Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
Settings.gitlab['issue_closing_pattern'] = '([Cc]loses|[Ff]ixes) #(\d+)' if Settings.gitlab['issue_closing_pattern'].nil?
Settings.gitlab['default_projects_features'] ||= {}
......@@ -76,7 +100,7 @@ Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.g
Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil?
Settings.gitlab.default_projects_features['wall'] = false if Settings.gitlab.default_projects_features['wall'].nil?
Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil?
Settings.gitlab.default_projects_features['public'] = false if Settings.gitlab.default_projects_features['public'].nil?
Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE)
#
# Gravatar
......
class AddVisibilityLevelToProjects < ActiveRecord::Migration
def self.up
add_column :projects, :visibility_level, :integer, :default => 0, :null => false
Project.where(public: true).update_all(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
remove_column :projects, :public
end
def self.down
add_column :projects, :public, :boolean, :default => false, :null => false
Project.where(visibility_level: Gitlab::VisibilityLevel::PUBLIC).update_all(public: true)
remove_column :projects, :visibility_level
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20131112114325) do
ActiveRecord::Schema.define(:version => 20131112220935) do
create_table "broadcast_messages", :force => true do |t|
t.text "message", :null => false
......@@ -185,13 +185,13 @@ ActiveRecord::Schema.define(:version => 20131112114325) do
t.boolean "merge_requests_enabled", :default => true, :null => false
t.boolean "wiki_enabled", :default => true, :null => false
t.integer "namespace_id"
t.boolean "public", :default => false, :null => false
t.string "issues_tracker", :default => "gitlab", :null => false
t.string "issues_tracker_id"
t.boolean "snippets_enabled", :default => true, :null => false
t.datetime "last_activity_at"
t.boolean "imported", :default => false, :null => false
t.string "import_url"
t.integer "visibility_level", :default => 0, :null => false
end
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
......
......@@ -15,6 +15,7 @@ GET /projects
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
"web_url": "http://example.com/diaspora/diaspora-client",
......@@ -49,6 +50,7 @@ GET /projects
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
"web_url": "http://example.com/brightbox/puppet",
......@@ -117,6 +119,7 @@ Parameters:
"description": null,
"default_branch": "master",
"public": false,
"visibility_level": 0,
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git",
"http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git",
"web_url": "http://example.com/diaspora/diaspora-project-site",
......@@ -234,7 +237,8 @@ Parameters:
+ `merge_requests_enabled` (optional)
+ `wiki_enabled` (optional)
+ `snippets_enabled` (optional)
+ `public` (optional)
+ `public` (optional) - if `true` same as setting visibility_level = 20
+ `visibility_level` (optional)
### Create project for user
......@@ -256,7 +260,8 @@ Parameters:
+ `merge_requests_enabled` (optional)
+ `wiki_enabled` (optional)
+ `snippets_enabled` (optional)
+ `public` (optional)
+ `public` (optional) - if `true` same as setting visibility_level = 20
+ `visibility_level` (optional)
## Remove project
......
Feature: Public Projects Feature
Background:
Given public project "Community"
And internal project "Internal"
And private project "Enterprise"
Scenario: I visit public area
When I visit the public projects area
Then I should see project "Community"
And I should not see project "Internal"
And I should not see project "Enterprise"
Scenario: I visit public project page
When I visit project "Community" page
Then I should see project "Community" home page
Scenario: I visit internal project page
When I visit project "Internal" page
Then page status code should be 404
Scenario: I visit private project page
When I visit project "Enterprise" page
Then page status code should be 404
Scenario: I visit an empty public project page
Given public empty project "Empty Public Project"
When I visit empty project page
Then I should see empty public project details
Scenario: I visit public area as user
Given I sign in as a user
When I visit the public projects area
Then I should see project "Community"
And I should see project "Internal"
And I should not see project "Enterprise"
Scenario: I visit internal project page as user
Given I sign in as a user
When I visit project "Internal" page
Then I should see project "Internal" home page
class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedProject
step 'I should see project "Community"' do
page.should have_content "Community"
......@@ -23,11 +25,11 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
end
step 'public project "Community"' do
create :project_with_code, name: 'Community', public: true
create :project_with_code, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
end
step 'public empty project "Empty Public Project"' do
create :project, name: 'Empty Public Project', public: true
create :project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC
end
step 'I visit empty project page' do
......@@ -48,16 +50,38 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
create :project, name: 'Enterprise'
end
step 'I visit project "Enterprise" page' do
project = Project.find_by_name('Enterprise')
visit project_path(project)
end
step 'I should see project "Community" home page' do
within '.project-home-title' do
page.should have_content 'Community'
end
end
private
step 'internal project "Internal"' do
create :project_with_code, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL
end
def project
@project ||= Project.find_by_name("Community")
step 'I should see project "Internal"' do
page.should have_content "Internal"
end
step 'I should not see project "Internal"' do
page.should_not have_content "Internal"
end
step 'I visit project "Internal" page' do
project = Project.find_by_name('Internal')
visit project_path(project)
end
step 'I should see project "Internal" home page' do
within '.project-home-title' do
page.should have_content 'Internal'
end
end
end
......@@ -31,11 +31,13 @@ module API
end
class Project < Grape::Entity
expose :id, :description, :default_branch, :public, :ssh_url_to_repo, :http_url_to_repo, :web_url
expose :id, :description, :default_branch
expose :public?, as: :public
expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url
expose :owner, using: Entities::UserBasic
expose :name, :name_with_namespace
expose :path, :path_with_namespace
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at, :public
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at
expose :namespace
expose :forked_from_project, using: Entities::ForkedFromProject, :if => lambda{ | project, options | project.forked? }
end
......
......@@ -11,6 +11,13 @@ module API
end
not_found!
end
def map_public_to_visibility_level(attrs)
publik = attrs.delete(:public)
publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik)
attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true
attrs
end
end
# Get a projects list for authenticated user
......@@ -76,7 +83,8 @@ module API
# wiki_enabled (optional)
# snippets_enabled (optional)
# namespace_id (optional) - defaults to user namespace
# public (optional) - false by default
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - 0 by default
# Example Request
# POST /projects
post do
......@@ -90,7 +98,9 @@ module API
:wiki_enabled,
:snippets_enabled,
:namespace_id,
:public]
:public,
:visibility_level]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateContext.new(current_user, attrs).execute
if @project.saved?
present @project, with: Entities::Project
......@@ -114,7 +124,8 @@ module API
# merge_requests_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
# public (optional)
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional)
# Example Request
# POST /projects/user/:user_id
post "user/:user_id" do
......@@ -128,7 +139,9 @@ module API
:merge_requests_enabled,
:wiki_enabled,
:snippets_enabled,
:public]
:public,
:visibility_level]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateContext.new(user, attrs).execute
if @project.saved?
present @project, with: Entities::Project
......@@ -290,7 +303,8 @@ module API
# GET /projects/search/:query
get "/search/:query" do
ids = current_user.authorized_projects.map(&:id)
projects = Project.where("(id in (?) OR public = true) AND (name LIKE (?))", ids, "%#{params[:query]}%")
visibility_levels = [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ]
projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%")
present paginate(projects), with: Entities::Project
end
end
......
......@@ -58,7 +58,7 @@ module Grack
end
else
return unauthorized unless project.public
return unauthorized unless project.public?
end
if authorized_git_request?
......@@ -80,7 +80,7 @@ module Grack
def authorize_request(service)
case service
when 'git-upload-pack'
project.public || can?(user, :download_code, project)
can?(user, :download_code, project)
when'git-receive-pack'
refs.each do |ref|
action = if project.protected_branch?(ref)
......
# Gitlab::VisibilityLevel module
#
# Define allowed public modes that can be used for
# GitLab projects to determine project public mode
#
module Gitlab
module VisibilityLevel
PRIVATE = 0
INTERNAL = 10
PUBLIC = 20
class << self
def values
options.values
end
def options
{
'Private' => PRIVATE,
'Internal' => INTERNAL,
'Public' => PUBLIC
}
end
def allowed_for?(user, level)
user.is_admin? || !Gitlab.config.gitlab.restricted_visibility_levels.include?(level)
end
end
def private?
visibility_level_field == PRIVATE
end
def internal?
visibility_level_field == INTERNAL
end
def public?
visibility_level_field == PUBLIC
end
end
end
......@@ -7,6 +7,7 @@ describe Projects::CreateContext do
describe :create_by_user do
before do
@user = create :user
@admin = create :user, admin: true
@opts = {
name: "GitLab",
namespace: @user.namespace
......@@ -37,7 +38,7 @@ describe Projects::CreateContext do
it { @project.namespace.should == @group }
end
context 'respect configured public setting' do
context 'respect configured visibility setting' do
before(:each) do
@settings = double("settings")
@settings.stub(:issues) { true }
......@@ -46,25 +47,90 @@ describe Projects::CreateContext do
@settings.stub(:wall) { true }
@settings.stub(:snippets) { true }
stub_const("Settings", Class.new)
@restrictions = double("restrictions")
@restrictions.stub(:restricted_visibility_levels) { [] }
Settings.stub_chain(:gitlab).and_return(@restrictions)
Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings)
end
context 'should be public when setting is public' do
before do
@settings.stub(:public) { true }
@settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PUBLIC }
@project = create_project(@user, @opts)
end
it { @project.public.should be_true }
it { @project.public?.should be_true }
end
context 'should be private when setting is not public' do
context 'should be private when setting is private' do
before do
@settings.stub(:public) { false }
@settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE }
@project = create_project(@user, @opts)
end
it { @project.public.should be_false }
it { @project.private?.should be_true }
end
context 'should be internal when setting is internal' do
before do
@settings.stub(:visibility_level) { Gitlab::VisibilityLevel::INTERNAL }
@project = create_project(@user, @opts)
end
it { @project.internal?.should be_true }
end
end
context 'respect configured visibility restrictions setting' do
before(:each) do
@settings = double("settings")
@settings.stub(:issues) { true }
@settings.stub(:merge_requests) { true }
@settings.stub(:wiki) { true }
@settings.stub(:wall) { true }
@settings.stub(:snippets) { true }
@settings.stub(:visibility_level) { Gitlab::VisibilityLevel::PRIVATE }
stub_const("Settings", Class.new)
@restrictions = double("restrictions")
@restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] }
Settings.stub_chain(:gitlab).and_return(@restrictions)
Settings.stub_chain(:gitlab, :default_projects_features).and_return(@settings)
end
context 'should be private when option is public' do
before do
@opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
@project = create_project(@user, @opts)
end
it { @project.private?.should be_true }
end
context 'should be public when option is public for admin' do
before do
@opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
@project = create_project(@admin, @opts)
end
it { @project.public?.should be_true }
end
context 'should be private when option is private' do
before do
@opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
@project = create_project(@user, @opts)
end
it { @project.private?.should be_true }
end
context 'should be internal when option is internal' do
before do
@opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
@project = create_project(@user, @opts)
end
it { @project.internal?.should be_true }
end
end
end
......@@ -73,3 +139,4 @@ describe Projects::CreateContext do
Projects::CreateContext.new(user, opts).execute
end
end
require 'spec_helper'
describe Projects::UpdateContext do
before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
describe :update_by_user do
before do
@user = create :user
@admin = create :user, admin: true
@project = create :project, creator_id: @user.id, namespace: @user.namespace
@opts = { project: {} }
end
context 'should be private when updated to private' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.private?.should be_true }
end
context 'should be internal when updated to internal' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.internal?.should be_true }
end
context 'should be public when updated to public' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.public?.should be_true }
end
context 'respect configured visibility restrictions setting' do
before(:each) do
@restrictions = double("restrictions")
@restrictions.stub(:restricted_visibility_levels) { [ Gitlab::VisibilityLevel::PUBLIC ] }
Settings.stub_chain(:gitlab).and_return(@restrictions)
end
context 'should be private when updated to private' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.private?.should be_true }
end
context 'should be internal when updated to internal' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.internal?.should be_true }
end
context 'should be private when updated to public' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
update_project(@project, @user, @opts)
end
it { @created_private.should be_true }
it { @project.private?.should be_true }
end
context 'should be public when updated to public by admin' do
before do
@created_private = @project.private?
@opts[:project].merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
update_project(@project, @admin, @opts)
end
it { @created_private.should be_true }
it { @project.public?.should be_true }
end
end
end
def update_project(project, user, opts)
Projects::UpdateContext.new(project, user, opts).execute
end
end
\ No newline at end of file
......@@ -3,23 +3,39 @@ require 'spec_helper'
describe SearchContext do
let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') }
let(:user) { create(:user, namespace: found_namespace) }
let!(:found_project) { create(:project, name: 'searchable_project', creator_id: user.id, namespace: found_namespace, public: false) }
let!(:found_project) { create(:project, name: 'searchable_project', creator_id: user.id, namespace: found_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
let(:unfound_namespace) { create(:namespace, name: 'unfound namespace', path: 'yet_something_else') }
let!(:unfound_project) { create(:project, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace, public: false) }
let(:public_namespace) { create(:namespace, path: 'something_else',name: 'searchable public namespace') }
let(:other_user) { create(:user, namespace: public_namespace) }
let!(:public_project) { create(:project, name: 'searchable_public_project', creator_id: other_user.id, namespace: public_namespace, public: true) }
let!(:unfound_project) { create(:project, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
let(:internal_namespace) { create(:namespace, path: 'something_internal',name: 'searchable internal namespace') }
let(:internal_user) { create(:user, namespace: internal_namespace) }
let!(:internal_project) { create(:project, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
let(:public_namespace) { create(:namespace, path: 'something_public',name: 'searchable public namespace') }
let(:public_user) { create(:user, namespace: public_namespace) }
let!(:public_project) { create(:project, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
describe '#execute' do
it 'public projects should be searchable' do
context = SearchContext.new([found_project.id], {search_code: false, search: "searchable"})
context = SearchContext.new([found_project.id], nil, {search_code: false, search: "searchable"})
results = context.execute
results[:projects].should == [found_project, public_project]
end
it 'internal projects should be searchable' do
context = SearchContext.new([found_project.id], user, {search_code: false, search: "searchable"})
results = context.execute
# can't seem to rely on the return order, so check this way
#subject { results[:projects] }
results[:projects].should have(3).items
results[:projects].should include(found_project)
results[:projects].should include(internal_project)
results[:projects].should include(public_project)
end
it 'namespace name should be searchable' do
context = SearchContext.new([found_project.id], {search_code: false, search: "searchable namespace"})
context = SearchContext.new([found_project.id], user, {search_code: false, search: "searchable namespace"})
results = context.execute
results[:projects].should == [found_project]
end
......
require 'spec_helper'
describe "Internal Project Access" do
let(:project) { create(:project_with_code) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:reporter) { create(:user) }
before do
# internal project
project.visibility_level = Gitlab::VisibilityLevel::INTERNAL
project.save!
# full access
project.team << [master, :master]
# readonly
project.team << [reporter, :reporter]
end
describe "Project should be internal" do
subject { project }
its(:internal?) { should be_true }
end
describe "GET /:project_path" do
subject { project_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/tree/master" do
subject { project_tree_path(project, project.repository.root_ref) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/commits/master" do
subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/commit/:sha" do
subject { project_commit_path(project, project.repository.commit) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/compare" do
subject { project_compare_index_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/team" do
subject { project_team_index_path(project) }
it { should be_allowed_for master }
it { should be_denied_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/wall" do
subject { project_wall_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/blob" do
before do
commit = project.repository.commit
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
@blob_path = project_blob_path(project, File.join(commit.id, path))
end
it { @blob_path.should be_allowed_for master }
it { @blob_path.should be_allowed_for reporter }
it { @blob_path.should be_allowed_for :admin }
it { @blob_path.should be_allowed_for guest }
it { @blob_path.should be_allowed_for :user }
it { @blob_path.should be_denied_for :visitor }
end
describe "GET /:project_path/edit" do
subject { edit_project_path(project) }
it { should be_allowed_for master }
it { should be_denied_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/deploy_keys" do
subject { project_deploy_keys_path(project) }
it { should be_allowed_for master }
it { should be_denied_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/issues" do
subject { project_issues_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/snippets/new" do
subject { new_project_snippet_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/merge_requests" do
subject { project_merge_requests_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/merge_requests/new" do
subject { new_project_merge_request_path(project) }
it { should be_allowed_for master }
it { should be_denied_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/branches/recent" do
subject { recent_project_branches_path(project) }
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/branches" do
subject { project_branches_path(project) }
before do
# Speed increase
Project.any_instance.stub(:branches).and_return([])
end
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/tags" do
subject { project_tags_path(project) }
before do
# Speed increase
Project.any_instance.stub(:tags).and_return([])
end
it { should be_allowed_for master }
it { should be_allowed_for reporter }
it { should be_allowed_for :admin }
it { should be_allowed_for guest }
it { should be_allowed_for :user }
it { should be_denied_for :visitor }
end
describe "GET /:project_path/hooks" do
subject { project_hooks_path(project) }
it { should be_allowed_for master }
it { should be_denied_for reporter }
it { should be_allowed_for :admin }
it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
end
......@@ -15,6 +15,12 @@ describe "Private Project Access" do
project.team << [reporter, :reporter]
end
describe "Project should be private" do
subject { project }
its(:private?) { should be_true }
end
describe "GET /:project_path" do
subject { project_path(project) }
......
......@@ -9,7 +9,7 @@ describe "Public Project Access" do
before do
# public project
project.public = true
project.visibility_level = Gitlab::VisibilityLevel::PUBLIC
project.save!
# full access
......
......@@ -14,13 +14,13 @@
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
# public :boolean default(FALSE), not null
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
# imported :boolean default(FALSE), not null
# import_url :string(255)
# visibility_level :integer default(0), not null
#
require 'spec_helper'
......
......@@ -132,15 +132,45 @@ describe API::API do
end
it "should set a project as public" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC })
post api("/projects", user), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
end
it "should set a project as public using :public" do
project = attributes_for(:project, { public: true })
post api("/projects", user), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
end
it "should set a project as internal" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL })
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as internal overriding :public" do
project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL })
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as private" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
it "should set a project as private using :public" do
project = attributes_for(:project, { public: false })
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
end
......@@ -183,19 +213,46 @@ describe API::API do
end
it "should set a project as public" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
end
it "should set a project as public using :public" do
project = attributes_for(:project, { public: true })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
end
it "should set a project as internal" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as private" do
project = attributes_for(:project, { public: false })
it "should set a project as internal overriding :public" do
project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as private" do
project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
it "should set a project as private using :public" do
project = attributes_for(:project, { public: false })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
end
end
describe "GET /projects/:id" do
......@@ -649,10 +706,10 @@ describe API::API do
describe :fork_admin do
let(:project_fork_target) { create(:project) }
let(:project_fork_source) { create(:project, public: true) }
let(:project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
describe "POST /projects/:id/fork/:forked_from_id" do
let(:new_project_fork_source) { create(:project, public: true) }
let(:new_project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
it "shouldn't available for non admin users" do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
......@@ -721,8 +778,10 @@ describe API::API do
let!(:post) { create(:project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
let!(:pre_post) { create(:project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
let!(:unfound) { create(:project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
let!(:public) { create(:project, name: "another #{query}",public: true) }
let!(:unfound_public) { create(:project, name: 'unfound public', public: true) }
let!(:internal) { create(:project, name: "internal #{query}", visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
let!(:unfound_internal) { create(:project, name: 'unfound internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
let!(:public) { create(:project, name: "public #{query}", visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let!(:unfound_public) { create(:project, name: 'unfound public', visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
context "when unauthenticated" do
it "should return authentication error" do
......@@ -736,7 +795,7 @@ describe API::API do
get api("/projects/search/#{query}",user)
response.status.should == 200
json_response.should be_an Array
json_response.size.should == 5
json_response.size.should == 6
json_response.each {|project| project['name'].should =~ /.*query.*/}
end
end
......@@ -746,8 +805,8 @@ describe API::API do
get api("/projects/search/#{query}", user2)
response.status.should == 200
json_response.should be_an Array
json_response.size.should == 1
json_response.first['name'].should == "another #{query}"
json_response.size.should == 2
json_response.each {|project| project['name'].should =~ /(internal|public) query/}
end
end
end
......
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