projects.rb 10.6 KB
Newer Older
1
module API
N
Nihad Abbasov 已提交
2 3 4 5 6
  # Projects API
  class Projects < Grape::API
    before { authenticate! }

    resource :projects do
7 8 9 10 11 12 13
      helpers do
        def handle_project_member_errors(errors)
          if errors[:project_access].any?
            error!(errors[:project_access], 422)
          end
          not_found!
        end
14 15 16 17 18 19 20
        
        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
21 22
      end

N
Nihad Abbasov 已提交
23 24 25 26 27
      # Get a projects list for authenticated user
      #
      # Example Request:
      #   GET /projects
      get do
28
        @projects = paginate current_user.authorized_projects
29
        present @projects, with: Entities::Project
N
Nihad Abbasov 已提交
30 31
      end

32 33 34 35 36 37 38 39 40
      # Get an owned projects list for authenticated user
      #
      # Example Request:
      #   GET /projects/owned
      get '/owned' do
        @projects = paginate current_user.owned_projects
        present @projects, with: Entities::Project
      end

41 42 43 44 45 46 47 48 49 50
      # Get all projects for admin user
      #
      # Example Request:
      #   GET /projects/all
      get '/all' do
        authenticated_as_admin!
        @projects = paginate Project
        present @projects, with: Entities::Project
      end

N
Nihad Abbasov 已提交
51 52 53
      # Get a single project
      #
      # Parameters:
54
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
55 56 57
      # Example Request:
      #   GET /projects/:id
      get ":id" do
58
        present user_project, with: Entities::Project
N
Nihad Abbasov 已提交
59 60
      end

D
Dmitriy Zaporozhets 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74
      # Get a single project events
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request:
      #   GET /projects/:id
      get ":id/events" do
        limit = (params[:per_page] || 20).to_i
        offset = (params[:page] || 0).to_i * limit
        events = user_project.events.recent.limit(limit).offset(offset)

        present events, with: Entities::Event
      end

75 76 77 78
      # Create new project
      #
      # Parameters:
      #   name (required) - name for new project
79
      #   description (optional) - short project description
80 81 82 83
      #   issues_enabled (optional)
      #   wall_enabled (optional)
      #   merge_requests_enabled (optional)
      #   wiki_enabled (optional)
84
      #   snippets_enabled (optional)
85
      #   namespace_id (optional) - defaults to user namespace
86 87
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional) - 0 by default
88 89 90
      # Example Request
      #   POST /projects
      post do
91
        required_attributes! [:name]
92
        attrs = attributes_for_keys [:name,
93 94 95 96 97 98 99 100
                                     :path,
                                     :description,
                                     :issues_enabled,
                                     :wall_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
                                     :namespace_id,
101 102 103
                                     :public,
                                     :visibility_level]
        attrs = map_public_to_visibility_level(attrs)
104
        @project = ::Projects::CreateContext.new(current_user, attrs).execute
105 106 107
        if @project.saved?
          present @project, with: Entities::Project
        else
108 109 110
          if @project.errors[:limit_reached].present?
            error!(@project.errors[:limit_reached], 403)
          end
111
          not_found!
112 113 114
        end
      end

A
Angus MacArthur 已提交
115 116 117 118 119 120 121
      # Create new project for a specified user.  Only available to admin users.
      #
      # Parameters:
      #   user_id (required) - The ID of a user
      #   name (required) - name for new project
      #   description (optional) - short project description
      #   default_branch (optional) - 'master' by default
122 123 124
      #   issues_enabled (optional)
      #   wall_enabled (optional)
      #   merge_requests_enabled (optional)
125 126
      #   wiki_enabled (optional)
      #   snippets_enabled (optional)
127 128
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional)
A
Angus MacArthur 已提交
129 130 131 132 133 134
      # Example Request
      #   POST /projects/user/:user_id
      post "user/:user_id" do
        authenticated_as_admin!
        user = User.find(params[:user_id])
        attrs = attributes_for_keys [:name,
135 136 137 138 139 140 141
                                     :description,
                                     :default_branch,
                                     :issues_enabled,
                                     :wall_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
142 143 144
                                     :public,
                                     :visibility_level]
        attrs = map_public_to_visibility_level(attrs)
A
Angus MacArthur 已提交
145 146 147 148 149 150 151 152
        @project = ::Projects::CreateContext.new(user, attrs).execute
        if @project.saved?
          present @project, with: Entities::Project
        else
          not_found!
        end
      end

153 154 155 156 157 158 159 160 161 162
      # Remove project
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request:
      #   DELETE /projects/:id
      delete ":id" do
        authorize! :remove_project, user_project
        user_project.destroy
      end
A
Angus MacArthur 已提交
163

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
      # Mark this project as forked from another
      #
      # Parameters:
      #   id: (required) - The ID of the project being marked as a fork
      #   forked_from_id: (required) - The ID of the project it was forked from
      # Example Request:
      #   POST /projects/:id/fork/:forked_from_id
      post ":id/fork/:forked_from_id" do
        authenticated_as_admin!
        forked_from_project = find_project(params[:forked_from_id])
        unless forked_from_project.nil?
          if user_project.forked_from_project.nil?
            user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id)
          else
            render_api_error!("Project already forked", 409)
          end
        else
          not_found!
        end

      end

      # Remove a forked_from relationship
      #
      # Parameters:
      # id: (required) - The ID of the project being marked as a fork
      # Example Request:
      #  DELETE /projects/:id/fork
      delete ":id/fork" do
        authenticated_as_admin!
        unless user_project.forked_project_link.nil?
          user_project.forked_project_link.destroy
        end
      end

N
Nihad Abbasov 已提交
199
      # Get a project team members
M
miks 已提交
200 201
      #
      # Parameters:
202
      #   id (required) - The ID of a project
V
Valeriy Sizov 已提交
203
      #   query         - Query string
M
miks 已提交
204
      # Example Request:
N
Nihad Abbasov 已提交
205 206
      #   GET /projects/:id/members
      get ":id/members" do
V
Valeriy Sizov 已提交
207 208 209 210 211
        if params[:query].present?
          @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%")
        else
          @members = paginate user_project.users
        end
N
Nihad Abbasov 已提交
212
        present @members, with: Entities::ProjectMember, project: user_project
M
miks 已提交
213 214
      end

N
Nihad Abbasov 已提交
215
      # Get a project team members
216 217
      #
      # Parameters:
218
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
219
      #   user_id (required) - The ID of a user
220
      # Example Request:
N
Nihad Abbasov 已提交
221 222 223 224 225 226 227 228 229
      #   GET /projects/:id/members/:user_id
      get ":id/members/:user_id" do
        @member = user_project.users.find params[:user_id]
        present @member, with: Entities::ProjectMember, project: user_project
      end

      # Add a new project team member
      #
      # Parameters:
230
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
231 232 233 234 235
      #   user_id (required) - The ID of a user
      #   access_level (required) - Project access level
      # Example Request:
      #   POST /projects/:id/members
      post ":id/members" do
R
randx 已提交
236
        authorize! :admin_project, user_project
237
        required_attributes! [:user_id, :access_level]
238 239 240 241 242 243 244 245 246 247 248 249

        # either the user is already a team member or a new one
        team_member = user_project.team_member_by_id(params[:user_id])
        if team_member.nil?
          team_member = user_project.users_projects.new(
            user_id: params[:user_id],
            project_access: params[:access_level]
          )
        end

        if team_member.save
          @member = team_member.user
N
Nihad Abbasov 已提交
250 251
          present @member, with: Entities::ProjectMember, project: user_project
        else
252
          handle_project_member_errors team_member.errors
N
Nihad Abbasov 已提交
253
        end
254 255
      end

N
Nihad Abbasov 已提交
256
      # Update project team member
M
miks 已提交
257 258
      #
      # Parameters:
259
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
260 261
      #   user_id (required) - The ID of a team member
      #   access_level (required) - Project access level
M
miks 已提交
262
      # Example Request:
N
Nihad Abbasov 已提交
263 264
      #   PUT /projects/:id/members/:user_id
      put ":id/members/:user_id" do
R
randx 已提交
265
        authorize! :admin_project, user_project
266
        required_attributes! [:access_level]
N
Nihad Abbasov 已提交
267

268
        team_member = user_project.users_projects.find_by_user_id(params[:user_id])
269
        not_found!("User can not be found") if team_member.nil?
270 271 272

        if team_member.update_attributes(project_access: params[:access_level])
          @member = team_member.user
N
Nihad Abbasov 已提交
273 274
          present @member, with: Entities::ProjectMember, project: user_project
        else
275
          handle_project_member_errors team_member.errors
N
Nihad Abbasov 已提交
276
        end
M
miks 已提交
277 278
      end

N
Nihad Abbasov 已提交
279
      # Remove a team member from project
M
miks 已提交
280 281
      #
      # Parameters:
282
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
283
      #   user_id (required) - The ID of a team member
M
miks 已提交
284
      # Example Request:
N
Nihad Abbasov 已提交
285 286
      #   DELETE /projects/:id/members/:user_id
      delete ":id/members/:user_id" do
R
randx 已提交
287
        authorize! :admin_project, user_project
288 289 290
        team_member = user_project.users_projects.find_by_user_id(params[:user_id])
        unless team_member.nil?
          team_member.destroy
291
        else
292
          {message: "Access revoked", id: params[:user_id].to_i}
293
        end
M
miks 已提交
294
      end
295 296 297 298 299

      # search for projects current_user has access to
      #
      # Parameters:
      #   query (required) - A string contained in the project name
300 301
      #   per_page (optional) - number of projects to return per page
      #   page (optional) - the page to retrieve
302 303 304 305
      # Example Request:
      #   GET /projects/search/:query
      get "/search/:query" do
        ids = current_user.authorized_projects.map(&:id)
306 307
        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]}%")
308
        present paginate(projects), with: Entities::Project
309
      end
N
Nihad Abbasov 已提交
310 311 312
    end
  end
end