-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from georchestra/refactoring_accounts_creation…
…_and_rabbitmq Refactor LDAP account creation functionality for better separation of concerns
- Loading branch information
Showing
68 changed files
with
1,414 additions
and
519 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
gateway/src/main/java/org/georchestra/gateway/accounts/admin/AbstractAccountsManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (C) 2023 by the geOrchestra PSC | ||
* | ||
* This file is part of geOrchestra. | ||
* | ||
* geOrchestra is free software: you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, either version 3 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* geOrchestra. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.georchestra.gateway.accounts.admin; | ||
|
||
import java.util.Optional; | ||
import java.util.concurrent.locks.ReadWriteLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
import java.util.function.Consumer; | ||
|
||
import org.georchestra.security.model.GeorchestraUser; | ||
|
||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
public abstract class AbstractAccountsManager implements AccountManager { | ||
|
||
private final @NonNull Consumer<AccountCreated> eventPublisher; | ||
|
||
protected final ReadWriteLock lock = new ReentrantReadWriteLock(); | ||
|
||
@Override | ||
public GeorchestraUser getOrCreate(@NonNull GeorchestraUser mappedUser) { | ||
return find(mappedUser).orElseGet(() -> createIfMissing(mappedUser)); | ||
} | ||
|
||
protected Optional<GeorchestraUser> find(GeorchestraUser mappedUser) { | ||
lock.readLock().lock(); | ||
try { | ||
return findInternal(mappedUser); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
|
||
protected Optional<GeorchestraUser> findInternal(GeorchestraUser mappedUser) { | ||
if (null != mappedUser.getOAuth2ProviderId()) { | ||
return findByOAuth2ProviderId(mappedUser.getOAuth2ProviderId()); | ||
} | ||
return findByUsername(mappedUser.getUsername()); | ||
} | ||
|
||
GeorchestraUser createIfMissing(GeorchestraUser mapped) { | ||
lock.writeLock().lock(); | ||
try { | ||
GeorchestraUser existing = findInternal(mapped).orElse(null); | ||
if (null == existing) { | ||
createInternal(mapped); | ||
existing = findInternal(mapped).orElseThrow(() -> new IllegalStateException( | ||
"User " + mapped.getUsername() + " not found right after creation")); | ||
eventPublisher.accept(new AccountCreated(existing)); | ||
} | ||
return existing; | ||
|
||
} finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
|
||
protected abstract Optional<GeorchestraUser> findByOAuth2ProviderId(String oauth2ProviderId); | ||
|
||
protected abstract Optional<GeorchestraUser> findByUsername(String username); | ||
|
||
protected abstract void createInternal(GeorchestraUser mapped); | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
gateway/src/main/java/org/georchestra/gateway/accounts/admin/AccountCreated.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright (C) 2023 by the geOrchestra PSC | ||
* | ||
* This file is part of geOrchestra. | ||
* | ||
* geOrchestra is free software: you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, either version 3 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* geOrchestra. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.georchestra.gateway.accounts.admin; | ||
|
||
import org.georchestra.security.model.GeorchestraUser; | ||
|
||
import lombok.NonNull; | ||
import lombok.Value; | ||
|
||
/** | ||
* Application event published when a new account was created | ||
*/ | ||
@Value | ||
public class AccountCreated { | ||
|
||
private @NonNull GeorchestraUser user; | ||
} |
48 changes: 48 additions & 0 deletions
48
gateway/src/main/java/org/georchestra/gateway/accounts/admin/AccountManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (C) 2023 by the geOrchestra PSC | ||
* | ||
* This file is part of geOrchestra. | ||
* | ||
* geOrchestra is free software: you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, either version 3 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* geOrchestra. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.georchestra.gateway.accounts.admin; | ||
|
||
import org.georchestra.gateway.security.GeorchestraUserMapper; | ||
import org.georchestra.gateway.security.ResolveGeorchestraUserGlobalFilter; | ||
import org.georchestra.security.model.GeorchestraUser; | ||
import org.springframework.context.ApplicationEventPublisher; | ||
import org.springframework.security.core.Authentication; | ||
|
||
/** | ||
* @see CreateAccountUserCustomizer | ||
* @see ResolveGeorchestraUserGlobalFilter | ||
*/ | ||
public interface AccountManager { | ||
|
||
/** | ||
* Finds the stored user that belongs to the {@code mappedUser} or creates it if | ||
* it doesn't exist in the users repository. | ||
* <p> | ||
* When a user is created, an {@link AccountCreated} event must be published to | ||
* the {@link ApplicationEventPublisher}. | ||
* | ||
* @param mappedUser the user {@link ResolveGeorchestraUserGlobalFilter} | ||
* resolved by calling | ||
* {@link GeorchestraUserMapper#resolve(Authentication)} | ||
* @return the stored version of the user, whether it existed or was created as | ||
* the result of calling this method. | ||
*/ | ||
GeorchestraUser getOrCreate(GeorchestraUser mappedUser); | ||
|
||
} |
68 changes: 68 additions & 0 deletions
68
...way/src/main/java/org/georchestra/gateway/accounts/admin/CreateAccountUserCustomizer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (C) 2023 by the geOrchestra PSC | ||
* | ||
* This file is part of geOrchestra. | ||
* | ||
* geOrchestra is free software: you can redistribute it and/or modify it under | ||
* the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, either version 3 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* geOrchestra is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* geOrchestra. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.georchestra.gateway.accounts.admin; | ||
|
||
import java.util.Objects; | ||
|
||
import org.georchestra.gateway.security.GeorchestraUserCustomizerExtension; | ||
import org.georchestra.security.model.GeorchestraUser; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; | ||
|
||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
/** | ||
* {@link GeorchestraUserCustomizerExtension} that | ||
* {@link AccountManager#getOrCreate creates an account} when authenticated | ||
* through request headers (trusted proxy feature) or through OAuth2. | ||
*/ | ||
@RequiredArgsConstructor | ||
public class CreateAccountUserCustomizer implements GeorchestraUserCustomizerExtension, Ordered { | ||
|
||
private final @NonNull AccountManager accounts; | ||
|
||
/** | ||
* @return {@link Ordered#LOWEST_PRECEDENCE} so it runs after all other | ||
* authentication customizations have been performed, such as setting | ||
* additional roles from externalized configuration, etc. | ||
*/ | ||
public @Override int getOrder() { | ||
return Ordered.LOWEST_PRECEDENCE; | ||
} | ||
|
||
/** | ||
* @return the stored version (either existing or created as result of calling | ||
* this method) of the user account, if the {@code Authentication} | ||
* object is either an {@link OAuth2AuthenticationToken} | ||
*/ | ||
@Override | ||
public @NonNull GeorchestraUser apply(@NonNull Authentication auth, @NonNull GeorchestraUser mappedUser) { | ||
final boolean isOauth2 = auth instanceof OAuth2AuthenticationToken; | ||
if (isOauth2) { | ||
Objects.requireNonNull(mappedUser.getOAuth2ProviderId(), "GeorchestraUser.oAuth2ProviderId is null"); | ||
} | ||
if (isOauth2) { | ||
return accounts.getOrCreate(mappedUser); | ||
} | ||
return mappedUser; | ||
} | ||
|
||
} |
Oops, something went wrong.