diff --git a/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java b/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java index 3e891426ee..0f60569b8f 100644 --- a/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java +++ b/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java @@ -25,6 +25,7 @@ package sonia.scm.security; import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.subject.SimplePrincipalCollection; @@ -48,6 +49,7 @@ import java.util.Set; * @author Sebastian Sdorra * @since 2.0.0 */ +@Slf4j @Extension public final class SyncingRealmHelper { @@ -133,6 +135,7 @@ public final class SyncingRealmHelper { if (userManager.contains(user.getName())) { User clone = user.clone(); if (!externalUserConverters.isEmpty()) { + log.debug("execute available user converters"); for (ExternalUserConverter converter : externalUserConverters) { clone = converter.convert(clone); } diff --git a/scm-ui/ui-webapp/src/users/components/UserForm.tsx b/scm-ui/ui-webapp/src/users/components/UserForm.tsx index e240e02953..1b4dac8bf9 100644 --- a/scm-ui/ui-webapp/src/users/components/UserForm.tsx +++ b/scm-ui/ui-webapp/src/users/components/UserForm.tsx @@ -23,9 +23,10 @@ */ import React from "react"; import { WithTranslation, withTranslation } from "react-i18next"; -import { User, Link } from "@scm-manager/ui-types"; +import { Link, User } from "@scm-manager/ui-types"; import { Checkbox, + ErrorNotification, InputField, Level, Modal, @@ -50,6 +51,7 @@ type State = { displayNameValidationError: boolean; passwordValid: boolean; showPasswordModal: boolean; + error?: Error; }; class UserForm extends React.Component { @@ -126,19 +128,34 @@ class UserForm extends React.Component { const { user, passwordValid } = this.state; event.preventDefault(); if (!this.isInvalid()) { - this.props.submitForm(this.state.user); if (user.password && passwordValid) { - setPassword((user._links.password as Link).href, user.password); - //TODO handle error + setPassword((user._links.password as Link).href, user.password).catch(); } + this.props.submitForm(this.state.user); } }; render() { const { loading, t } = this.props; - const { user, showPasswordModal, passwordValid } = this.state; + const { user, showPasswordModal, passwordValid, error } = this.state; const passwordChangeField = ; + const passwordModal = ( + this.setState({ user: { ...user, external: true } }, () => this.showPasswordModal(false))} + active={showPasswordModal} + title={t("userForm.modal.passwordRequired")} + footer={ + !!user.password && passwordValid && this.showPasswordModal(false)} + disabled={!this.state.passwordValid} + scrollToTop={false} + label={t("userForm.modal.setPassword")} + /> + } + /> + ); let nameField = null; let subtitle = null; if (!this.props.user) { @@ -160,30 +177,14 @@ class UserForm extends React.Component { subtitle = ; } - if (showPasswordModal) { - return ( - - this.setState({ user: { ...user, external: true } }, () => this.showPasswordModal(false)) - } - active={showPasswordModal} - title={"userForm.modal.passwordRequired"} - footer={ - !!user.password && passwordValid && this.showPasswordModal(false)} - disabled={!this.state.passwordValid} - scrollToTop={false} - label={t("userForm.modal.setPassword")} - /> - } - /> - ); + if (error) { + return ; } return ( <> {subtitle} + {showPasswordModal && passwordModal}
{nameField} @@ -298,8 +299,8 @@ class UserForm extends React.Component { external } }, - //Only show password modal if edit mode and external flag was changed to internal - () => !external && this.props.user?.external && this.showPasswordModal(true) + //Only show password modal if edit mode and external flag was changed to internal and password was not already set + () => !external && this.props.user?.external && !this.state.user.password && this.showPasswordModal(true) ); }; } diff --git a/scm-webapp/src/main/java/sonia/scm/user/InternalToExternalUserConverter.java b/scm-webapp/src/main/java/sonia/scm/user/InternalToExternalUserConverter.java index 02dfb2de27..b87e33bf78 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/InternalToExternalUserConverter.java +++ b/scm-webapp/src/main/java/sonia/scm/user/InternalToExternalUserConverter.java @@ -24,11 +24,13 @@ package sonia.scm.user; +import lombok.extern.slf4j.Slf4j; import sonia.scm.config.ScmConfiguration; import sonia.scm.plugin.Extension; import javax.inject.Inject; +@Slf4j @Extension public class InternalToExternalUserConverter implements ExternalUserConverter{ @@ -40,15 +42,15 @@ public class InternalToExternalUserConverter implements ExternalUserConverter{ } public User convert(User user) { - if (shouldNotConvertUser(user)) { - return user; + if (shouldConvertUser(user)) { + log.info("Convert internal user {} to external", user.getId()); + user.setExternal(true); + user.setPassword(null); } - user.setExternal(true); - user.setPassword(null); return user; } - private boolean shouldNotConvertUser(User user) { - return user.isExternal() || !scmConfiguration.isEnabledUserConverter(); + private boolean shouldConvertUser(User user) { + return !user.isExternal() && scmConfiguration.isEnabledUserConverter(); } }