77 Commits

Author SHA1 Message Date
Jan Sandbrink e7bee82f9e Introduce and use ConfidentialCache
It's like OpenProject::Cache, but it encrypts cached
values at rest. Callers that store confidential things in the cache
have been updated to use it, reducing the risk to expose secrets
to an attacker that obtained access to the contents of OpenProject's cache.
2026-05-19 15:56:53 +02:00
Oliver Günther 86daea4b45 Revert "[#67763] Remove omniauth-openid_connect-providers." 2025-11-05 08:19:33 +01:00
ba1ash 6b1c30d381 [#67763] Remove omniauth-openid_connect-providers. 2025-10-22 17:22:52 +02:00
OpenProject Actions CI 2e37c926fb Merge branch 'release/16.2' into dev 2025-07-29 03:59:49 +00:00
Jan Sandbrink bd4b09592b Fix registration of auth providers through register_auth_providers
This is the only and official API to register an auth provider.
However, so far it was optional to create a database entry in the
auth_providers table and only OIDC and SAML did that.

On the other hand, we added expectations about auth providers have
a database entry in more and more places of the codebase.

Now making sure that every auth provider is represented in the database.
2025-07-28 09:01:10 +02:00
Jan Sandbrink 48ee98b6ef Add UI to inspect OIDC group links
This is to add some transparency on the fact that users
can automatically be assigned to such a group and how that
would work.
2025-07-25 16:16:25 +02:00
Jan Sandbrink 8596c8a5b5 Allow to synchronize groups via OpenID Connect
When the corresponding claim is present and synchronization of groups
is enabled, then we'll import groups from the groups claim.
2025-07-25 09:39:32 +02:00
Jan Sandbrink f87b3ee347 Add UI for SCIM Clients
Allowing to manage SCIM clients through the UI, including
all the authentication methods and their related "behind the scenes"
setup, i.e. service account, oauth application and access tokens.
2025-07-01 15:54:12 +02:00
Pavel Balashou b78678c5ec Load STI models explicitly.
Due to STI nature it is required. Otherwise undesired behavior is possible
in dev and test environments(where usually lazy loading is enabled).
The udesired behavior can be like:
  Fetching not loaded yet STI model through its parent model
  (e.g. `User.find(service_account_id)` raises `ActiveRecord::NotFound`, because
  `ServiceAccount` has not been referenced yet.

`SubclassRegistry` has been removed, because:
1. `.register_subclasses` and `.registered_subclasses` produce unexpected results.
    ```ruby
      # e.g.: Principal -> User -> ServiceAccount
      Principal.register_subclass(User)

      # Then
      Principal.registered_subclasses == [User] # true
      User.registered_subclasses == [User] # true
      ServiceAccount.registered_subclasses == [User] # true
      # Having User as a subclass of User and ServiceAccount seems to be weird.
    ```

2. There seems to be no big win in have the additional list of subclasses that have to be manually filled.
3. Used in commit apprach seems to be simpler.
   It is just calling STI classes explicitly in to_prepare block of configuration.
2025-06-20 17:00:08 +02:00
Jan Sandbrink 06a0917c21 Fix omission in token exchange implementation
Providing a subject_token_type is required according to RFC 8693,
but we left it out so far. New versions of Keycloak fail the token exchange
request if that parameter is missing.

Since this required introducing another urn-constant, I've decided to move all
of them to a common location.
2025-05-21 08:17:26 +02:00
ulferts 3a5b66cabb Merge remote-tracking branch 'origin/release/15.4' into dev 2025-03-19 15:47:41 +01:00
Jan Sandbrink f41175c7d0 Correctly handle when expires_in is a string
Azure/Entra ID seems to return stringly typed
expiry dates under certain conditions. We'll now
also handle properly readable numeric strings.

Missing expiration times or non-numeric strings,
such as "banana" will be treated as not knowing
the expiration time.
2025-03-19 08:52:10 +01:00
Jan Sandbrink ecbf6bdda9 Add magic comment for frozen string literals to OIDC module
Some files were missing the corresponding comment before.
This change was effectively achieved through:

    rubocop -A --only Style/FrozenStringLiteralComment,Layout/EmptyLineAfterMagicComment,Style/RedundantFreeze modules/openid_connect
2025-03-18 14:46:00 +01:00
Jan Sandbrink 21632c4938 Add missing copyright headers to OIDC module 2025-03-18 14:46:00 +01:00
Klaus Zanders 158e7c6264 Merge branch 'dev' into merge-release/15.4-20250317034137 2025-03-17 13:30:46 +01:00
Jan Sandbrink 6e000374e5 Do not call create service when access token is missing
Other parameters stored in the session are kind of optional,
but without the access token we can't create a user token.

The most popular case for a missing access token should be
that the login happened through a non-OIDC provider.
2025-03-13 16:35:29 +01:00
Jan Sandbrink c8be09420a Ensure to only store tokens for OIDC logins
The hook we are using is firing for all kinds of omniauth
logins. By ensuring that we have a matching OpenIDConnect provider,
we know that we are currently performing an OIDC login, which is
the only case where we want to try storing OIDC tokens.
2025-03-13 09:33:00 +01:00
ulferts 8018cc060b use cache_key_with_version to adapt to changed cache_key method 2025-03-12 17:43:29 +01:00
Jan Sandbrink 48f1f081f0 Explicitly store expiration time of access tokens
Previously we didn't consider the expires_in from the
token endpoint response, thus being unable to know whether
a token was expired or not before using it. While we worked
around that by inspecting tokens that seemed readable as JWTs,
the better approach is to memoize the information returned by the
server, as that also allows to know the expiration time of
opaque access tokens.

We'll keep the JWT extraction around as a fallback mechanism,
but prefer reading the info from the token endpoint, if it's present.
2025-02-19 10:17:04 +01:00
Jan Sandbrink 8ab8ae498d Rename AssociateUserToken to CreateService
This is more aligned with how we call other similar services,
since the focus of this service is about creating user tokens.
2025-01-14 15:49:21 +01:00
Jan Sandbrink 543f8decf3 Add some frozen string literal comments
Those places were noticed by Rubocop after
rebasing a feature branch onto the dev branch.
2025-01-13 16:22:15 +01:00
Jan Sandbrink e5f122630e Store tokens on user, not session
Doing so hopefully simplifies token handling a bit.
It's now not required to pass specific sessions into services
as long as a user is passed.
This theoretically also enables us to act in the name of a user from
a background job, though we have no specific plans for that yet.

A possible downside is, that we now require being handed long-term tokens
(i.e. tokens with offline_access scope). On the other hand, we'd have had
to consider keeping our tokens fresh for the previous implementation, which
we also didn't solve yet.
2025-01-13 16:13:34 +01:00
Jan Sandbrink cdc304faf4 Change the way user tokens are stored
This commit provides an alternative implementation
for storing tokens compared to the parent commit.

The idea is that we will not only need to store access
and refresh tokens obtained via Omniauth, but also the ones
to access third party services that will most likely be obtained
through OAuth 2.0 Token Exchange. This structure allows to store
all of these tokens in the same data model, while keeping the
implementation separated from the back-channel logout logic.
2025-01-13 16:13:34 +01:00
Jan Sandbrink 12da6c6b12 Save OIDC tokens to OpenProject database.
Storing tokens in the database to have them available for
requests to third parties (e.g. Nextcloud) later.

The OIDC session is now marked as optional, since the
session link is also used to store access and refresh tokens
associated with the session. Those tokens might be present,
even if the session id (which belongs to the optional
OIDC Back-Channel Logout specification) is missing.
2025-01-13 16:13:34 +01:00
Oliver Günther 718d934875 Fix generation of provider classes from new config 2024-10-21 13:03:50 +02:00
Oliver Günther 7247a232ae Remove form_post security impact option
This is probably no longer in place, but should be solved differently by now (by session mapping similar to saml RelayState)
2024-10-21 13:03:48 +02:00
Oliver Günther 30fae2b090 Rename seeder 2024-10-21 13:03:48 +02:00
Pavel Balashou e0c5dd3ef6 Update OIDC configuration UI. 2024-10-21 13:03:46 +02:00
Oliver Günther ad91efa908 Rename openid_providers -> sso_auth_providers 2024-09-26 11:35:44 +02:00
Oliver Günther 64a94a4567 Match constant names 2024-09-20 10:24:00 +02:00
Ivan Kuchin 4911b8a149 remove years from copyrights (except for COPYRIGHT file) 2024-07-31 15:02:49 +02:00
Pavel Balashou f611ba3bcb [#55643] Extend API authentication to accept JWT issued by OpenID provider to other client.
https://community.openproject.org/work_packages/55643

- Add new warden authentication stategy to handle jwt issued by configured OIDC.
- Modify exisiting doorkeeper_oauth stategy to ignore jwts.
- Fill in WWW-Autheticate header with auth failure information.
- Make keycloak docker dev setup use postgres as a database.
2024-07-23 10:42:04 +02:00
Pavel Balashou 400d3b0bf6 [#55472] Extend omniauth_user_authorized comment.
Co-authored-by: Kabiru Mwenja <k.mwenja@openproject.com>
2024-06-07 13:28:57 +02:00
Pavel Balashou d928f0f44b [#55472] Do not save access token in cookies
https://community.openproject.org/work_packages/55472

Reason: This logic is an orphan of old removed behavior.
So, it should be safe to just remove it.
2024-06-06 14:18:33 +02:00
Ivan Kuchin fa5d03eae0 rubocop safe autocorrect all except Rails/WhereRange 2024-05-30 19:54:08 +02:00
ulferts 3b2121f733 Revert "Merge remote-tracking branch 'origin/release/13.4' into dev"
This reverts commit 40b2bbeb09, reversing
changes made to b4c6cb17cc.
2024-03-21 11:31:17 +01:00
Ivan Kuchin 7787e457a3 Revert "Merge branch 'dev' into release/13.4"
This reverts commit a901541269, reversing
changes made to e573ca00b7.
2024-03-20 20:19:08 +01:00
Ivan Kuchin 9e4934cd0a change quotes using rubocop --only Style/StringLiterals,Style/QuotedSymbols -a 2024-03-20 18:05:22 +01:00
Christophe Bliard 8fa8584538 Run rubocop --autocorrect on all files
Only the safe cops have run. rubocop version is 1.59.0.
2024-01-05 15:27:09 +01:00
Christophe Bliard c795874f7f Update copyright year for 2024
command used: `rg -l 'Copyright \(C\) 2012-202\d the OpenProject' | xargs -n 100 sed -i -r 's/Copyright \(C\) 2012-202. the OpenProject/Copyright (C) 2012-2024 the OpenProject/'`
2024-01-02 16:23:54 +01:00
Oliver Günther 35bbac8ff4 Allow omniauth integrations to map admin flag, update on login
Provides a separate call to Users::UpdateService when an admin attribute
has been mapped to the omniauth info hash.

When updating the admin flag fails for some reason (e.g., trying to remove the last admin)
it will prevent the user from logging in.
2023-11-02 20:38:42 +01:00
Oliver Günther 47b32dd5cc Move use_graph_api and self_registration OIDC options into configuration 2023-10-11 16:50:53 +02:00
Pavel Balashou 15a78adef8 [#47155] Bump rack-oauth2 gem.
https://community.openproject.org/work_packages/47155
2023-03-29 14:32:35 +02:00
ulferts 52aba5e993 Revert "Merge pull request #12202 from opf/fix/bump_rack-oauth2"
This reverts commit f110631265, reversing
changes made to 4985ba1c77.
2023-03-20 11:33:43 +01:00
Pavel Balashov 9dee4fb53f Remove no needed ssl configuration anymore.
The reason: it is set by default in
https://github.com/lostisland/faraday-net_http/blob/main/lib/faraday/adapter/net_http.rb#L175
2023-03-06 14:40:38 +01:00
Pavel Balashov 0614bff348 Fix specs after rack-oauth2 update. 2023-03-06 14:40:38 +01:00
Oliver Günther 3807fd989f Merge remote-tracking branch 'origin/release/12.4' into dev 2023-01-23 15:51:25 +01:00
Oliver Günther 2a1dcb2781 Allow nil on session link 2023-01-23 15:21:07 +01:00
Oliver Günther b7b931861b Fix upstream oidc_sid link 2023-01-23 15:21:06 +01:00
Christophe Bliard 21a696ef9b Update copyright information for 2023 2022-12-30 15:51:26 +01:00