projects.rb 10.3 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
        @projects = filter_projects(@projects)
D
Dmitriy Zaporozhets 已提交
23
        @projects = paginate @projects
24
        present @projects, with: Entities::Project
N
Nihad Abbasov 已提交
25 26
      end

27 28 29 30 31
      # Get an owned projects list for authenticated user
      #
      # Example Request:
      #   GET /projects/owned
      get '/owned' do
32
        @projects = current_user.owned_projects
33
        @projects = filter_projects(@projects)
34
        @projects = paginate @projects
35 36 37
        present @projects, with: Entities::Project
      end

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

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

60
      # Get events for a single project
D
Dmitriy Zaporozhets 已提交
61 62 63 64
      #
      # Parameters:
      #   id (required) - The ID of a project
      # Example Request:
C
Ciro Santilli 已提交
65
      #   GET /projects/:id/events
D
Dmitriy Zaporozhets 已提交
66
      get ":id/events" do
67
        events = paginate user_project.events.recent
D
Dmitriy Zaporozhets 已提交
68 69 70
        present events, with: Entities::Event
      end

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

A
Angus MacArthur 已提交
111 112 113 114 115 116 117
      # 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
118 119
      #   issues_enabled (optional)
      #   merge_requests_enabled (optional)
120 121
      #   wiki_enabled (optional)
      #   snippets_enabled (optional)
122 123
      #   public (optional) - if true same as setting visibility_level = 20
      #   visibility_level (optional)
124
      #   import_url (optional)
A
Angus MacArthur 已提交
125 126 127 128 129 130
      # 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,
131 132 133 134 135 136
                                     :description,
                                     :default_branch,
                                     :issues_enabled,
                                     :merge_requests_enabled,
                                     :wiki_enabled,
                                     :snippets_enabled,
137
                                     :public,
138 139
                                     :visibility_level,
                                     :import_url]
140
        attrs = map_public_to_visibility_level(attrs)
141
        @project = ::Projects::CreateService.new(user, attrs).execute
A
Angus MacArthur 已提交
142 143 144
        if @project.saved?
          present @project, with: Entities::Project
        else
J
jubianchi 已提交
145
          render_validation_error!(@project)
A
Angus MacArthur 已提交
146 147 148
        end
      end

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
      # 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

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 199 200 201
      # 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

202
        if user_project.errors.any?
203
          render_validation_error!(user_project)
204 205
        else
          present user_project, with: Entities::Project
206 207 208
        end
      end

209 210 211 212 213 214 215 216
      # 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 已提交
217
        ::Projects::DestroyService.new(user_project, current_user, {}).execute
218
      end
A
Angus MacArthur 已提交
219

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
      # 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
237
          not_found!("Source Project")
238 239 240 241 242 243 244 245 246 247 248
        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
249
        authorize! :remove_fork_project, user_project
250
        if user_project.forked?
251 252 253
          user_project.forked_project_link.destroy
        end
      end
254 255 256 257
      # search for projects current_user has access to
      #
      # Parameters:
      #   query (required) - A string contained in the project name
258 259
      #   per_page (optional) - number of projects to return per page
      #   page (optional) - the page to retrieve
260 261 262 263
      # Example Request:
      #   GET /projects/search/:query
      get "/search/:query" do
        ids = current_user.authorized_projects.map(&:id)
264 265
        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]}%")
266
        sort = params[:sort] == 'desc' ? 'desc' : 'asc'
267 268

        projects = case params["order_by"]
269 270 271 272 273
                   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
274 275
                   end

276
        present paginate(projects), with: Entities::Project
277
      end
278 279 280 281 282 283 284 285 286 287


      # 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
288
        present @users, with: Entities::UserBasic
289
      end
N
Nihad Abbasov 已提交
290 291 292
    end
  end
end