summaryrefslogtreecommitdiff
path: root/lib/api/groups.rb
blob: 9b9d3df74359a97aee4dceda1588b92d0a116077 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
module API
  class Groups < Grape::API
    include PaginationParams

    before { authenticate! }

    helpers do
      params :optional_params do
        optional :description, type: String, desc: 'The description of the group'
        optional :visibility_level, type: Integer, desc: 'The visibility level of the group'
        optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group'
        optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
      end
    end

    resource :groups do
      desc 'Get a groups list' do
        success Entities::Group
      end
      params do
        optional :skip_groups, type: Array[Integer], desc: 'Array of group ids to exclude from list'
        optional :all_available, type: Boolean, desc: 'Show all group that you have access to'
        optional :search, type: String, desc: 'Search for a specific group'
        optional :order_by, type: String, values: %w[name path], default: 'name', desc: 'Order by name or path'
        optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)'
        use :pagination
      end
      get do
        groups = if current_user.admin
                   Group.all
                 elsif params[:all_available]
                   GroupsFinder.new.execute(current_user)
                 else
                   current_user.groups
                 end

        groups = groups.search(params[:search]) if params[:search].present?
        groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present?
        groups = groups.reorder(params[:order_by] => params[:sort])

        present paginate(groups), with: Entities::Group
      end

      desc 'Get list of owned groups for authenticated user' do
        success Entities::Group
      end
      params do
        use :pagination
      end
      get '/owned' do
        groups = current_user.owned_groups
        present paginate(groups), with: Entities::Group, user: current_user
      end

      desc 'Create a group. Available only for users who can create groups.' do
        success Entities::Group
      end
      params do
        requires :name, type: String, desc: 'The name of the group'
        requires :path, type: String, desc: 'The path of the group'
        use :optional_params
      end
      post do
        authorize! :create_group

        group = ::Groups::CreateService.new(current_user, declared_params(include_missing: false)).execute

        if group.persisted?
          present group, with: Entities::Group
        else
          render_api_error!("Failed to save group #{group.errors.messages}", 400)
        end
      end
    end

    params do
      requires :id, type: String, desc: 'The ID of a group'
    end
    resource :groups do
      desc 'Update a group. Available only for users who can administrate groups.' do
        success Entities::Group
      end
      params do
        optional :name, type: String, desc: 'The name of the group'
        optional :path, type: String, desc: 'The path of the group'
        use :optional_params
        at_least_one_of :name, :path, :description, :visibility_level,
                        :lfs_enabled, :request_access_enabled
      end
      put ':id' do
        group = find_group!(params[:id])
        authorize! :admin_group, group

        if ::Groups::UpdateService.new(group, current_user, declared_params(include_missing: false)).execute
          present group, with: Entities::GroupDetail
        else
          render_validation_error!(group)
        end
      end

      desc 'Get a single group, with containing projects.' do
        success Entities::GroupDetail
      end
      get ":id" do
        group = find_group!(params[:id])
        present group, with: Entities::GroupDetail
      end

      desc 'Remove a group.'
      delete ":id" do
        group = find_group!(params[:id])
        authorize! :admin_group, group
        DestroyGroupService.new(group, current_user).execute
      end

      desc 'Get a list of projects in this group.' do
        success Entities::Project
      end
      params do
        optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
        optional :visibility, type: String, values: %w[public internal private],
                              desc: 'Limit by visibility'
        optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
        optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at],
                            default: 'created_at', desc: 'Return projects ordered by field'
        optional :sort, type: String, values: %w[asc desc], default: 'desc',
                        desc: 'Return projects sorted in ascending and descending order'
        optional :simple, type: Boolean, default: false,
                          desc: 'Return only the ID, URL, name, and path of each project'
        use :pagination
      end
      get ":id/projects" do
        group = find_group!(params[:id])
        projects = GroupProjectsFinder.new(group).execute(current_user)
        projects = filter_projects(projects)
        entity = params[:simple] ? Entities::BasicProjectDetails : Entities::Project
        present paginate(projects), with: entity, user: current_user
      end

      desc 'Transfer a project to the group namespace. Available only for admin.' do
        success Entities::GroupDetail
      end
      params do
        requires :project_id, type: String, desc: 'The ID of the project'
      end
      post ":id/projects/:project_id" do
        authenticated_as_admin!
        group = Group.find_by(id: params[:id])
        project = Project.find(params[:project_id])
        result = ::Projects::TransferService.new(project, current_user).execute(group)

        if result
          present group, with: Entities::GroupDetail
        else
          render_api_error!("Failed to transfer project #{project.errors.messages}", 400)
        end
      end
    end
  end
end