Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.deftdevs.bootstrapi.commons.service;

import com.atlassian.plugins.authentication.api.config.IdpConfig;
import com.atlassian.plugins.authentication.api.config.IdpConfigService;
import com.atlassian.plugins.authentication.api.config.SsoConfig;
import com.atlassian.plugins.authentication.api.config.SsoConfigService;
import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException;
import com.deftdevs.bootstrapi.commons.model.AbstractAuthenticationIdpModel;
import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel;
import com.deftdevs.bootstrapi.commons.service.api.AuthenticationService;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public abstract class AbstractAuthenticationService<IB extends AbstractAuthenticationIdpModel, SB extends AuthenticationSsoModel>

Check warning on line 17 in commons/src/main/java/com/deftdevs/bootstrapi/commons/service/AbstractAuthenticationService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this generic name to match the regular expression '^[A-Z][0-9]?$'.

See more on https://sonarcloud.io/project/issues?id=deftdevs_bootstrapi&issues=AZ4hnmexxfNA7aylfPjo&open=AZ4hnmexxfNA7aylfPjo&pullRequest=477

Check warning on line 17 in commons/src/main/java/com/deftdevs/bootstrapi/commons/service/AbstractAuthenticationService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this generic name to match the regular expression '^[A-Z][0-9]?$'.

See more on https://sonarcloud.io/project/issues?id=deftdevs_bootstrapi&issues=AZ4hnmexxfNA7aylfPjn&open=AZ4hnmexxfNA7aylfPjn&pullRequest=477
implements AuthenticationService<IB, SB> {

protected final IdpConfigService idpConfigService;
protected final SsoConfigService ssoConfigService;

protected AbstractAuthenticationService(
final IdpConfigService idpConfigService,
final SsoConfigService ssoConfigService) {

this.idpConfigService = idpConfigService;
this.ssoConfigService = ssoConfigService;
}

@Override
public Map<String, ? extends IB> getAuthenticationIdps() {
return idpConfigService.getIdpConfigs().stream()
.map(this::toAuthenticationIdpModel)
.collect(Collectors.toMap(AbstractAuthenticationIdpModel::getName, Function.identity()));
}

@Override
public Map<String, ? extends IB> setAuthenticationIdps(
final Map<String, ? extends IB> authenticationIdpModels) {

final Map<String, IB> resultIdpModels = new LinkedHashMap<>();

for (Map.Entry<String, ? extends IB> entry : authenticationIdpModels.entrySet()) {
final String idpName = entry.getKey();
final IB idpModel = entry.getValue();

if (idpModel == null) {
// declarative no-op: null model + existing entity → return as-is;

Check warning on line 49 in commons/src/main/java/com/deftdevs/bootstrapi/commons/service/AbstractAuthenticationService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This block of commented-out lines of code should be removed.

See more on https://sonarcloud.io/project/issues?id=deftdevs_bootstrapi&issues=AZ4hnmexxfNA7aylfPjp&open=AZ4hnmexxfNA7aylfPjp&pullRequest=477
// null model + missing entity → nothing to do
final IdpConfig existingIdpConfig = findIdpConfigByName(idpName);
if (existingIdpConfig != null) {
resultIdpModels.put(idpName, toAuthenticationIdpModel(existingIdpConfig));
}
continue;
}

if (idpModel.getName() == null) {
idpModel.setName(idpName);
}

final IB resultIdpModel = setAuthenticationIdp(idpModel);
resultIdpModels.put(resultIdpModel.getName(), resultIdpModel);
}
Comment thread
pathob marked this conversation as resolved.

return resultIdpModels;
}

@Override
public IB setAuthenticationIdp(
final IB authenticationIdpModel) {

if (authenticationIdpModel.getName() == null || authenticationIdpModel.getName().trim().isEmpty()) {
throw new BadRequestException("The name cannot be empty");
}

final IdpConfig existingIdpConfig = findIdpConfigByName(authenticationIdpModel.getName());

if (existingIdpConfig == null) {
final IdpConfig idpConfig = toIdpConfig(authenticationIdpModel);
final IdpConfig addedIdpConfig = idpConfigService.addIdpConfig(idpConfig);
return toAuthenticationIdpModel(addedIdpConfig);
}

final IdpConfig idpConfig = toIdpConfig(authenticationIdpModel, existingIdpConfig);
final IdpConfig updatedIdpConfig = idpConfigService.updateIdpConfig(idpConfig);
return toAuthenticationIdpModel(updatedIdpConfig);
}

@Override
public SB getAuthenticationSso() {
return toAuthenticationSsoModel(ssoConfigService.getSsoConfig());
}

@Override
public SB setAuthenticationSso(
final SB authenticationSsoModel) {

final SsoConfig existingSsoConfig = ssoConfigService.getSsoConfig();
final SsoConfig ssoConfig = toSsoConfig(authenticationSsoModel, existingSsoConfig);
return toAuthenticationSsoModel(ssoConfigService.updateSsoConfig(ssoConfig));
}

IdpConfig findIdpConfigByName(
final String name) {

final Map<String, IdpConfig> idpConfigsByName = idpConfigService.getIdpConfigs().stream().collect(Collectors.toMap(
IdpConfig::getName, Function.identity(), (existing, replacement) -> {
throw new IllegalStateException("Duplicate name key found: " + existing.getName());
}
));

return idpConfigsByName.get(name);
}

protected abstract IB toAuthenticationIdpModel(IdpConfig idpConfig);

protected abstract IdpConfig toIdpConfig(IB authenticationIdpModel);

protected abstract IdpConfig toIdpConfig(IB authenticationIdpModel, IdpConfig existingIdpConfig);

protected abstract SB toAuthenticationSsoModel(SsoConfig ssoConfig);

protected abstract SsoConfig toSsoConfig(SB authenticationSsoModel, SsoConfig existingSsoConfig);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,89 +4,47 @@
import com.atlassian.plugins.authentication.api.config.IdpConfigService;
import com.atlassian.plugins.authentication.api.config.SsoConfig;
import com.atlassian.plugins.authentication.api.config.SsoConfigService;
import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException;
import com.deftdevs.bootstrapi.commons.model.AbstractAuthenticationIdpModel;
import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel;
import com.deftdevs.bootstrapi.commons.service.AbstractAuthenticationService;
import com.deftdevs.bootstrapi.confluence.model.util.AuthenticationIdpModelUtil;
import com.deftdevs.bootstrapi.confluence.model.util.AuthenticationSsoModelUtil;
import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class AuthenticationServiceImpl implements ConfluenceAuthenticationService {

private final IdpConfigService idpConfigService;

private final SsoConfigService ssoConfigService;
public class AuthenticationServiceImpl
extends AbstractAuthenticationService<AbstractAuthenticationIdpModel, AuthenticationSsoModel>
implements ConfluenceAuthenticationService {

public AuthenticationServiceImpl(
final IdpConfigService idpConfigService,
final SsoConfigService ssoConfigService) {

this.idpConfigService = idpConfigService;
this.ssoConfigService = ssoConfigService;
super(idpConfigService, ssoConfigService);
}

@Override
public Map<String, ? extends AbstractAuthenticationIdpModel> getAuthenticationIdps() {
return idpConfigService.getIdpConfigs().stream()
.map(AuthenticationIdpModelUtil::toAuthenticationIdpModel)
.collect(Collectors.toMap(AbstractAuthenticationIdpModel::getName, Function.identity()));
protected AbstractAuthenticationIdpModel toAuthenticationIdpModel(final IdpConfig idpConfig) {
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(idpConfig);
}

@Override
public Map<String, ? extends AbstractAuthenticationIdpModel> setAuthenticationIdps(
final Map<String, ? extends AbstractAuthenticationIdpModel> authenticationIdpModels) {

return authenticationIdpModels.values().stream()
.map(this::setAuthenticationIdp)
.collect(Collectors.toMap(AbstractAuthenticationIdpModel::getName, Function.identity()));
}

public AbstractAuthenticationIdpModel setAuthenticationIdp(
final AbstractAuthenticationIdpModel authenticationIdpModel) {

if (authenticationIdpModel.getName() == null || authenticationIdpModel.getName().trim().isEmpty()) {
throw new BadRequestException("The name cannot be empty");
}

final IdpConfig existingIdpConfig = findIdpConfigByName(authenticationIdpModel.getName());

if (existingIdpConfig == null) {
final IdpConfig idpConfig = AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel);
final IdpConfig addedIdpConfig = idpConfigService.addIdpConfig(idpConfig);
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(addedIdpConfig);
}

final IdpConfig idpConfig = AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel, existingIdpConfig);
final IdpConfig updatedIdpConfig = idpConfigService.updateIdpConfig(idpConfig);
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(updatedIdpConfig);
protected IdpConfig toIdpConfig(final AbstractAuthenticationIdpModel authenticationIdpModel) {
return AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel);
}

@Override
public AuthenticationSsoModel getAuthenticationSso() {
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfigService.getSsoConfig());
protected IdpConfig toIdpConfig(final AbstractAuthenticationIdpModel authenticationIdpModel, final IdpConfig existingIdpConfig) {
return AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel, existingIdpConfig);
}

@Override
public AuthenticationSsoModel setAuthenticationSso(AuthenticationSsoModel authenticationSsoModel) {
final SsoConfig existingSsoConfig = ssoConfigService.getSsoConfig();
final SsoConfig ssoConfig = AuthenticationSsoModelUtil.toSsoConfig(authenticationSsoModel, existingSsoConfig);
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfigService.updateSsoConfig(ssoConfig));
protected AuthenticationSsoModel toAuthenticationSsoModel(final SsoConfig ssoConfig) {
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfig);
}

IdpConfig findIdpConfigByName(
final String name) {

final Map<String, IdpConfig> idpConfigsByName = idpConfigService.getIdpConfigs().stream().collect(Collectors.toMap(
IdpConfig::getName, Function.identity(), (existing, replacement) -> {
throw new IllegalStateException("Duplicate name key found: " + existing.getName());
}
));

return idpConfigsByName.get(name);
@Override
protected SsoConfig toSsoConfig(final AuthenticationSsoModel authenticationSsoModel, final SsoConfig existingSsoConfig) {
return AuthenticationSsoModelUtil.toSsoConfig(authenticationSsoModel, existingSsoConfig);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -117,6 +118,45 @@ void testSetAuthenticationIdpsNameEmpty() {
});
}

@Test
void testSetAuthenticationIdpsNullNameUsesMapKey() {
final String mapKey = "from-map-key";
final AuthenticationIdpOidcModel modelWithoutName = AuthenticationIdpOidcModel.builder().build();
final Map<String, AbstractAuthenticationIdpModel> authenticationIdpModels = Collections.singletonMap(mapKey, modelWithoutName);
doAnswer(invocation -> invocation.getArgument(0)).when(idpConfigService).addIdpConfig(any());

authenticationService.setAuthenticationIdps(authenticationIdpModels);
assertEquals(mapKey, modelWithoutName.getName());
verify(idpConfigService, times(1)).addIdpConfig(any());
}

@Test
void testSetAuthenticationIdpsNullModelMissingIdpSkipsEntry() {
final Map<String, AbstractAuthenticationIdpModel> authenticationIdpModels = new LinkedHashMap<>();
authenticationIdpModels.put("missing-idp", null);

final Map<String, ? extends AbstractAuthenticationIdpModel> result = authenticationService.setAuthenticationIdps(authenticationIdpModels);
assertTrue(result.isEmpty());
verify(idpConfigService, times(0)).addIdpConfig(any());
verify(idpConfigService, times(0)).updateIdpConfig(any());
}

@Test
void testSetAuthenticationIdpsNullModelExistingIdpReturnedAsIs() {
final AuthenticationIdpOidcModel idpModel = AuthenticationIdpOidcModel.EXAMPLE_1;
final IdpConfig idpConfig = AuthenticationIdpModelUtil.toIdpConfig(idpModel);
doReturn(Collections.singletonList(idpConfig)).when(idpConfigService).getIdpConfigs();

final Map<String, AbstractAuthenticationIdpModel> authenticationIdpModels = new LinkedHashMap<>();
authenticationIdpModels.put(idpModel.getName(), null);

final Map<String, ? extends AbstractAuthenticationIdpModel> result = authenticationService.setAuthenticationIdps(authenticationIdpModels);
assertEquals(1, result.size());
assertEquals(idpModel.getName(), result.values().iterator().next().getName());
verify(idpConfigService, times(0)).addIdpConfig(any());
verify(idpConfigService, times(0)).updateIdpConfig(any());
}

@Test
void testGetAuthenticationSso() {
final SsoConfig ssoConfig = ImmutableSsoConfig.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,88 +4,47 @@
import com.atlassian.plugins.authentication.api.config.IdpConfigService;
import com.atlassian.plugins.authentication.api.config.SsoConfig;
import com.atlassian.plugins.authentication.api.config.SsoConfigService;
import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException;
import com.deftdevs.bootstrapi.commons.model.AbstractAuthenticationIdpModel;
import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel;
import com.deftdevs.bootstrapi.commons.service.AbstractAuthenticationService;
import com.deftdevs.bootstrapi.jira.model.util.AuthenticationIdpModelUtil;
import com.deftdevs.bootstrapi.jira.model.util.AuthenticationSsoModelUtil;
import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class AuthenticationServiceImpl implements JiraAuthenticationService {

private final IdpConfigService idpConfigService;
private final SsoConfigService ssoConfigService;
public class AuthenticationServiceImpl
extends AbstractAuthenticationService<AbstractAuthenticationIdpModel, AuthenticationSsoModel>
implements JiraAuthenticationService {

public AuthenticationServiceImpl(
final IdpConfigService idpConfigService,
final SsoConfigService ssoConfigService) {

this.idpConfigService = idpConfigService;
this.ssoConfigService = ssoConfigService;
super(idpConfigService, ssoConfigService);
}

@Override
public Map<String, ? extends AbstractAuthenticationIdpModel> getAuthenticationIdps() {
return idpConfigService.getIdpConfigs().stream()
.map(AuthenticationIdpModelUtil::toAuthenticationIdpModel)
.collect(Collectors.toMap(AbstractAuthenticationIdpModel::getName, Function.identity()));
protected AbstractAuthenticationIdpModel toAuthenticationIdpModel(final IdpConfig idpConfig) {
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(idpConfig);
}

@Override
public Map<String, ? extends AbstractAuthenticationIdpModel> setAuthenticationIdps(
final Map<String, ? extends AbstractAuthenticationIdpModel> authenticationIdpModels) {

return authenticationIdpModels.values().stream()
.map(this::setAuthenticationIdp)
.collect(Collectors.toMap(AbstractAuthenticationIdpModel::getName, Function.identity()));
}

public AbstractAuthenticationIdpModel setAuthenticationIdp(
final AbstractAuthenticationIdpModel authenticationIdpModel) {

if (authenticationIdpModel.getName() == null || authenticationIdpModel.getName().trim().isEmpty()) {
throw new BadRequestException("The name cannot be empty");
}

final IdpConfig existingIdpConfig = findIdpConfigByName(authenticationIdpModel.getName());

if (existingIdpConfig == null) {
final IdpConfig idpConfig = AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel);
final IdpConfig addedIdpConfig = idpConfigService.addIdpConfig(idpConfig);
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(addedIdpConfig);
}

final IdpConfig idpConfig = AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel, existingIdpConfig);
final IdpConfig updatedIdpConfig = idpConfigService.updateIdpConfig(idpConfig);
return AuthenticationIdpModelUtil.toAuthenticationIdpModel(updatedIdpConfig);
protected IdpConfig toIdpConfig(final AbstractAuthenticationIdpModel authenticationIdpModel) {
return AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel);
}

@Override
public AuthenticationSsoModel getAuthenticationSso() {
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfigService.getSsoConfig());
protected IdpConfig toIdpConfig(final AbstractAuthenticationIdpModel authenticationIdpModel, final IdpConfig existingIdpConfig) {
return AuthenticationIdpModelUtil.toIdpConfig(authenticationIdpModel, existingIdpConfig);
}

@Override
public AuthenticationSsoModel setAuthenticationSso(AuthenticationSsoModel authenticationSsoModel) {
final SsoConfig existingSsoConfig = ssoConfigService.getSsoConfig();
final SsoConfig ssoConfig = AuthenticationSsoModelUtil.toSsoConfig(authenticationSsoModel, existingSsoConfig);
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfigService.updateSsoConfig(ssoConfig));
protected AuthenticationSsoModel toAuthenticationSsoModel(final SsoConfig ssoConfig) {
return AuthenticationSsoModelUtil.toAuthenticationSsoModel(ssoConfig);
}

IdpConfig findIdpConfigByName(
final String name) {

final Map<String, IdpConfig> idpConfigsByName = idpConfigService.getIdpConfigs().stream().collect(Collectors.toMap(
IdpConfig::getName, Function.identity(), (existing, replacement) -> {
throw new IllegalStateException("Duplicate name key found: " + existing.getName());
}
));

return idpConfigsByName.get(name);
@Override
protected SsoConfig toSsoConfig(final AuthenticationSsoModel authenticationSsoModel, final SsoConfig existingSsoConfig) {
return AuthenticationSsoModelUtil.toSsoConfig(authenticationSsoModel, existingSsoConfig);
}

}
Loading
Loading