Skip to content
Snippets Groups Projects
Commit 8db12921 authored by Douwe Maan's avatar Douwe Maan
Browse files

Tweaks, refactoring, and specs

parent 2eb19ea3
No related branches found
No related tags found
No related merge requests found
Showing
with 196 additions and 272 deletions
Loading
Loading
@@ -48,7 +48,7 @@
display: block;
}
 
#project-home-desc {
.project-home-desc {
font-size: 21px;
}
 
Loading
Loading
Loading
Loading
@@ -25,7 +25,6 @@ class ApplicationController < ActionController::Base
 
helper_method :abilities, :can?, :current_application_settings
helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
helper_method :repository, :can_collaborate_with_project?
 
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
Loading
Loading
@@ -118,47 +117,6 @@ class ApplicationController < ActionController::Base
abilities.allowed?(object, action, subject)
end
 
def project
unless @project
namespace = params[:namespace_id]
id = params[:project_id] || params[:id]
# Redirect from
# localhost/group/project.git
# to
# localhost/group/project
#
if id =~ /\.git\Z/
redirect_to request.original_url.gsub(/\.git\/?\Z/, '') and return
end
project_path = "#{namespace}/#{id}"
@project = Project.find_with_namespace(project_path)
if @project and can?(current_user, :read_project, @project)
if @project.path_with_namespace != project_path
redirect_to request.original_url.gsub(project_path, @project.path_with_namespace) and return
end
@project
elsif current_user.nil?
@project = nil
authenticate_user!
else
@project = nil
render_404 and return
end
end
@project
end
def repository
@repository ||= project.repository
end
def authorize_project!(action)
return access_denied! unless can?(current_user, action, project)
end
def access_denied!
render "errors/access_denied", layout: "errors", status: 404
end
Loading
Loading
@@ -167,14 +125,6 @@ class ApplicationController < ActionController::Base
render "errors/git_not_found.html", layout: "errors", status: 404
end
 
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /\Aauthorize_(.*)!\z/
authorize_project!($1.to_sym)
else
super
end
end
def render_403
head :forbidden
end
Loading
Loading
@@ -183,10 +133,6 @@ class ApplicationController < ActionController::Base
render file: Rails.root.join("public", "404"), layout: false, status: "404"
end
 
def require_non_empty_project
redirect_to @project if @project.empty_repo?
end
def no_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
Loading
Loading
@@ -412,13 +358,6 @@ class ApplicationController < ActionController::Base
current_user.nil? && root_path == request.path
end
 
def can_collaborate_with_project?(project = nil)
project ||= @project
can?(current_user, :push_code, project) ||
(current_user && current_user.already_forked?(project))
end
private
 
def set_default_sort
Loading
Loading
class Groups::ApplicationController < ApplicationController
layout 'group'
skip_before_action :authenticate_user!
before_action :group
 
private
 
def group
@group ||= Group.find_by(path: params[:group_id])
end
unless @group
id = params[:group_id] || params[:id]
@group = Group.find_by(path: id)
unless @group && can?(current_user, :read_group, @group)
@group = nil
 
def authorize_read_group!
unless @group && can?(current_user, :read_group, @group)
if current_user.nil?
return authenticate_user!
else
return render_404
if current_user.nil?
authenticate_user!
else
render_404
end
end
end
@group
end
def group_projects
@projects ||= GroupProjectsFinder.new(group).execute(current_user)
end
 
def authorize_admin_group!
Loading
Loading
class Groups::AvatarsController < Groups::ApplicationController
before_action :authorize_admin_group!
def destroy
@group.remove_avatar!
@group.save
Loading
Loading
class Groups::GroupMembersController < Groups::ApplicationController
skip_before_action :authenticate_user!, only: [:index]
# Authorize
before_action :authorize_read_group!
before_action :authorize_admin_group_member!, except: [:index, :leave]
 
def index
Loading
Loading
class Groups::MilestonesController < Groups::ApplicationController
include GlobalMilestones
 
before_action :projects
before_action :group_projects
before_action :milestones, only: [:index]
before_action :milestone, only: [:show, :update]
before_action :authorize_group_milestone!, only: [:create, :update]
before_action :authorize_admin_milestones!, only: [:new, :create, :update]
 
def index
end
Loading
Loading
@@ -17,7 +17,7 @@ class Groups::MilestonesController < Groups::ApplicationController
project_ids = params[:milestone][:project_ids]
title = milestone_params[:title]
 
@group.projects.where(id: project_ids).each do |project|
@projects.where(id: project_ids).each do |project|
Milestones::CreateService.new(project, current_user, milestone_params).execute
end
 
Loading
Loading
@@ -37,7 +37,7 @@ class Groups::MilestonesController < Groups::ApplicationController
 
private
 
def authorize_group_milestone!
def authorize_admin_milestones!
return render_404 unless can?(current_user, :admin_milestones, group)
end
 
Loading
Loading
@@ -48,8 +48,4 @@ class Groups::MilestonesController < Groups::ApplicationController
def milestone_path(title)
group_milestone_path(@group, title.to_slug.to_s, title: title)
end
def projects
@projects ||= @group.projects
end
end
Loading
Loading
@@ -5,16 +5,15 @@ class GroupsController < Groups::ApplicationController
 
respond_to :html
 
skip_before_action :authenticate_user!, only: [:index, :show, :issues, :merge_requests]
before_action :authenticate_user!, only: [:new, :create]
before_action :group, except: [:index, :new, :create]
 
# Authorize
before_action :authorize_read_group!, except: [:index, :new, :create]
before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects]
before_action :authorize_create_group!, only: [:new, :create]
 
# Load group projects
before_action :load_projects, except: [:index, :new, :create, :projects, :edit, :update, :autocomplete]
before_action :group_projects, only: [:show, :projects, :activity, :issues, :merge_requests]
before_action :event_filter, only: [:activity]
 
layout :determine_layout
Loading
Loading
@@ -39,12 +38,13 @@ class GroupsController < Groups::ApplicationController
 
def show
@last_push = current_user.recent_push if current_user
@projects = @projects.includes(:namespace)
@projects = filter_projects(@projects)
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.page(params[:page]).per(PER_PAGE) if params[:filter_projects].blank?
 
@shared_projects = @group.shared_projects
@shared_projects = GroupProjectsFinder.new(group, shared: true).execute(current_user)
 
respond_to do |format|
format.html
Loading
Loading
@@ -77,7 +77,7 @@ class GroupsController < Groups::ApplicationController
end
 
def projects
@projects = @group.projects.page(params[:page])
@projects = @projects.sorted_by_activity.page(params[:page])
end
 
def update
Loading
Loading
@@ -96,15 +96,6 @@ class GroupsController < Groups::ApplicationController
 
protected
 
def group
@group ||= Group.find_by(path: params[:id])
@group || render_404
end
def load_projects
@projects ||= ProjectsFinder.new.execute(current_user, group: group).sorted_by_activity
end
def authorize_create_group!
unless can?(current_user, :create_group, nil)
return render_404
Loading
Loading
class Projects::ApplicationController < ApplicationController
before_action :project
before_action :repository
skip_before_action :authenticate_user!
before_action :project, :repository
layout 'project'
 
def authenticate_user!
# Restrict access to Projects area only
# for non-signed users
if !current_user
helper_method :repository, :can_collaborate_with_project?
private
def project
unless @project
namespace = params[:namespace_id]
id = params[:project_id] || params[:id]
project_with_namespace = "#{params[:namespace_id]}/#{id}"
@project = Project.find_with_namespace(project_with_namespace)
 
return if @project && @project.public?
# Redirect from
# localhost/group/project.git
# to
# localhost/group/project
#
if id =~ /\.git\Z/
redirect_to request.original_url.gsub(/\.git\/?\Z/, '')
return
end
project_path = "#{namespace}/#{id}"
@project = Project.find_with_namespace(project_path)
if @project && can?(current_user, :read_project, @project)
if @project.path_with_namespace != project_path
redirect_to request.original_url.gsub(project_path, @project.path_with_namespace)
end
else
@project = nil
if current_user.nil?
authenticate_user!
else
render_404
end
end
end
@project
end
def repository
@repository ||= project.repository
end
def can_collaborate_with_project?(project = nil)
project ||= @project
can?(current_user, :push_code, project) ||
(current_user && current_user.already_forked?(project))
end
def authorize_project!(action)
return access_denied! unless can?(current_user, action, project)
end
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /\Aauthorize_(.*)!\z/
authorize_project!($1.to_sym)
else
super
end
end
 
super
def require_non_empty_project
redirect_to @project if @project.empty_repo?
end
 
def require_branch_head
Loading
Loading
@@ -26,8 +79,6 @@ class Projects::ApplicationController < ApplicationController
end
end
 
private
def apply_diff_view_cookie!
view = params[:view] || cookies[:diff_view]
cookies.permanent[:diff_view] = params[:view] = view if view
Loading
Loading
class Projects::AvatarsController < Projects::ApplicationController
include BlobHelper
 
before_action :project
before_action :authorize_admin_project!, only: [:destroy]
 
def show
@blob = @repository.blob_at_branch('master', @project.avatar_in_git)
Loading
Loading
class Projects::UploadsController < Projects::ApplicationController
skip_before_action :authenticate_user!, :reject_blocked!, :project,
skip_before_action :reject_blocked!, :project,
:repository, if: -> { action_name == 'show' && image? }
 
before_action :authenticate_user!, only: [:create]
def create
link_to_file = ::Projects::UploadService.new(project, params[:file]).
execute
Loading
Loading
@@ -26,6 +28,8 @@ class Projects::UploadsController < Projects::ApplicationController
send_file uploader.file.path, disposition: disposition
end
 
private
def uploader
return @uploader if defined?(@uploader)
 
Loading
Loading
class ProjectsController < ApplicationController
class ProjectsController < Projects::ApplicationController
include ExtractsPath
 
skip_before_action :authenticate_user!, only: [:show, :activity]
before_action :authenticate_user!, except: [:show, :activity]
before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create]
before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists?
Loading
Loading
class ContributedProjectsFinder
class ContributedProjectsFinder < UnionFinder
def initialize(user)
@user = user
end
Loading
Loading
@@ -10,27 +10,20 @@ class ContributedProjectsFinder
# visible by this user.
#
# Returns an ActiveRecord::Relation.
def execute(current_user = nil)
if current_user
relation = projects_visible_to_user(current_user)
else
relation = public_projects
end
segments = all_projects(current_user)
 
relation.includes(:namespace).order_id_desc
find_union(segments, Project).includes(:namespace).order_id_desc
end
 
private
 
def projects_visible_to_user(current_user)
authorized = @user.contributed_projects.visible_to_user(current_user)
union = Gitlab::SQL::Union.new([authorized.select(:id), public_projects.select(:id)])
def all_projects(current_user)
projects = []
 
Project.where("projects.id IN (#{union.to_sql})")
end
projects << @user.contributed_projects.visible_to_user(current_user) if current_user
projects << @user.contributed_projects.public_to_user(current_user)
 
def public_projects
@user.contributed_projects.public_only
projects
end
end
class GroupProjectsFinder < UnionFinder
def initialize(group, options = {})
@group = group
@options = options
end
def execute(current_user = nil)
segments = group_projects(current_user)
find_union(segments, Project)
end
private
def group_projects(current_user)
include_owned = @options.fetch(:owned, true)
include_shared = @options.fetch(:shared, true)
projects = []
if current_user
if @group.users.include?(current_user)
projects << @group.projects if include_owned
projects << @group.shared_projects if include_shared
else
if include_owned
projects << @group.projects.visible_to_user(current_user)
projects << @group.projects.public_to_user(current_user)
end
if include_shared
projects << @group.shared_projects.visible_to_user(current_user)
projects << @group.shared_projects.public_to_user(current_user)
end
end
else
projects << @group.projects.public_only if include_owned
projects << @group.shared_projects.public_only if include_shared
end
projects
end
end
class GroupsFinder
class GroupsFinder < UnionFinder
def execute(current_user = nil)
segments = all_groups(current_user)
 
if segments.length > 1
union = Gitlab::SQL::Union.new(segments.map { |s| s.select(:id) })
Group.where("namespaces.id IN (#{union.to_sql})").order_id_desc
else
segments.first
end
find_union(segments, Group).order_id_desc
end
 
private
 
def all_groups(current_user)
if current_user
user_groups(current_user)
else
[Group.unscoped.public_only]
end
end
groups = []
groups << current_user.authorized_groups if current_user
groups << Group.unscoped.public_to_user(current_user)
 
def user_groups(current_user)
if current_user.external?
[current_user.authorized_groups, Group.unscoped.public_only]
else
[current_user.authorized_groups, Group.unscoped.public_and_internal_only]
end
groups
end
end
Loading
Loading
@@ -81,7 +81,7 @@ class IssuableFinder
elsif current_user && params[:authorized_only].presence && !current_user_related?
@projects = current_user.authorized_projects.reorder(nil)
else
@projects = ProjectsFinder.new.execute(current_user, group: group).
@projects = GroupProjectsFinder.new(group).execute(current_user).
reorder(nil)
end
end
Loading
Loading
@@ -170,7 +170,7 @@ class IssuableFinder
end
 
def by_scope(items)
case params[:scope]
case params[:scope] || 'all'
when 'created-by-me', 'authored' then
items.where(author_id: current_user.id)
when 'all' then
Loading
Loading
#Shows only authorized groups of a user
class JoinedGroupsFinder
class JoinedGroupsFinder < UnionFinder
def initialize(user)
@user = user
end
Loading
Loading
@@ -12,34 +11,19 @@ class JoinedGroupsFinder
#
# Returns an ActiveRecord::Relation.
def execute(current_user = nil)
if current_user
relation = groups_visible_to_user(current_user)
else
relation = public_groups
end
segments = all_groups(current_user)
 
relation.order_id_desc
find_union(segments, Group).order_id_desc
end
 
private
 
# Returns the groups the user in "current_user" can see.
#
# This list includes all public/internal projects as well as the projects of
# "@user" that "current_user" also has access to.
def groups_visible_to_user(current_user)
base = @user.authorized_groups.visible_to_user(current_user)
extra = current_user.external? ? public_groups : public_and_internal_groups
union = Gitlab::SQL::Union.new([base.select(:id), extra.select(:id)])
Group.where("namespaces.id IN (#{union.to_sql})")
end
def all_groups(current_user)
groups = []
 
def public_groups
@user.authorized_groups.public_only
end
groups << @user.authorized_groups.visible_to_user(current_user) if current_user
groups << @user.authorized_groups.public_to_user(current_user)
 
def public_and_internal_groups
@user.authorized_groups.public_and_internal_only
groups
end
end
class PersonalProjectsFinder
class PersonalProjectsFinder < UnionFinder
def initialize(user)
@user = user
end
Loading
Loading
@@ -11,38 +11,19 @@ class PersonalProjectsFinder
#
# Returns an ActiveRecord::Relation.
def execute(current_user = nil)
if current_user
relation = projects_visible_to_user(current_user)
else
relation = public_projects
end
segments = all_projects(current_user)
 
relation.includes(:namespace).order_id_desc
find_union(segments, Project).includes(:namespace).order_id_desc
end
 
private
 
def projects_visible_to_user(current_user)
union = Gitlab::SQL::Union.new(projects_for_user_ids(current_user))
def all_projects(current_user)
projects = []
 
Project.where("projects.id IN (#{union.to_sql})")
end
def public_projects
@user.personal_projects.public_only
end
def public_and_internal_projects
@user.personal_projects.public_and_internal_only
end
def projects_for_user_ids(current_user)
authorized = @user.personal_projects.visible_to_user(current_user)
projects << @user.personal_projects.visible_to_user(current_user) if current_user
projects << @user.personal_projects.public_to_user(current_user)
 
if current_user.external?
[authorized.select(:id), public_projects.select(:id)]
else
[authorized.select(:id), public_and_internal_projects.select(:id)]
end
projects
end
end
class ProjectsFinder
# Returns all projects, optionally including group projects a user has access
# to.
#
# ## Examples
#
# Retrieving all public projects:
#
# ProjectsFinder.new.execute
#
# Retrieving all public/internal projects and those the given user has access
# to:
#
# ProjectsFinder.new.execute(some_user)
#
# Retrieving all public/internal projects as well as the group's projects the
# user has access to:
#
# ProjectsFinder.new.execute(some_user, group: some_group)
#
# Returns an ActiveRecord::Relation.
class ProjectsFinder < UnionFinder
def execute(current_user = nil, options = {})
group = options[:group]
segments = all_projects(current_user)
 
if group
segments = group_projects(current_user, group)
else
segments = all_projects(current_user)
end
if segments.length > 1
union = Gitlab::SQL::Union.new(segments.map { |s| s.select(:id) })
Project.where("projects.id IN (#{union.to_sql})")
else
segments.first
end
find_union(segments, Project)
end
 
private
 
def group_projects(current_user, group)
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
user_group_projects << group.projects.public_and_internal_only
end
end
def all_projects(current_user)
return [public_projects] unless current_user
projects = []
 
if current_user.external?
[current_user.authorized_projects, public_projects]
else
[current_user.authorized_projects, public_and_internal_projects]
end
end
def group_projects_for_user(current_user, group)
if group.users.include?(current_user)
group.projects
else
group.projects.visible_to_user(current_user)
end
end
def public_projects
Project.unscoped.public_only
end
projects << current_user.authorized_projects if current_user
projects << Project.unscoped.public_to_user(current_user)
 
def public_and_internal_projects
Project.unscoped.public_and_internal_only
projects
end
end
class UnionFinder
def find_union(segments, klass)
if segments.length > 1
union = Gitlab::SQL::Union.new(segments.map { |s| s.select(:id) })
klass.where("#{klass.table_name}.id IN (#{union.to_sql})")
else
segments.first
end
end
end
Loading
Loading
@@ -43,8 +43,4 @@ module GroupsHelper
full_title
end
end
def group_visibility_description(group)
"#{visibility_level_label(group.visibility_level)} - #{group_visibility_level_description(group.visibility_level)}"
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment