From edb3d776aab47cb249c3552b2d10976baab39730 Mon Sep 17 00:00:00 2001 From: Manoj Garai Date: Fri, 19 Jul 2024 16:55:03 +0100 Subject: [PATCH 01/30] Set reset service account --- .../aup/DefaultAupSignatureCheckService.java | 2 +- .../iam/api/scim/converter/UserConverter.java | 5 + .../infn/mw/iam/api/scim/model/ScimUser.java | 18 ++- .../provisioning/ScimUserProvisioning.java | 4 +- .../mw/iam/api/scim/updater/UpdaterType.java | 1 + .../api/scim/updater/builders/Replacers.java | 7 ++ .../factory/DefaultAccountUpdaterFactory.java | 2 + .../account/ServiceAccountReplacedEvent.java | 41 +++++++ .../webapp/WEB-INF/views/iam/dashboard.jsp | 1 + .../user.request-aup-signature.component.html | 2 +- .../user.service.account.component.html | 38 ++++++ .../user.service.account.component.js | 109 ++++++++++++++++++ .../user.sign-on-behalf.component.html | 2 +- .../components/user/user.component.html | 3 + .../services/scim-factory.service.js | 25 +++- .../mw/iam/persistence/model/IamAccount.java | 11 ++ .../h2/V106__add_service_account.sql | 3 + 17 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 iam-login-service/src/main/java/it/infn/mw/iam/audit/events/account/ServiceAccountReplacedEvent.java create mode 100644 iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/service-account/user.service.account.component.html create mode 100644 iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/service-account/user.service.account.component.js create mode 100644 iam-persistence/src/main/resources/db/migration/h2/V106__add_service_account.sql diff --git a/iam-common/src/main/java/it/infn/mw/iam/service/aup/DefaultAupSignatureCheckService.java b/iam-common/src/main/java/it/infn/mw/iam/service/aup/DefaultAupSignatureCheckService.java index 84743c82f..67c31f090 100644 --- a/iam-common/src/main/java/it/infn/mw/iam/service/aup/DefaultAupSignatureCheckService.java +++ b/iam-common/src/main/java/it/infn/mw/iam/service/aup/DefaultAupSignatureCheckService.java @@ -53,7 +53,7 @@ public boolean needsAupSignature(IamAccount account) { Date now = new Date(timeProvider.currentTimeMillis()); - if (!aup.isPresent()) { + if (!aup.isPresent() || account.isServiceAccount()) { LOG.debug("AUP signature not needed for account '{}': AUP is not defined", account.getUsername()); return false; diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/converter/UserConverter.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/converter/UserConverter.java index c2a1aebfd..258f7b65e 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/converter/UserConverter.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/converter/UserConverter.java @@ -91,6 +91,10 @@ public IamAccount entityFromDto(ScimUser scimUser) { account.setActive(scimUser.getActive()); } + if (scimUser.getServiceAccount() != null) { + account.setServiceAccount(scimUser.getServiceAccount()); + } + if (scimUser.getPassword() != null) { account.setPassword(scimUser.getPassword()); @@ -190,6 +194,7 @@ public ScimUser dtoFromEntity(IamAccount entity) { .meta(getScimMeta(entity)) .name(getScimName(entity)) .active(entity.isActive()) + .serviceAccount(entity.isServiceAccount()) .displayName(entity.getUsername()) .locale(entity.getUserInfo().getLocale()) .nickName(entity.getUserInfo().getNickname()) diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/model/ScimUser.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/model/ScimUser.java index dc5e60bb3..19ec98509 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/model/ScimUser.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/model/ScimUser.java @@ -68,6 +68,7 @@ public interface UpdateUserValidation extends Default { private final String locale; private final String timezone; private final Boolean active; + private final Boolean serviceAccount; @NotEmpty(groups = {NewUserValidation.class}) @Valid @@ -93,7 +94,8 @@ private ScimUser(@JsonProperty("id") String id, @JsonProperty("externalId") Stri @JsonProperty("userType") String userType, @JsonProperty("preferredLanguage") String preferredLanguage, @JsonProperty("locale") String locale, @JsonProperty("timezone") String timezone, - @JsonProperty("active") Boolean active, @JsonProperty("emails") List emails, + @JsonProperty("active") Boolean active, @JsonProperty("serviceAccount") Boolean serviceAccount, + @JsonProperty("emails") List emails, @JsonProperty("addresses") List addresses, @JsonProperty("photos") List photos, @JsonProperty("groups") Set groups, @@ -116,6 +118,7 @@ private ScimUser(@JsonProperty("id") String id, @JsonProperty("externalId") Stri this.timezone = timezone; this.emails = emails; this.active = active; + this.serviceAccount = serviceAccount; this.groups = groups; this.addresses = addresses; this.indigoUser = indigoUser; @@ -135,6 +138,7 @@ private ScimUser(Builder b) { this.locale = b.locale; this.timezone = b.timezone; this.active = b.active; + this.serviceAccount = b.serviceAccount; this.emails = b.emails; this.addresses = b.addresses; /* build indigoUserBuilder only if it has been touched */ @@ -216,6 +220,11 @@ public Boolean getActive() { return active; } + public Boolean getServiceAccount() { + + return serviceAccount; + } + public List getEmails() { return emails; @@ -300,6 +309,7 @@ public static class Builder extends ScimResource.Builder { private String locale; private String timezone; private Boolean active; + private Boolean serviceAccount; private List emails = new ArrayList<>(); private Set groups = new LinkedHashSet<>(); @@ -401,6 +411,12 @@ public Builder active(Boolean active) { return this; } + public Builder serviceAccount(Boolean serviceAccount) { + + this.serviceAccount = serviceAccount; + return this; + } + public Builder addGroupRef(ScimGroupRef scimGroupRef) { Preconditions.checkNotNull(scimGroupRef, "Null group ref"); diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java index ad3931674..3726514b6 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java @@ -30,6 +30,7 @@ import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_GIVEN_NAME; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_PASSWORD; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_PICTURE; +import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_SERVICE_ACCOUNT; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_USERNAME; import java.util.ArrayList; @@ -79,7 +80,8 @@ public class ScimUserProvisioning ACCOUNT_ADD_SSH_KEY, ACCOUNT_REMOVE_SSH_KEY, ACCOUNT_ADD_X509_CERTIFICATE, ACCOUNT_REMOVE_X509_CERTIFICATE, ACCOUNT_REPLACE_ACTIVE, ACCOUNT_REPLACE_EMAIL, ACCOUNT_REPLACE_FAMILY_NAME, ACCOUNT_REPLACE_GIVEN_NAME, ACCOUNT_REPLACE_PASSWORD, - ACCOUNT_REPLACE_PICTURE, ACCOUNT_REPLACE_USERNAME, ACCOUNT_REMOVE_PICTURE); + ACCOUNT_REPLACE_PICTURE, ACCOUNT_REPLACE_USERNAME, ACCOUNT_REMOVE_PICTURE, + ACCOUNT_REPLACE_SERVICE_ACCOUNT); private final IamAccountService accountService; private final IamAccountRepository accountRepository; diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/UpdaterType.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/UpdaterType.java index b370099d5..cff249892 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/UpdaterType.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/UpdaterType.java @@ -24,6 +24,7 @@ public enum UpdaterType { ACCOUNT_REPLACE_PICTURE("Replace user picture"), ACCOUNT_REPLACE_USERNAME("Replace user username"), ACCOUNT_REPLACE_ACTIVE("Replace user active status"), + ACCOUNT_REPLACE_SERVICE_ACCOUNT("Replace user service account status"), ACCOUNT_ADD_OIDC_ID("Add OpenID Connect account to user"), ACCOUNT_ADD_SAML_ID("Add SAML account to user"), diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java index 7340ec897..63ee27279 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java @@ -16,6 +16,7 @@ package it.infn.mw.iam.api.scim.updater.builders; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_ACTIVE; +import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_SERVICE_ACCOUNT; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_EMAIL; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_FAMILY_NAME; import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_GIVEN_NAME; @@ -36,6 +37,7 @@ import it.infn.mw.iam.api.scim.updater.util.AccountFinder; import it.infn.mw.iam.api.scim.updater.util.IdNotBoundChecker; import it.infn.mw.iam.audit.events.account.ActiveReplacedEvent; +import it.infn.mw.iam.audit.events.account.ServiceAccountReplacedEvent; import it.infn.mw.iam.audit.events.account.EmailReplacedEvent; import it.infn.mw.iam.audit.events.account.FamilyNameReplacedEvent; import it.infn.mw.iam.audit.events.account.GivenNameReplacedEvent; @@ -146,4 +148,9 @@ public AccountUpdater active(boolean isActive) { account::isActive, account::setActive, isActive, ActiveReplacedEvent::new); } + public AccountUpdater serviceAccount(boolean isServiceAccount) { + return new DefaultAccountUpdater(account, ACCOUNT_REPLACE_SERVICE_ACCOUNT, + account::isServiceAccount, account::setServiceAccount, isServiceAccount, ServiceAccountReplacedEvent::new); + } + } diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java index d3533f044..11ef7126c 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java @@ -139,6 +139,7 @@ private void prepareAdders(List updaters, ScimUser user, IamAcco addUpdater(updaters, Objects::nonNull, user::getUserName, add::username); addUpdater(updaters, Objects::nonNull, user::getPassword, add::password); addUpdater(updaters, Objects::nonNull, user::getActive, add::active); + //addUpdater(updaters, Objects::nonNull, user::getServiceAccount, add::serviceAccount); if (user.hasEmails()) { addUpdater(updaters, Objects::nonNull, user.getEmails().get(0)::getValue, add::email); @@ -207,6 +208,7 @@ private void prepareReplacers(List updaters, ScimUser user, IamA addUpdater(updaters, Objects::nonNull, user::getUserName, replace::username); addUpdater(updaters, Objects::nonNull, user::getPassword, replace::password); addUpdater(updaters, Objects::nonNull, user::getActive, replace::active); + addUpdater(updaters, Objects::nonNull, user::getServiceAccount, replace::serviceAccount); if (user.hasEmails()) { addUpdater(updaters, Objects::nonNull, user.getEmails().get(0)::getValue, replace::email); diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/audit/events/account/ServiceAccountReplacedEvent.java b/iam-login-service/src/main/java/it/infn/mw/iam/audit/events/account/ServiceAccountReplacedEvent.java new file mode 100644 index 000000000..2a00d1e64 --- /dev/null +++ b/iam-login-service/src/main/java/it/infn/mw/iam/audit/events/account/ServiceAccountReplacedEvent.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2016-2021 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.infn.mw.iam.audit.events.account; + +import static it.infn.mw.iam.api.scim.updater.UpdaterType.ACCOUNT_REPLACE_SERVICE_ACCOUNT; + +import it.infn.mw.iam.api.scim.updater.UpdaterType; +import it.infn.mw.iam.persistence.model.IamAccount; + +public class ServiceAccountReplacedEvent extends AccountUpdatedEvent { + + private static final long serialVersionUID = 5681737929767602266L; + + private final Boolean serviceAccount; + + public ServiceAccountReplacedEvent(Object source, IamAccount account, Boolean serviceAccount) { + super(source, account, ACCOUNT_REPLACE_SERVICE_ACCOUNT, buildMessage(ACCOUNT_REPLACE_SERVICE_ACCOUNT, serviceAccount)); + this.serviceAccount = serviceAccount; + } + + public Boolean getServiceAccount() { + return serviceAccount; + } + + protected static String buildMessage(UpdaterType t, Boolean serviceAccount) { + return String.format("%s: %s", t.getDescription(), serviceAccount); + } +} diff --git a/iam-login-service/src/main/webapp/WEB-INF/views/iam/dashboard.jsp b/iam-login-service/src/main/webapp/WEB-INF/views/iam/dashboard.jsp index a9bf2d60d..cfc6b003e 100644 --- a/iam-login-service/src/main/webapp/WEB-INF/views/iam/dashboard.jsp +++ b/iam-login-service/src/main/webapp/WEB-INF/views/iam/dashboard.jsp @@ -136,6 +136,7 @@ +