Add external flag to user config

This commit is contained in:
Eduard Heimbuch
2020-10-13 16:33:05 +02:00
parent 04a4add8ee
commit 3efe23e74d
7 changed files with 109 additions and 391 deletions

View File

@@ -24,12 +24,14 @@
package sonia.scm.user; package sonia.scm.user;
//~--- non-JDK imports --------------------------------------------------------
import com.github.sdorra.ssp.PermissionObject; import com.github.sdorra.ssp.PermissionObject;
import com.github.sdorra.ssp.StaticPermissions; import com.github.sdorra.ssp.StaticPermissions;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import sonia.scm.BasicPropertiesAware; import sonia.scm.BasicPropertiesAware;
import sonia.scm.ModelObject; import sonia.scm.ModelObject;
import sonia.scm.ReducedModelObject; import sonia.scm.ReducedModelObject;
@@ -41,12 +43,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import java.security.Principal; import java.security.Principal;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
*/
@StaticPermissions( @StaticPermissions(
value = "user", value = "user",
globalPermissions = {"create", "list", "autocomplete"}, globalPermissions = {"create", "list", "autocomplete"},
@@ -55,57 +51,36 @@ import java.security.Principal;
) )
@XmlRootElement(name = "users") @XmlRootElement(name = "users")
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject, ReducedModelObject @Getter
{ @Setter
@NoArgsConstructor
@AllArgsConstructor
public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject, ReducedModelObject {
/** Field description */
private static final long serialVersionUID = -3089541936726329663L; private static final long serialVersionUID = -3089541936726329663L;
//~--- constructors --------------------------------------------------------- private boolean active = true;
private boolean external;
private Long creationDate;
private String displayName;
private Long lastModified;
private String mail;
private String name;
private String password;
private String type;
/** public User(String name) {
* Constructs ...
*
*/
public User() {}
/**
* Constructs ...
*
*
* @param name
*/
public User(String name)
{
this.name = name; this.name = name;
this.displayName = name; this.displayName = name;
} }
/** public User(String name, String displayName, String mail) {
* Constructs ...
*
*
* @param name
* @param displayName
* @param mail
*/
public User(String name, String displayName, String mail)
{
this.name = name; this.name = name;
this.displayName = displayName; this.displayName = displayName;
this.mail = mail; this.mail = mail;
} }
/** public User(String name, String displayName, String mail, String password, String type, boolean active) {
* Constructs ...
*
*
* @param name
* @param displayName
* @param mail
*/
public User(String name, String displayName, String mail, String password, String type, boolean active)
{
this.name = name; this.name = name;
this.displayName = displayName; this.displayName = displayName;
this.mail = mail; this.mail = mail;
@@ -114,90 +89,57 @@ public class User extends BasicPropertiesAware implements Principal, ModelObject
this.active = active; this.active = active;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*
*/
@Override @Override
public User clone() public User clone() {
{ User user;
User user = null;
try try {
{
user = (User) super.clone(); user = (User) super.clone();
} } catch (CloneNotSupportedException ex) {
catch (CloneNotSupportedException ex)
{
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
return user; return user;
} }
/** public boolean copyProperties(User user) {
* Method description
*
*
* @param user
*
* @return
*/
public boolean copyProperties(User user)
{
return copyProperties(user, true); return copyProperties(user, true);
} }
/** public boolean copyProperties(User user, boolean copyPassword) {
* Method description
*
*
* @param user
* @param copyPassword
*
* @return
*/
public boolean copyProperties(User user, boolean copyPassword)
{
boolean result = false; boolean result = false;
if (user.isActive() != active) if (user.isActive() != active) {
{
result = true; result = true;
user.setActive(active); user.setActive(active);
} }
if (Util.isNotEquals(user.getDisplayName(), displayName)) if (user.isExternal() != external) {
{ result = true;
user.setExternal(external);
}
if (Util.isNotEquals(user.getDisplayName(), displayName)) {
result = true; result = true;
user.setDisplayName(displayName); user.setDisplayName(displayName);
} }
if (Util.isNotEquals(user.getMail(), mail)) if (Util.isNotEquals(user.getMail(), mail)) {
{
result = true; result = true;
user.setMail(mail); user.setMail(mail);
} }
if (Util.isNotEquals(user.getName(), name)) if (Util.isNotEquals(user.getName(), name)) {
{
result = true; result = true;
user.setName(name); user.setName(name);
} }
if (copyPassword && Util.isNotEquals(user.getPassword(), password)) if (copyPassword && Util.isNotEquals(user.getPassword(), password)) {
{
result = true; result = true;
user.setPassword(password); user.setPassword(password);
} }
if (Util.isNotEquals(user.getType(), type)) if (Util.isNotEquals(user.getType(), type)) {
{
result = true; result = true;
user.setType(type); user.setType(type);
} }
@@ -205,316 +147,65 @@ public class User extends BasicPropertiesAware implements Principal, ModelObject
return result; return result;
} }
/**
* {@inheritDoc}
*
*
* @param obj
*
* @return
*/
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj) {
{ if (obj == null) {
if (obj == null)
{
return false; return false;
} }
if (getClass() != obj.getClass()) if (getClass() != obj.getClass()) {
{
return false; return false;
} }
final User other = (User) obj; final User other = (User) obj;
return Objects.equal(name, other.name) return Objects.equal(name, other.name)
&& Objects.equal(displayName, other.displayName) && Objects.equal(displayName, other.displayName)
&& Objects.equal(mail, other.mail) && Objects.equal(mail, other.mail)
&& Objects.equal(type, other.type) && Objects.equal(type, other.type)
&& Objects.equal(active, other.active) && Objects.equal(active, other.active)
&& Objects.equal(password, other.password) && Objects.equal(password, other.password)
&& Objects.equal(creationDate, other.creationDate) && Objects.equal(creationDate, other.creationDate)
&& Objects.equal(lastModified, other.lastModified) && Objects.equal(lastModified, other.lastModified)
&& Objects.equal(properties, other.properties); && Objects.equal(properties, other.properties);
} }
/**
* {@inheritDoc}
*
*
* @return
*/
@Override @Override
public int hashCode() public int hashCode() {
{
return Objects.hashCode(name, displayName, mail, type, password, return Objects.hashCode(name, displayName, mail, type, password,
active, creationDate, lastModified, properties); active, creationDate, lastModified, properties);
} }
/**
* {@inheritDoc}
*
*
* @return
*/
@Override @Override
public String toString() public String toString() {
{
String pwd = (password != null) String pwd = (password != null)
? "(is set)" ? "(is set)"
: "(not set)"; : "(not set)";
//J- //J-
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this)
.add("name", name) .add("name", name)
.add("displayName",displayName) .add("displayName", displayName)
.add("mail", mail) .add("mail", mail)
.add("password", pwd) .add("password", pwd)
.add("type", type) .add("type", type)
.add("active", active) .add("active", active)
.add("creationDate", creationDate) .add("creationDate", creationDate)
.add("lastModified", lastModified) .add("lastModified", lastModified)
.add("properties", properties) .add("properties", properties)
.toString(); .toString();
//J+ //J+
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public Long getCreationDate()
{
return creationDate;
}
/**
* Method description
*
*
* @return
*/
public String getDisplayName()
{
return displayName;
}
/**
* Method description
*
*
* @return
*/
@Override @Override
public String getId() public boolean isValid() {
{
return name;
}
/**
* Method description
*
*
* @return
*/
@Override
public Long getLastModified()
{
return lastModified;
}
/**
* Method description
*
*
* @return
*/
public String getMail()
{
return mail;
}
/**
* Method description
*
*
* @return
*/
@Override
public String getName()
{
return name;
}
/**
* Method description
*
*
* @return
*/
public String getPassword()
{
return password;
}
/**
* Method description
*
*
* @return
*/
@Override
public String getType()
{
return type;
}
/**
* Returns false if the user is deactivated.
*
*
* @return false if the user is deactivated
* @since 1.16
*/
public boolean isActive()
{
return active;
}
/**
* Method description
*
*
* @return
*/
@Override
public boolean isValid()
{
return ValidationUtil.isNameValid(name) && Util.isNotEmpty(displayName) return ValidationUtil.isNameValid(name) && Util.isNotEmpty(displayName)
&& Util.isNotEmpty(type) && Util.isNotEmpty(type)
&& ((Util.isEmpty(mail)) || ValidationUtil.isMailAddressValid(mail)); && ((Util.isEmpty(mail)) || ValidationUtil.isMailAddressValid(mail));
} }
//~--- set methods ---------------------------------------------------------- @Override
public String getId() {
/** return name;
* Activate or deactive this user.
*
*
* @param active false to deactivate the user.
* @since 1.6
*/
public void setActive(boolean active)
{
this.active = active;
} }
/**
* Method description
*
*
* @param creationDate
*/
public void setCreationDate(Long creationDate)
{
this.creationDate = creationDate;
}
/**
* Method description
*
*
* @param displayName
*/
public void setDisplayName(String displayName)
{
this.displayName = displayName;
}
/**
* Method description
*
*
* @param lastModified
*/
public void setLastModified(Long lastModified)
{
this.lastModified = lastModified;
}
/**
* Method description
*
*
* @param mail
*/
public void setMail(String mail)
{
this.mail = mail;
}
/**
* Method description
*
*
*
* @param name
*/
public void setName(String name)
{
this.name = name;
}
/**
* Method description
*
*
* @param password
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* Method description
*
*
* @param type
*/
public void setType(String type)
{
this.type = type;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private boolean active = true;
/** Field description */
private Long creationDate;
/** Field description */
private String displayName;
/** Field description */
private Long lastModified;
/** Field description */
private String mail;
/** Field description */
private String name;
/** Field description */
private String password;
/** Field description */
private String type;
} }

View File

@@ -39,5 +39,6 @@ export type User = {
type?: string; type?: string;
creationDate?: string; creationDate?: string;
lastModified?: string; lastModified?: string;
external?: boolean;
_links: Links; _links: Links;
}; };

View File

@@ -6,6 +6,7 @@
"password": "Passwort", "password": "Passwort",
"active": "Aktiv", "active": "Aktiv",
"inactive": "Inaktiv", "inactive": "Inaktiv",
"externalFlag": "Extern",
"type": "Typ", "type": "Typ",
"creationDate": "Erstellt", "creationDate": "Erstellt",
"lastModified": "Zuletzt bearbeitet" "lastModified": "Zuletzt bearbeitet"
@@ -20,7 +21,8 @@
"displayNameHelpText": "Anzeigename des Benutzers", "displayNameHelpText": "Anzeigename des Benutzers",
"mailHelpText": "E-Mail Adresse des Benutzers", "mailHelpText": "E-Mail Adresse des Benutzers",
"adminHelpText": "Ein Administrator kann Repositories, Gruppen und Benutzer erstellen, bearbeiten und löschen.", "adminHelpText": "Ein Administrator kann Repositories, Gruppen und Benutzer erstellen, bearbeiten und löschen.",
"activeHelpText": "Aktivierung oder Deaktivierung eines Benutzers" "activeHelpText": "Aktivierung oder Deaktivierung eines Benutzers",
"externalFlagHelpText": "Der Benutzer wird über ein Fremdsystem verwaltet."
}, },
"users": { "users": {
"title": "Benutzer", "title": "Benutzer",

View File

@@ -6,6 +6,7 @@
"password": "Password", "password": "Password",
"active": "Active", "active": "Active",
"inactive": "Inactive", "inactive": "Inactive",
"externalFlag": "External",
"type": "Type", "type": "Type",
"creationDate": "Creation Date", "creationDate": "Creation Date",
"lastModified": "Last Modified" "lastModified": "Last Modified"
@@ -20,7 +21,8 @@
"displayNameHelpText": "Display name of the user.", "displayNameHelpText": "Display name of the user.",
"mailHelpText": "Email address of the user.", "mailHelpText": "Email address of the user.",
"adminHelpText": "An administrator is able to create, modify and delete repositories, groups and users.", "adminHelpText": "An administrator is able to create, modify and delete repositories, groups and users.",
"activeHelpText": "Activate or deactivate the user." "activeHelpText": "Activate or deactivate the user.",
"externalFlagHelpText": "This user is managed by an external system."
}, },
"users": { "users": {
"title": "Users", "title": "Users",

View File

@@ -60,6 +60,7 @@ class UserForm extends React.Component<Props, State> {
mail: "", mail: "",
password: "", password: "",
active: true, active: true,
external: false,
_links: {} _links: {}
}, },
mailValidationError: false, mailValidationError: false,
@@ -80,14 +81,10 @@ class UserForm extends React.Component<Props, State> {
} }
} }
isFalsy(value) {
return !value;
}
createUserComponentsAreInvalid = () => { createUserComponentsAreInvalid = () => {
const user = this.state.user; const user = this.state.user;
if (!this.props.user) { if (!this.props.user) {
return this.state.nameValidationError || this.isFalsy(user.name) || !this.state.passwordValid; return this.state.nameValidationError || !user.name || !this.state.passwordValid;
} else { } else {
return false; return false;
} }
@@ -99,7 +96,8 @@ class UserForm extends React.Component<Props, State> {
return ( return (
this.props.user.displayName === user.displayName && this.props.user.displayName === user.displayName &&
this.props.user.mail === user.mail && this.props.user.mail === user.mail &&
this.props.user.active === user.active this.props.user.active === user.active &&
this.props.user.external === user.external
); );
} else { } else {
return false; return false;
@@ -113,8 +111,8 @@ class UserForm extends React.Component<Props, State> {
this.editUserComponentsAreUnchanged() || this.editUserComponentsAreUnchanged() ||
this.state.mailValidationError || this.state.mailValidationError ||
this.state.displayNameValidationError || this.state.displayNameValidationError ||
this.isFalsy(user.displayName) || !user.displayName ||
this.isFalsy(user.mail) !user.mail
); );
}; };
@@ -181,7 +179,7 @@ class UserForm extends React.Component<Props, State> {
</div> </div>
{passwordChangeField} {passwordChangeField}
<div className="columns"> <div className="columns">
<div className="column"> <div className="column is-half">
<Checkbox <Checkbox
label={t("user.active")} label={t("user.active")}
onChange={this.handleActiveChange} onChange={this.handleActiveChange}
@@ -189,6 +187,14 @@ class UserForm extends React.Component<Props, State> {
helpText={t("help.activeHelpText")} helpText={t("help.activeHelpText")}
/> />
</div> </div>
<div className="column is-half">
<Checkbox
label={t("user.externalFlag")}
onChange={this.handleExternalFlagChange}
checked={!!user?.external && user.external}
helpText={t("help.externalFlagHelpText")}
/>
</div>
</div> </div>
<Level right={<SubmitButton disabled={!this.isValid()} loading={loading} label={t("userForm.button")} />} /> <Level right={<SubmitButton disabled={!this.isValid()} loading={loading} label={t("userForm.button")} />} />
</form> </form>
@@ -232,7 +238,7 @@ class UserForm extends React.Component<Props, State> {
...this.state.user, ...this.state.user,
password password
}, },
passwordValid: !this.isFalsy(password) && passwordValid passwordValid: !!password && passwordValid
}); });
}; };
@@ -244,6 +250,15 @@ class UserForm extends React.Component<Props, State> {
} }
}); });
}; };
handleExternalFlagChange = (external: boolean) => {
this.setState({
user: {
...this.state.user,
external
}
});
};
} }
export default withTranslation("users")(UserForm); export default withTranslation("users")(UserForm);

View File

@@ -61,6 +61,12 @@ class Details extends React.Component<Props> {
<Checkbox checked={user.active} /> <Checkbox checked={user.active} />
</td> </td>
</tr> </tr>
<tr>
<th>{t("user.externalFlag")}</th>
<td>
<Checkbox checked={!!user?.external && user.external} />
</td>
</tr>
<tr> <tr>
<th>{t("user.type")}</th> <th>{t("user.type")}</th>
<td>{user.type}</td> <td>{user.type}</td>

View File

@@ -41,6 +41,7 @@ import java.time.Instant;
@NoArgsConstructor @Getter @Setter @NoArgsConstructor @Getter @Setter
public class UserDto extends HalRepresentation { public class UserDto extends HalRepresentation {
private boolean active; private boolean active;
private boolean external;
private Instant creationDate; private Instant creationDate;
@NotEmpty @NotEmpty
private String displayName; private String displayName;