projects.rb 11.2 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 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

        def filter_projects(projects)
          # If the archived parameter is passed, limit results accordingly
          if params[:archived].present?
            projects = projects.where(archived: parse_boolean(params[:archived]))
          end

          if params[:search].present?
            projects = projects.search(params[:search])
          end

          projects.reorder(project_order_by => project_sort)
        end

        def project_order_by
          order_fields = %w(id name path created_at updated_at last_activity_at)

          if order_fields.include?(params['order_by'])
            params['order_by']
          else
            'created_at'
          end
        end

        def project_sort
          if params["sort"] == 'asc'
            :asc
          else
            :desc
          end
        end
45 46
      end

N
Nihad Abbasov 已提交
47 48 49 50 51
      # Get a projects list for authenticated user
      #
      # Example Request:
      #   GET /projects
      get do
D
Dmitriy Zaporozhets 已提交
52
        @projects = current_user.authorized_projects
53
        @projects = filter_projects(@projects)
D
Dmitriy Zaporozhets 已提交
54
        @projects = paginate @projects
55
        present @projects, with: Entities::Project
N
Nihad Abbasov 已提交
56 57
      end

58 59 60 61 62
      # Get an owned projects list for authenticated user
      #
      # Example Request:
      #   GET /projects/owned
      get '/owned' do
63
        @projects = current_user.owned_projects
64
        @projects = filter_projects(@projects)
65
        @projects = paginate @projects
66 67 68
        present @projects, with: Entities::Project
      end

69 70 71 72 73 74
      # Get all projects for admin user
      #
      # Example Request:
      #   GET /projects/all
      get '/all' do
        authenticated_as_admin!
75 76
        @projects = Project.all
        @projects = filter_projects(@projects)
77
        @projects = paginate @projects
78 79 80
        present @projects, with: Entities::Project
      end

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

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

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

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

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
      # 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

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

243 244 245 246 247 248 249 250
      # 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 已提交
251
        ::Projects::DestroyService.new(user_project, current_user, {}).execute
252
      end
A
Angus MacArthur 已提交
253

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

        projects = case params["order_by"]
303 304 305 306 307
                   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
308 309
                   end

310
        present paginate(projects), with: Entities::Project
311
      end
312 313 314 315 316 317 318 319 320 321


      # 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
322
        present @users, with: Entities::UserBasic
323
      end
N
Nihad Abbasov 已提交
324 325 326
    end
  end
end