Skip to content

Commit

Permalink
[ENH] ✨ Allow to configure mail unicity by realm
Browse files Browse the repository at this point in the history
Signed-off-by: Donatien Eneman <[email protected]>
  • Loading branch information
micedre committed Aug 5, 2021
1 parent 9edea43 commit a6f7ae0
Show file tree
Hide file tree
Showing 20 changed files with 296 additions and 26 deletions.
51 changes: 27 additions & 24 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,35 @@ Realm can be load from different sources.
| fr.insee.sugoi.config.ldap.profils.pattern | Use only if config type is ldap. String pattern to find realms ('{realm}' is replaced with realm's name). cn={realm} wil search realm config for realm1 | | |
| fr.insee.sugoi.ldap.default.vlv.enabled | enable vlv searched on ldap | false | |
| fr.insee.sugoi.config.ldap.default.sortKey | attribute on which paging request will be ordered | | uid |
| fr.insee.sugoi.verify.unique.email | indicate if a check on user email must be done before each update/creation | | true |

### Reader writer configuration

For each realm we have the possibility to configure a default reader and a default writer. For the moment it's possible to use ldap, file, and jms as writerStore and only ldap and file as reader.

| Properties | Description | Default value | example |
| ----------------------------------------------------- | :-------------------------------------------------------------------------------------: | ------------: | ----------------------------------------------: |
| fr.insee.sugoi.store.defaultReader | Can be LdapReaderStore, FileReaderStore | | LdapReaderStore |
| fr.insee.sugoi.store.defaultWriter | Can be LdapWriterStore, FileWriterStore, JmsWriterStore | | LdapWriterStore |
| fr.insee.sugoi.jms.broker.url | Use only if default writer or reader is JMS. | | ssl://broker.com:61617?verifyHostName=false |
| fr.insee.sugoi.jms.queue.requests.name | Use only if defaultWriter is JMS. | | queue.sugoi.developpement.requests |
| fr.insee.sugoi.jms.queue.response.name | Use only if defaultWriter is JMS. | | queue.sugoi.developpement.response |
| fr.insee.sugoi.jms.priority.queue.request.name | Name of the request queue to listen | | queue.sugoi.developpement.prioritaire.requests |
| fr.insee.sugoi.jms.priority.queue.response.name | Name of the response queue to listen | | queue.sugoi.developpement.prioritaire.responses |
| fr.insee.sugoi.jms.receiver.request.enabled | Enable to listen a request queue in a broker | | |
| fr.insee.sugoi.jms.receiver.response.enabled | Enable to listen a response queue in a broker | | |
| fr.insee.sugoi.ldap.default.ldap.pool | Use only if defaultWriter is ldap. Default pool size for each ldap connection | | 10 |
| fr.insee.sugoi.ldap.default.username | Use only if defaultWriter is ldap. Default username to establish connection with ldap | | cn=Directory Manager |
| fr.insee.sugoi.ldap.default.password | Use only if defaultWriter is ldap. Default password to establish connection with ldap | | admin |
| fr.insee.sugoi.ldap.default.port | Use only if defaultWriter is ldap. Default port to establish connection with ldap | | 10389 |
| fr.insee.sugoi.ldap.default.group_source_pattern | Use only if defaultWriter is ldap. Default pattern to follow to find group | | |
| fr.insee.sugoi.ldap.default.group_filter_pattern | Use only if defaultWriter is ldap. Default pattern to follow for naming groups | | |
| fr.insee.sugoi.default.app_managed_attribute_keys | a list of all attributes that a user can update directly | |
| fr.insee.sugoi.default.app_managed_attribute_patterns | Default pattern that each fr.insee.sugoi.default.app_managed_attribute_keys must follow | |
| fr.insee.sugoi.ldap.default.user-mapping | List of mappings between sugoi user attributes and ldap attributes divided by semicolon , see [Realm configuration](realm-configuration.md) | username:uid,String,rw;groups:memberOf,list_group,ro;habilitations:inseeGroupeDefaut,list_habilitation,rw |
| fr.insee.sugoi.ldap.default.organization-mapping | List of mappings between sugoi organization attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | identifiant:uid,String,rw;address:inseeAdressePostaleDN,address,rw;organization:inseeOrganisationDN,organization,rw |
| fr.insee.sugoi.ldap.default.group-mapping | List of mappings between sugoi group attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | name:cn,String,rw;description:description,String,rw;users:uniquemember,list_user,rw |
| fr.insee.sugoi.ldap.default.application-mapping | List of mappings between sugoi application attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | name:ou,String,rw |
| Properties | Description | Default value | example |
| ----------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------: |
| fr.insee.sugoi.store.defaultReader | Can be LdapReaderStore, FileReaderStore | | LdapReaderStore |
| fr.insee.sugoi.store.defaultWriter | Can be LdapWriterStore, FileWriterStore, JmsWriterStore | | LdapWriterStore |
| fr.insee.sugoi.jms.broker.url | Use only if default writer or reader is JMS. | | ssl://broker.com:61617?verifyHostName=false |
| fr.insee.sugoi.jms.queue.requests.name | Use only if defaultWriter is JMS. | | queue.sugoi.developpement.requests |
| fr.insee.sugoi.jms.queue.response.name | Use only if defaultWriter is JMS. | | queue.sugoi.developpement.response |
| fr.insee.sugoi.jms.priority.queue.request.name | Name of the request queue to listen | | queue.sugoi.developpement.prioritaire.requests |
| fr.insee.sugoi.jms.priority.queue.response.name | Name of the response queue to listen | | queue.sugoi.developpement.prioritaire.responses |
| fr.insee.sugoi.jms.receiver.request.enabled | Enable to listen a request queue in a broker | | |
| fr.insee.sugoi.jms.receiver.response.enabled | Enable to listen a response queue in a broker | | |
| fr.insee.sugoi.ldap.default.ldap.pool | Use only if defaultWriter is ldap. Default pool size for each ldap connection | | 10 |
| fr.insee.sugoi.ldap.default.username | Use only if defaultWriter is ldap. Default username to establish connection with ldap | | cn=Directory Manager |
| fr.insee.sugoi.ldap.default.password | Use only if defaultWriter is ldap. Default password to establish connection with ldap | | admin |
| fr.insee.sugoi.ldap.default.port | Use only if defaultWriter is ldap. Default port to establish connection with ldap | | 10389 |
| fr.insee.sugoi.ldap.default.group_source_pattern | Use only if defaultWriter is ldap. Default pattern to follow to find group | | |
| fr.insee.sugoi.ldap.default.group_filter_pattern | Use only if defaultWriter is ldap. Default pattern to follow for naming groups | | |
| fr.insee.sugoi.default.app_managed_attribute_keys | a list of all attributes that a user can update directly | |
| fr.insee.sugoi.default.app_managed_attribute_patterns | Default pattern that each fr.insee.sugoi.default.app_managed_attribute_keys must follow | |
| fr.insee.sugoi.ldap.default.user-mapping | List of mappings between sugoi user attributes and ldap attributes divided by semicolon , see [Realm configuration](realm-configuration.md) | username:uid,String,rw;groups:memberOf,list_group,ro;habilitations:inseeGroupeDefaut,list_habilitation,rw |
| fr.insee.sugoi.ldap.default.organization-mapping | List of mappings between sugoi organization attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | identifiant:uid,String,rw;address:inseeAdressePostaleDN,address,rw;organization:inseeOrganisationDN,organization,rw |
| fr.insee.sugoi.ldap.default.group-mapping | List of mappings between sugoi group attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | name:cn,String,rw;description:description,String,rw;users:uniquemember,list_user,rw |
| fr.insee.sugoi.ldap.default.application-mapping | List of mappings between sugoi application attributes and ldap attributes divided by semicolon, see [Realm configuration](realm-configuration.md) | name:ou,String,rw |

### SpringDoc configuration

Expand Down Expand Up @@ -145,7 +146,8 @@ A metrics event module is provided to add metrics when events occured. This is d
```
fr.insee.sugoi.api.event.metrics.enabled=true
```
All actuator endpoints are available to admin users. You can also enable a specific monitoring user with the properties :

All actuator endpoints are available to admin users. You can also enable a specific monitoring user with the properties :

```
fr.insee.sugoi.security.monitor-user-enabled=true
Expand All @@ -154,6 +156,7 @@ fr.insee.sugoi.security.monitor-user-password=monitor
```

This user only has rights on `/actuator` endpoints.

### Other info configuration

You can add all other spring properties for example :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ public class GlobalKeysConfig {
public static final String APP_MANAGED_ATTRIBUTE_KEYS_LIST = "app-managed-attribute-keys-list";
public static final String APP_MANAGED_ATTRIBUTE_PATTERNS_LIST =
"app-managed-attribute-patterns-list";
public static final String VERIFY_MAIL_UNICITY = "verify_mail_unicity";
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class EventKeysConfig extends GlobalKeysConfig {
public static final String USER = "user";
public static final String USER_ID = "userId";
public static final String USER_NAME = "userName";
public static final String USER_MAIL = "userMail";
public static final String USER_FILTER = "userFilter";
public static final String USER_PROPERTIES = "userProperties";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum SugoiEventTypeEnum {
UPDATE_USER,
FIND_USERS,
FIND_USER_BY_ID,
FIND_USER_BY_MAIL,
FIND_REALMS,
FIND_REALM_BY_ID,
CREATE_REALM,
Expand Down Expand Up @@ -76,6 +77,7 @@ public enum SugoiEventTypeEnum {
DELETE_USER_FROM_GROUP_ERROR,
FIND_USERS_ERROR,
FIND_USER_BY_ID_ERROR,
FIND_USER_BY_MAIL_ERROR,
FIND_REALMS_ERROR,
FIND_REALM_BY_ID_ERROR,
FIND_ORGANIZATIONS_ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ public interface UserService {
*/
Optional<User> findById(String realm, String storageName, String idep);

/**
* Find a user by its username in a realm
*
* @param realm
* @param storageName
* @param idep
* @return an optional of user
*/
Optional<User> findByMail(String realm, String storageName, String mail);

/**
* Find users by criterias in a realm
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,4 +376,79 @@ public ProviderResponse deleteAppManagedAttribute(
throw e;
}
}

@Override
public Optional<User> findByMail(String realmName, String storageName, String mail) {
User user = null;
try {
if (mail != null) {
Realm realm =
realmProvider
.load(realmName)
.orElseThrow(
() -> new RealmNotFoundException("The realm " + realmName + " doesn't exist "));
if (storageName != null) {
user = storeProvider.getReaderStore(realmName, storageName).getUserByMail(mail);
user.addMetadatas(GlobalKeysConfig.REALM, realmName.toLowerCase());
user.addMetadatas(GlobalKeysConfig.USERSTORAGE, storageName.toLowerCase());
} else {
for (UserStorage us : realm.getUserStorages()) {
try {
user = storeProvider.getReaderStore(realmName, us.getName()).getUserByMail(mail);
user.addMetadatas(GlobalKeysConfig.REALM, realmName);
user.addMetadatas(GlobalKeysConfig.USERSTORAGE, us.getName());
break;
} catch (Exception e) {
logger.debug(
"Error when trying to find user with mail"
+ mail
+ " on realm "
+ realmName
+ " and userstorage "
+ us
+ " error "
+ e.getMessage());
}
}
}
if (seeAlsoService != null
&& realm.getProperties().containsKey(GlobalKeysConfig.SEEALSO_ATTRIBUTES)) {
String[] seeAlsosAttributes =
realm
.getProperties()
.get(GlobalKeysConfig.SEEALSO_ATTRIBUTES)
.replace(" ", "")
.split(",");
List<String> seeAlsos = new ArrayList<>();
for (String seeAlsoAttribute : seeAlsosAttributes) {
Object seeAlsoAttributeValue = user.getAttributes().get(seeAlsoAttribute);
if (seeAlsoAttributeValue instanceof String) {
seeAlsos.add((String) seeAlsoAttributeValue);
} else if (seeAlsoAttributeValue instanceof List) {
((List<?>) seeAlsoAttributeValue)
.forEach(seeAlso -> seeAlsos.add(seeAlso.toString()));
}
}
for (String seeAlso : seeAlsos) {
seeAlsoService.decorateWithSeeAlso(user, seeAlso);
}
}
sugoiEventPublisher.publishCustomEvent(
realmName,
storageName,
SugoiEventTypeEnum.FIND_USER_BY_MAIL,
Map.ofEntries(Map.entry(EventKeysConfig.USER_MAIL, mail)));
}
return Optional.ofNullable(user);
} catch (Exception e) {
sugoiEventPublisher.publishCustomEvent(
realmName,
storageName,
SugoiEventTypeEnum.FIND_USER_BY_MAIL_ERROR,
Map.ofEntries(
Map.entry(EventKeysConfig.USER_MAIL, mail),
Map.entry(EventKeysConfig.ERROR, e.toString())));
return Optional.ofNullable(user);
}
}
}
Loading

0 comments on commit a6f7ae0

Please sign in to comment.