projects.rb 11.9 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
      helpers do
8 9
        def map_public_to_visibility_level(attrs)
          publik = attrs.delete(:public)
10
          publik = parse_boolean(publik)
11 12 13
          attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true
          attrs
        end
14 15
      end

N
Nihad Abbasov 已提交
16 17 18 19 20
      # Get a projects list for authenticated user
      #
      # Example Request:
      #   GET /projects
      get do
D
Dmitriy Zaporozhets 已提交
21
        @projects = current_user.authorized_projects
22
        sort = params[:sort] == 'desc' ? 'desc' : 'asc'
23 24

        @projects = case params["order_by"]
25 26 27 28 29
                    when 'id' then @projects.reorder("id #{sort}")
                    when 'name' then @projects.reorder("name #{sort}")
                    when 'created_at' then @projects.reorder("created_at #{sort}")
                    when 'last_activity_at' then @projects.reorder("last_activity_at #{sort}")
                    else @projects
30 31
                    end

32 33
        # If the archived parameter is passed, limit results accordingly
        if params[:archived].present?
D
Dmitriy Zaporozhets 已提交
34
          @projects = @projects.where(archived: parse_boolean(params[:archived]))
35
        end
D
Dmitriy Zaporozhets 已提交
36

37 38 39 40
        if params[:search].present?
          @projects = @projects.search(params[:search])
        end

D
Dmitriy Zaporozhets 已提交
41
        @projects = paginate @projects
42
        present @projects, with: Entities::Project
N
Nihad Abbasov 已提交
43 44
      end

45 46 47 48 49
      # Get an owned projects list for authenticated user
      #
      # Example Request:
      #   GET /projects/owned
      get '/owned' do
50
        sort = params[:sort] == 'desc' ? 'desc' : 'asc'
51 52
        @projects = current_user.owned_projects
        @projects = case params["order_by"]
53 54 55 56 57
                    when 'id' then @projects.reorder("id #{sort}")
                    when 'name' then @projects.reorder("name #{sort}")
                    when 'created_at' then @projects.reorder("created_at #{sort}")
                    when 'last_activity_at' then @projects.reorder("last_activity_at #{sort}")
                    else @projects
58 59 60
                    end

        @projects = paginate @projects
61 62 63
        present @projects, with: Entities::Project
      end

64 65 66 67 68 69
      # Get all projects for admin user
      #
      # Example Request:
      #   GET /projects/all
      get '/all' do
        authenticated_as_admin!
70
        sort = params[:sort] == 'desc' ? 'desc' : 'asc'
71 72

        @projects = case params["order_by"]
73 74 75 76 77
                    when 'id' then Project.order("id #{sort}")
                    when 'name' then Project.order("name #{sort}")
                    when 'created_at' then Project.order("created_at #{sort}")
                    when 'last_activity_at' then Project.order("last_activity_at #{sort}")
                    else Project
78 79 80
                    end

        @projects = paginate @projects
81 82 83
        present @projects, with: Entities::Project
      end

N
Nihad Abbasov 已提交
84 85 86
      # Get a single project
      #
      # Parameters:
87
      #   id (required) - The ID of a project
N
Nihad Abbasov 已提交
88 89 90
      # Example Request:
      #   GET /projects/:id
      get ":id" do
91
        present user_project, with: Entities::ProjectWithAccess, user: current_user
N
Nihad Abbasov 已提交
92 93
      end

D
Dmitriy Zaporozhets 已提交
94 95 96 97 98
      # Get a single project events
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request:
C
Ciro Santilli 已提交
99
      #   GET /projects/:id/events
D
Dmitriy Zaporozhets 已提交
100 101 102 103 104 105 106 107
      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

108 109 110 111
      # Create new project
      #
      # Parameters:
      #   name (required) - name for new project
112
      #   description (optional) - short project description
113 114 115
      #   issues_enabled (optional)
      #   merge_requests_enabled (optional)
      #   wiki_enabled (optional)
116
      #   snippets_enabled (optional)
117
      #   namespace_id (optional) - defaults to user namespace
118 119
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional) - 0 by default
120
      #   import_url (optional)
121 122 123
      # Example Request
      #   POST /projects
      post do
124
        required_attributes! [:name]
125
        attrs = attributes_for_keys [:name,
126 127 128 129 130 131 132
                                     :path,
                                     :description,
                                     :issues_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
                                     :namespace_id,
133
                                     :public,
134 135
                                     :visibility_level,
                                     :import_url]
136
        attrs = map_public_to_visibility_level(attrs)
137
        @project = ::Projects::CreateService.new(current_user, attrs).execute
138 139 140
        if @project.saved?
          present @project, with: Entities::Project
        else
141 142 143
          if @project.errors[:limit_reached].present?
            error!(@project.errors[:limit_reached], 403)
          end
J
jubianchi 已提交
144
          render_validation_error!(@project)
145 146 147
        end
      end

A
Angus MacArthur 已提交
148 149 150 151 152 153 154
      # 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
155 156
      #   issues_enabled (optional)
      #   merge_requests_enabled (optional)
157 158
      #   wiki_enabled (optional)
      #   snippets_enabled (optional)
159 160
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional)
161
      #   import_url (optional)
A
Angus MacArthur 已提交
162 163 164 165 166 167
      # 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,
168 169 170 171 172 173
                                     :description,
                                     :default_branch,
                                     :issues_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
174
                                     :public,
175 176
                                     :visibility_level,
                                     :import_url]
177
        attrs = map_public_to_visibility_level(attrs)
178
        @project = ::Projects::CreateService.new(user, attrs).execute
A
Angus MacArthur 已提交
179 180 181
        if @project.saved?
          present @project, with: Entities::Project
        else
J
jubianchi 已提交
182
          render_validation_error!(@project)
A
Angus MacArthur 已提交
183 184 185
        end
      end

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
      # Fork new project for the current user.
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request
      #   POST /projects/fork/:id
      post 'fork/:id' do
        @forked_project =
          ::Projects::ForkService.new(user_project,
                                      current_user).execute
        if @forked_project.errors.any?
          conflict!(@forked_project.errors.messages)
        else
          present @forked_project, with: Entities::Project
        end
      end

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
      # Update an existing project
      #
      # Parameters:
      #   id (required) - the id of a project
      #   name (optional) - name of a project
      #   path (optional) - path of a project
      #   description (optional) - short project description
      #   issues_enabled (optional)
      #   merge_requests_enabled (optional)
      #   wiki_enabled (optional)
      #   snippets_enabled (optional)
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional) - visibility level of a project
      # Example Request
      #   PUT /projects/:id
      put ':id' do
        attrs = attributes_for_keys [:name,
                                     :path,
                                     :description,
                                     :default_branch,
                                     :issues_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
                                     :public,
                                     :visibility_level]
        attrs = map_public_to_visibility_level(attrs)
        authorize_admin_project
        authorize! :rename_project, user_project if attrs[:name].present?
        if attrs[:visibility_level].present?
          authorize! :change_visibility_level, user_project
        end

        ::Projects::UpdateService.new(user_project,
                                      current_user, attrs).execute

        if user_project.valid?
          present user_project, with: Entities::Project
        else
          render_validation_error!(user_project)
        end
      end

246 247 248 249 250 251 252 253
      # Remove project
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request:
      #   DELETE /projects/:id
      delete ":id" do
        authorize! :remove_project, user_project
V
Vinnie Okada 已提交
254
        ::Projects::DestroyService.new(user_project, current_user, {}).execute
255
      end
A
Angus MacArthur 已提交
256

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
      # 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
274
          not_found!("Source Project")
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
        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
291 292 293 294
      # search for projects current_user has access to
      #
      # Parameters:
      #   query (required) - A string contained in the project name
295 296
      #   per_page (optional) - number of projects to return per page
      #   page (optional) - the page to retrieve
297 298 299 300
      # Example Request:
      #   GET /projects/search/:query
      get "/search/:query" do
        ids = current_user.authorized_projects.map(&:id)
301 302
        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]}%")
303
        sort = params[:sort] == 'desc' ? 'desc' : 'asc'
304 305

        projects = case params["order_by"]
306 307 308 309 310
                   when 'id' then projects.order("id #{sort}")
                   when 'name' then projects.order("name #{sort}")
                   when 'created_at' then projects.order("created_at #{sort}")
                   when 'last_activity_at' then projects.order("last_activity_at #{sort}")
                   else projects
311 312
                   end

313
        present paginate(projects), with: Entities::Project
314
      end
315 316 317 318 319 320 321 322 323 324


      # Get a users list
      #
      # Example Request:
      #  GET /users
      get ':id/users' do
        @users = User.where(id: user_project.team.users.map(&:id))
        @users = @users.search(params[:search]) if params[:search].present?
        @users = paginate @users
325
        present @users, with: Entities::UserBasic
326
      end
N
Nihad Abbasov 已提交
327 328 329
    end
  end
end