diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index 4fb6c8759..9170975b5 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -10,4 +10,9 @@ class Api::V1::BaseController < ApplicationController def current_user User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token end + + def require_manager_above + @project = load_project + return render_forbidden unless current_user.admin? && @project.manager?(current_user) + end end \ No newline at end of file diff --git a/app/controllers/api/v1/projects/webhooks_controller.rb b/app/controllers/api/v1/projects/webhooks_controller.rb index bb828a70e..bb2c2172c 100644 --- a/app/controllers/api/v1/projects/webhooks_controller.rb +++ b/app/controllers/api/v1/projects/webhooks_controller.rb @@ -1,5 +1,5 @@ class Api::V1::Projects::WebhooksController < Api::V1::BaseController - before_action :load_project + before_action :require_manager_above before_action :find_webhook, only: [:show, :update, :destroy, :tests, :hooktasks] def index diff --git a/app/controllers/api/v1/users/projects_controller.rb b/app/controllers/api/v1/users/projects_controller.rb index d130071af..ac4b48324 100644 --- a/app/controllers/api/v1/users/projects_controller.rb +++ b/app/controllers/api/v1/users/projects_controller.rb @@ -2,6 +2,12 @@ class Api::V1::Users::ProjectsController < Api::V1::BaseController before_action :load_observe_user def index - @projects = kaminari_paginate(@observe_user.projects) + @object_results = Api::V1::Users::Projects::ListService.call(@observe_user, query_params, current_user) + @projects = kaminari_paginate(@object_results) + end + + private + def query_params + params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search) end end \ No newline at end of file diff --git a/app/services/api/v1/users/projects/list_service.rb b/app/services/api/v1/users/projects/list_service.rb new file mode 100644 index 000000000..32884ac78 --- /dev/null +++ b/app/services/api/v1/users/projects/list_service.rb @@ -0,0 +1,79 @@ +class Api::V1::Users::Projects::ListService < ApplicationService + include ActiveModel::Model + + attr_reader :observe_user, :category, :is_public, :project_type, :sort_by, :sort_direction, :search, :current_user + attr_accessor :queried_projects + + validates :category, inclusion: {in: %w(all join created watched forked), message: "请输入正确的Category"} + validates :is_public, inclusion: {in: [true, false], message: '请输入正确的IsPublic'} + validates :project_type, inclusion: {in: %w(common mirror sync_mirror), message: '请输入正确的ProjectType'}, allow_nil: true + validates :sort_by, inclusion: {in: Project.column_names, message: '请输入正确的SortBy'} + validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'} + + def initialize(observe_user, params, current_user=nil) + @observe_user = observe_user + @category = params[:category] || 'all' + @is_public = params[:is_public] || true + @project_type = params[:project_type] + @sort_by = params[:sort_by] || 'updated_on' + @sort_direction = params[:sort_direction] || 'desc' + @search = params[:search] + @current_user = current_user + end + + def call + raise Error, errors.full_messages.join(", ") unless valid? + # begin + project_query_data + + queried_projects + # rescue + # raise Error, "服务器错误,请联系系统管理员!" + # end + end + + private + def project_query_data + if current_user.admin? + projects = Project + else + projects = Project.visible + end + + case category + when 'join' + normal_projects = projects.where.not(user_id: observe_user.id).members_projects(observe_user.id).to_sql + org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observe_user.id}).to_sql + projects = Project.from("( #{normal_projects} UNION #{org_projects} ) AS projects").distinct + when 'created' + projects = projects.where(user_id: observe_user.id) + when 'watched' + projects = projects.where.not(user_id: observe_user.id).joins(:watchers).where(watchers: {watchable_type: "Project", user_id: observe_user.id}) + when 'forked' + fork_ids = observe_user.fork_users.select(:id, :fork_project_id).pluck(:fork_project_id) + projects = projects.where(id: fork_ids) + else + normal_projects = projects.members_projects(observe_user.id).to_sql + org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: observe_user.id}).to_sql + projects = Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct + end + + if is_public + projects = projects.visible + else + projects = projects.is_private + end + + projects = projects.with_project_type(project_type) + + q = projects.ransack(name_or_identifier_cont: search) + + scope = q.result.includes(:project_category, :project_language,:owner, :repository, :has_pinned_users) + + + scope = scope.order("projects.#{sort_by} #{sort_direction}") + + @queried_projects = scope + end + +end \ No newline at end of file diff --git a/app/views/api/v1/users/projects/index.json.jbuilder b/app/views/api/v1/users/projects/index.json.jbuilder index c126d414f..5450d2dd7 100644 --- a/app/views/api/v1/users/projects/index.json.jbuilder +++ b/app/views/api/v1/users/projects/index.json.jbuilder @@ -1,5 +1,8 @@ json.total_count @projects.total_count json.projects @projects do |project| + json.owner do + json.partial! "api/v1/users/simple_user", user: project.owner + end json.partial! "api/v1/projects/simple_detail", project: project end \ No newline at end of file