Skip to content

Commit 4386bde

Browse files
WIP: Require authentication for SCIM requests
Handling authentication through our regular warden strategies. Doing this required to make warden available to the Rails stack as well. This was not super straight-forward, because of load order issues: * Requiring a Rails middleware must be done before initialization finished * Our warden config was so far done _after_ initialization * static_routes were defined in lib, which is automatically reloaded, but auto-reloading code is now allowed during initialization * lib_static which is autoloaded_once is fine during init
1 parent 76d2f38 commit 4386bde

File tree

6 files changed

+90
-28
lines changed

6 files changed

+90
-28
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
module ScimV2
32+
module ScimControllerMixins
33+
def self.included(base)
34+
base.prepend(Overwrites)
35+
end
36+
37+
module Overwrites
38+
# Completely overwriting authenticate method of Scimitar
39+
def authenticate
40+
warden = request.env["warden"]
41+
User.current = warden.authenticate! scope: :scim_v2
42+
43+
# TODO: proper permissions check
44+
# TODO: validate whether authentication errors are handled by correct code/middleware (response didn't look SCIM-like)
45+
handle_scim_error(Scimitar::AuthenticationError.new) if !User.current.is_a?(ServiceAccount)|| !OpenProject::FeatureDecisions.scim_api_active?
46+
end
47+
end
48+
end
49+
end

app/models/user.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,3 +764,7 @@ def self.default_admin_account_changed?
764764
!User.active.find_by_login("admin").try(:current_password).try(:matches_plaintext?, "admin")
765765
end
766766
end
767+
768+
# Fix for development (and non eagerloaded environments), where User.find(...) would not return service accounts before
769+
# they've been autoloaded.
770+
require "service_account"

config/initializers/scimitar.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
patch: Scimitar::Supportable.unsupported
3434
})
3535
Scimitar.engine_configuration = Scimitar::EngineConfiguration.new(
36-
token_authenticator: Proc.new do |_token, _options|
37-
OpenProject::FeatureDecisions.scim_api_active?
38-
end
36+
application_controller_mixin: ScimV2::ScimControllerMixins
3937
)
4038
end

config/initializers/warden.rb

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,40 @@
1-
Rails.application.config.after_initialize do
2-
namespace = OpenProject::Authentication::Strategies::Warden
1+
namespace = OpenProject::Authentication::Strategies::Warden
32

4-
strategies = [
5-
[:basic_auth_failure, namespace::BasicAuthFailure, "Basic"],
6-
[:global_basic_auth, namespace::GlobalBasicAuth, "Basic"],
7-
[:user_basic_auth, namespace::UserBasicAuth, "Basic"],
8-
[:oauth, namespace::DoorkeeperOAuth, "Bearer"],
9-
[:anonymous_fallback, namespace::AnonymousFallback, "Basic"],
10-
[:jwt_oidc, namespace::JwtOidc, "Bearer"],
11-
[:session, namespace::Session, "Session"]
12-
]
3+
strategies = [
4+
[:basic_auth_failure, namespace::BasicAuthFailure, "Basic"],
5+
[:global_basic_auth, namespace::GlobalBasicAuth, "Basic"],
6+
[:user_basic_auth, namespace::UserBasicAuth, "Basic"],
7+
[:oauth, namespace::DoorkeeperOAuth, "Bearer"],
8+
[:anonymous_fallback, namespace::AnonymousFallback, "Basic"],
9+
[:jwt_oidc, namespace::JwtOidc, "Bearer"],
10+
[:session, namespace::Session, "Session"]
11+
]
1312

14-
strategies.each do |name, clazz, auth_scheme|
15-
OpenProject::Authentication.add_strategy(name, clazz, auth_scheme)
16-
end
13+
strategies.each do |name, clazz, auth_scheme|
14+
OpenProject::Authentication.add_strategy(name, clazz, auth_scheme)
15+
end
16+
17+
OpenProject::Authentication.update_strategies(OpenProject::Authentication::Scope::API_V3, { store: false }) do |_|
18+
%i[global_basic_auth
19+
user_basic_auth
20+
basic_auth_failure
21+
oauth
22+
jwt_oidc
23+
session
24+
anonymous_fallback]
25+
end
26+
27+
OpenProject::Authentication.update_strategies(OpenProject::Authentication::Scope::SCIM_V2, { store: false }) do |_|
28+
# TODO: reduce?
29+
%i[global_basic_auth
30+
user_basic_auth
31+
basic_auth_failure
32+
oauth
33+
jwt_oidc
34+
session
35+
anonymous_fallback]
36+
end
1737

18-
OpenProject::Authentication.update_strategies(OpenProject::Authentication::Scope::API_V3, { store: false }) do |_|
19-
%i[global_basic_auth
20-
user_basic_auth
21-
basic_auth_failure
22-
oauth
23-
jwt_oidc
24-
session
25-
anonymous_fallback]
26-
end
38+
Rails.application.configure do |app|
39+
app.config.middleware.use OpenProject::Authentication::Manager
2740
end

lib/api/root_api.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class RootAPI < Grape::API
4444

4545
content_type :json, "application/json; charset=utf-8"
4646

47-
use OpenProject::Authentication::Manager
48-
4947
helpers API::Caching::Helpers
5048
module Helpers
5149
include ::API::Helpers::RaiseQueryErrors

0 commit comments

Comments
 (0)