diff options
Diffstat (limited to 'lib/api')
| -rw-r--r-- | lib/api/commits.rb | 2 | ||||
| -rw-r--r-- | lib/api/entities.rb | 10 | ||||
| -rw-r--r-- | lib/api/features.rb | 39 | ||||
| -rw-r--r-- | lib/api/helpers/runner.rb | 3 | ||||
| -rw-r--r-- | lib/api/namespaces.rb | 2 | ||||
| -rw-r--r-- | lib/api/projects.rb | 4 | ||||
| -rw-r--r-- | lib/api/users.rb | 29 |
7 files changed, 70 insertions, 19 deletions
diff --git a/lib/api/commits.rb b/lib/api/commits.rb index c6fc17cc391..bcb842b9211 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -67,7 +67,7 @@ module API result = ::Files::MultiService.new(user_project, current_user, attrs).execute if result[:status] == :success - commit_detail = user_project.repository.commits(result[:result], limit: 1).first + commit_detail = user_project.repository.commit(result[:result]) present commit_detail, with: Entities::RepoCommitDetail else render_api_error!(result[:message], 400) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index aa91451c9f4..cef5a0abe12 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -444,7 +444,15 @@ module API end class Namespace < Grape::Entity - expose :id, :name, :path, :kind, :full_path + expose :id, :name, :path, :kind, :full_path, :parent_id + + expose :members_count_with_descendants, if: -> (namespace, opts) { expose_members_count_with_descendants?(namespace, opts) } do |namespace, _| + namespace.users_with_descendants.count + end + + def expose_members_count_with_descendants?(namespace, opts) + namespace.kind == 'group' && Ability.allowed?(opts[:current_user], :admin_group, namespace) + end end class MemberAccess < Grape::Entity diff --git a/lib/api/features.rb b/lib/api/features.rb index cff0ba2ddff..21745916463 100644 --- a/lib/api/features.rb +++ b/lib/api/features.rb @@ -2,6 +2,29 @@ module API class Features < Grape::API before { authenticated_as_admin! } + helpers do + def gate_value(params) + case params[:value] + when 'true' + true + when '0', 'false' + false + else + params[:value].to_i + end + end + + def gate_target(params) + if params[:feature_group] + Feature.group(params[:feature_group]) + elsif params[:user] + User.find_by_username(params[:user]) + else + gate_value(params) + end + end + end + resource :features do desc 'Get a list of all features' do success Entities::Feature @@ -17,16 +40,22 @@ module API end params do requires :value, type: String, desc: '`true` or `false` to enable/disable, an integer for percentage of time' + optional :feature_group, type: String, desc: 'A Feature group name' + optional :user, type: String, desc: 'A GitLab username' + mutually_exclusive :feature_group, :user end post ':name' do feature = Feature.get(params[:name]) + target = gate_target(params) + value = gate_value(params) - if %w(0 false).include?(params[:value]) - feature.disable - elsif params[:value] == 'true' - feature.enable + case value + when true + feature.enable(target) + when false + feature.disable(target) else - feature.enable_percentage_of_time(params[:value].to_i) + feature.enable_percentage_of_time(value) end present feature, with: Entities::Feature, current_user: current_user diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb index 1369b021ea4..f8645e364ce 100644 --- a/lib/api/helpers/runner.rb +++ b/lib/api/helpers/runner.rb @@ -46,7 +46,8 @@ module API yield if block_given? - forbidden!('Project has been deleted!') unless job.project + project = job.project + forbidden!('Project has been deleted!') if project.nil? || project.pending_delete? forbidden!('Job has been erased!') if job.erased? end diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb index 30761cb9b55..f1eaff6b0eb 100644 --- a/lib/api/namespaces.rb +++ b/lib/api/namespaces.rb @@ -17,7 +17,7 @@ module API namespaces = namespaces.search(params[:search]) if params[:search].present? - present paginate(namespaces), with: Entities::Namespace + present paginate(namespaces), with: Entities::Namespace, current_user: current_user end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index c5df45b7902..d0bd64b2972 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -1,3 +1,5 @@ +require_dependency 'declarative_policy' + module API # Projects API class Projects < Grape::API @@ -396,7 +398,7 @@ module API use :pagination end get ':id/users' do - users = user_project.team.users + users = DeclarativePolicy.subject_scope { user_project.team.users } users = users.search(params[:search]) if params[:search].present? present paginate(users), with: Entities::UserBasic diff --git a/lib/api/users.rb b/lib/api/users.rb index 2cac8c089f2..88bca235692 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -5,11 +5,11 @@ module API allow_access_with_scope :read_user, if: -> (request) { request.get? } - before do - authenticate! - end - resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do + before do + authenticate_non_get! + end + helpers do def find_user(params) id = params[:user_id] || params[:id] @@ -53,15 +53,22 @@ module API use :pagination end get do - unless can?(current_user, :read_users_list) - render_api_error!("Not authorized.", 403) - end - authenticated_as_admin! if params[:external].present? || (params[:extern_uid].present? && params[:provider].present?) users = UsersFinder.new(current_user, params).execute - entity = current_user.admin? ? Entities::UserWithAdmin : Entities::UserBasic + authorized = can?(current_user, :read_users_list) + + # When `current_user` is not present, require that the `username` + # parameter is passed, to prevent an unauthenticated user from accessing + # a list of all the users on the GitLab instance. `UsersFinder` performs + # an exact match on the `username` parameter, so we are guaranteed to + # get either 0 or 1 `users` here. + authorized &&= params[:username].present? if current_user.blank? + + forbidden!("Not authorized to access /api/v4/users") unless authorized + + entity = current_user&.admin? ? Entities::UserWithAdmin : Entities::UserBasic present paginate(users), with: entity end @@ -400,6 +407,10 @@ module API end resource :user do + before do + authenticate! + end + desc 'Get the currently authenticated user' do success Entities::UserPublic end |
