From 10c072263b2568a64321439860da039a4f572e31 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 16 Sep 2016 18:38:07 +0100 Subject: Enable Warden for the Grape API The practical effect of this commit is to make the API check the Rails session cookie for authentication details. If the cookie is present and valid, it will be used to authenticate. The API now has several authentication options for users. They follow in this order of precedence: * Authentication token * Personal access token * OAuth2 Bearer token (Doorkeeper - application access) * Rails session cookie --- lib/api/helpers.rb | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 150875ed4f0..714d4ea3dc6 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -12,13 +12,30 @@ module API nil end + def private_token + params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER] + end + + def warden + env['warden'] + end + + # Check the Rails session for valid authentication details + def find_user_from_warden + warden ? warden.authenticate : nil + end + def find_user_by_private_token - token_string = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - User.find_by_authentication_token(token_string) || User.find_by_personal_access_token(token_string) + token = private_token + return nil unless token.present? + + User.find_by_authentication_token(token) || User.find_by_personal_access_token(token) end def current_user - @current_user ||= (find_user_by_private_token || doorkeeper_guard) + @current_user ||= find_user_by_private_token + @current_user ||= doorkeeper_guard + @current_user ||= find_user_from_warden unless @current_user && Gitlab::UserAccess.new(@current_user).allowed? return nil -- cgit v1.2.1 From fd51f19c978023160ad759676a0363c12aea3fc8 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 22 Sep 2016 13:56:43 +0100 Subject: API: disable rails session auth for non-GET/HEAD requests --- lib/api/helpers.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 714d4ea3dc6..8b8c4eb4d46 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -21,8 +21,11 @@ module API end # Check the Rails session for valid authentication details + # + # Until CSRF protection is added to the API, disallow this method for + # state-changing endpoints def find_user_from_warden - warden ? warden.authenticate : nil + warden.try(:authenticate) if request.get? || request.head? end def find_user_by_private_token -- cgit v1.2.1 From 86c0c0869dd4b9de301822a7d598bc4528604e5a Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 30 Sep 2016 12:21:05 +0100 Subject: Switch from request to env in ::API::Helpers Per https://gitlab.com/gitlab-org/gitlab-ce/issues/22820, this helper is mixed in to classes that lack a `request` method. They do include `env`, so use it instead. --- lib/api/helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 8b8c4eb4d46..281a8f13531 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -25,7 +25,7 @@ module API # Until CSRF protection is added to the API, disallow this method for # state-changing endpoints def find_user_from_warden - warden.try(:authenticate) if request.get? || request.head? + warden.try(:authenticate) if %w[GET HEAD].include?(env['REQUEST_METHOD']) end def find_user_by_private_token -- cgit v1.2.1 From fe46e4eb35dd6728a8a5ebcee9cc05a4613effbf Mon Sep 17 00:00:00 2001 From: Justin DiPierro Date: Thu, 29 Sep 2016 12:46:54 -0400 Subject: Load Github::Shell's secret token from file on initialization instead of every request. --- lib/api/helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 8b8c4eb4d46..e3b947adcc3 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -433,7 +433,7 @@ module API end def secret_token - File.read(Gitlab.config.gitlab_shell.secret_file).chomp + Gitlab::Shell.secret_token end def send_git_blob(repository, blob) -- cgit v1.2.1 From bf710b5119dce329a1ffd43b01b3a4dbb3e94b09 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 13 Oct 2016 18:34:44 -0300 Subject: Validate label params against all labels available to project on the API --- lib/api/helpers.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 67473f300c9..45120898b76 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -71,6 +71,10 @@ module API @project ||= find_project(params[:id]) end + def available_labels + @available_labels ||= LabelsFinder.new(current_user, project_id: user_project.id).execute + end + def find_project(id) project = Project.find_with_namespace(id) || Project.find_by(id: id) @@ -118,7 +122,7 @@ module API end def find_project_label(id) - label = user_project.labels.find_by_id(id) || user_project.labels.find_by_title(id) + label = available_labels.find_by_id(id) || available_labels.find_by_title(id) label || not_found!('Label') end @@ -197,16 +201,11 @@ module API def validate_label_params(params) errors = {} - if params[:labels].present? - params[:labels].split(',').each do |label_name| - label = user_project.labels.create_with( - color: Label::DEFAULT_COLOR).find_or_initialize_by( - title: label_name.strip) + params[:labels].to_s.split(',').each do |label_name| + label = available_labels.find_or_initialize_by(title: label_name.strip) + next if label.valid? - if label.invalid? - errors[label.title] = label.errors - end - end + errors[label.title] = label.errors end errors -- cgit v1.2.1 From cae27eae3f80a58bbf7eb49e9d077ea774f2b25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 27 Oct 2016 18:21:09 +0200 Subject: API: Fix booleans not recognized as such when using the `to_boolean` helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- lib/api/helpers.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 45120898b76..8025581d3ca 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -6,6 +6,7 @@ module API SUDO_PARAM = :sudo def to_boolean(value) + return value if [true, false].include?(value) return true if value =~ /^(true|t|yes|y|1|on)$/i return false if value =~ /^(false|f|no|n|0|off)$/i -- cgit v1.2.1 From f4e31b820e0cebd0f4bd0fe5a5d6a7a3c903a969 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Fri, 28 Oct 2016 18:56:13 -0200 Subject: Fix project features default values --- lib/api/helpers.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 8025581d3ca..3c9d7b1aaef 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -1,18 +1,12 @@ module API module Helpers + include Gitlab::Utils + PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" PRIVATE_TOKEN_PARAM = :private_token SUDO_HEADER = "HTTP_SUDO" SUDO_PARAM = :sudo - def to_boolean(value) - return value if [true, false].include?(value) - return true if value =~ /^(true|t|yes|y|1|on)$/i - return false if value =~ /^(false|f|no|n|0|off)$/i - - nil - end - def private_token params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER] end -- cgit v1.2.1 From 510092c83ad6b35dc4cc0ac1f15c643952f519b5 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 10 Nov 2016 16:32:59 +0100 Subject: Use #to_h to convert params to a hash --- lib/api/helpers.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3c9d7b1aaef..6998b6dc039 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -23,6 +23,11 @@ module API warden.try(:authenticate) if %w[GET HEAD].include?(env['REQUEST_METHOD']) end + def declared_params(options = {}) + options = { include_parent_namespaces: false }.merge(options) + declared(params, options).to_h.symbolize_keys + end + def find_user_by_private_token token = private_token return nil unless token.present? -- cgit v1.2.1 From ef3be00a0297dfa31002616df6ee49a0e2132cb7 Mon Sep 17 00:00:00 2001 From: Adam Niedzielski Date: Wed, 16 Nov 2016 12:46:07 +0100 Subject: Defer saving project services to the database if there are no user changes --- lib/api/helpers.rb | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3c9d7b1aaef..b4e0457f773 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -81,25 +81,10 @@ module API end def project_service - @project_service ||= begin - underscored_service = params[:service_slug].underscore - - if Service.available_services_names.include?(underscored_service) - user_project.build_missing_services - - service_method = "#{underscored_service}_service" - - send_service(service_method) - end - end - + @project_service ||= user_project.find_or_initialize_service(params[:service_slug].underscore) @project_service || not_found!("Service") end - def send_service(service_method) - user_project.send(service_method) - end - def service_attributes @service_attributes ||= project_service.fields.inject([]) do |arr, hash| arr << hash[:name].to_sym -- cgit v1.2.1 From 0d04724fa1cd670124b8ad9a3860bfa476c50f99 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 18 Nov 2016 10:00:40 +0100 Subject: More coverage on service level --- lib/api/helpers.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 84cc9200d1b..d6526ec4fdc 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -90,6 +90,15 @@ module API @project_service || not_found!("Service") end + def service_by_slug(project, slug) + underscored_service = slug.underscore + + not_found!('Service') unless Service.available_services_names.include?(underscored_service) + service_method = "#{underscored_service}_service" + + service = project.public_send(service_method) + end + def service_attributes @service_attributes ||= project_service.fields.inject([]) do |arr, hash| arr << hash[:name].to_sym -- cgit v1.2.1 From f749fb7fe0574d07eeb38561b9af62754e518281 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 18 Nov 2016 11:38:54 +0100 Subject: Improve style, add more tests --- lib/api/helpers.rb | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'lib/api/helpers.rb') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index d6526ec4fdc..2c593dbb4ea 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -85,20 +85,11 @@ module API end end - def project_service - @project_service ||= user_project.find_or_initialize_service(params[:service_slug].underscore) + def project_service(project = user_project) + @project_service ||= project.find_or_initialize_service(params[:service_slug].underscore) @project_service || not_found!("Service") end - def service_by_slug(project, slug) - underscored_service = slug.underscore - - not_found!('Service') unless Service.available_services_names.include?(underscored_service) - service_method = "#{underscored_service}_service" - - service = project.public_send(service_method) - end - def service_attributes @service_attributes ||= project_service.fields.inject([]) do |arr, hash| arr << hash[:name].to_sym -- cgit v1.2.1