diff --git a/scm-ui-components/packages/ui-components/src/validation.js b/scm-ui-components/packages/ui-components/src/validation.js index 7fa4a262b9..561b0d79bc 100644 --- a/scm-ui-components/packages/ui-components/src/validation.js +++ b/scm-ui-components/packages/ui-components/src/validation.js @@ -1,5 +1,5 @@ // @flow -const nameRegex = /^([A-z0-9.\-_@]|[^ ]([A-z0-9.\-_@ ]*[A-z0-9.\-_@]|[^\s])?)$/; +const nameRegex = /^[A-Za-z0-9\.\-_][A-Za-z0-9\.\-_@]*$/; export const isNameValid = (name: string) => { return nameRegex.test(name); diff --git a/scm-ui-components/packages/ui-components/src/validation.test.js b/scm-ui-components/packages/ui-components/src/validation.test.js index c264b20a1c..8394c61854 100644 --- a/scm-ui-components/packages/ui-components/src/validation.test.js +++ b/scm-ui-components/packages/ui-components/src/validation.test.js @@ -5,6 +5,7 @@ describe("test name validation", () => { it("should return false", () => { // invalid names taken from ValidationUtilTest.java const invalidNames = [ + "@test", " test 123", " test 123 ", "test 123 ", @@ -35,10 +36,9 @@ describe("test name validation", () => { "Test123-git", "Test_user-123.git", "test@scm-manager.de", - "test 123", + "test123", "tt", "t", - "valid_name", "another1", "stillValid", diff --git a/scm-ui/public/locales/en/permissions.json b/scm-ui/public/locales/en/permissions.json deleted file mode 100644 index 6341bd93a4..0000000000 --- a/scm-ui/public/locales/en/permissions.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "permissions": { - "error-title": "Error", - "error-subtitle": "Unknown permissions error" - }, - "permission": { - "name": "User or Group", - "type": "Type", - "group-permission": "Group Permission" - }, - "edit-permission": { - "delete-button": "Delete", - "save-button": "Save Changes" - }, - "delete-permission-button": { - "label": "Delete", - "confirm-alert": { - "title": "Delete permission", - "message": "Do you really want to delete the permission?", - "submit": "Yes", - "cancel": "No" - } - }, - "add-permission": { - "add-permission-heading": "Add new Permission", - "submit-button": "Submit", - "name-input-invalid": "Permission is not allowed to start with an '@' or it already exists!" - } -} diff --git a/scm-ui/public/locales/en/repos.json b/scm-ui/public/locales/en/repos.json index 1eb8f7b828..98574129f6 100644 --- a/scm-ui/public/locales/en/repos.json +++ b/scm-ui/public/locales/en/repos.json @@ -43,5 +43,30 @@ "submit": "Yes", "cancel": "No" } - } + }, + "permission": { + "error-title": "Error", + "error-subtitle": "Unknown permissions error", + "name": "User or Group", + "type": "Type", + "group-permission": "Group Permission", + "edit-permission": { + "delete-button": "Delete", + "save-button": "Save Changes" + }, + "delete-permission-button": { + "label": "Delete", + "confirm-alert": { + "title": "Delete permission", + "message": "Do you really want to delete the permission?", + "submit": "Yes", + "cancel": "No" + } + }, + "add-permission": { + "add-permission-heading": "Add new Permission", + "submit-button": "Submit", + "name-input-invalid": "Permission is not allowed to be empty! If it is not empty, your input name is invalid or it already exists!" + } + } } diff --git a/scm-ui/src/repos/permissions/components/CreatePermissionForm.js b/scm-ui/src/repos/permissions/components/CreatePermissionForm.js index 088daea5ab..ab1411687e 100644 --- a/scm-ui/src/repos/permissions/components/CreatePermissionForm.js +++ b/scm-ui/src/repos/permissions/components/CreatePermissionForm.js @@ -7,6 +7,7 @@ import type { PermissionCollection, PermissionEntry } from "@scm-manager/ui-types"; +import * as validator from "./permissionValidation"; type Props = { t: string => string, @@ -18,7 +19,8 @@ type Props = { type State = { name: string, type: string, - groupPermission: boolean + groupPermission: boolean, + valid: boolean }; class CreatePermissionForm extends React.Component { @@ -28,7 +30,8 @@ class CreatePermissionForm extends React.Component { this.state = { name: "", type: "READ", - groupPermission: false + groupPermission: false, + valid: false }; } @@ -39,18 +42,15 @@ class CreatePermissionForm extends React.Component { return (

- {t("add-permission.add-permission-heading")} + {t("permission.add-permission.add-permission-heading")}

{ type={type ? type : "READ"} />
); } - isValid = () => { - if ( - this.state.name === null || - this.state.name === "" || - this.currentPermissionIncludeName() || - this.state.name.startsWith("@") - ) { - return true; - } - return false; - }; - - currentPermissionIncludeName = () => { - for (let i = 0; i < this.props.currentPermissions.length; i++) { - if ( - this.props.currentPermissions[i].name === this.state.name && - this.props.currentPermissions[i].groupPermission == - this.state.groupPermission - ) - return true; - } - return false; - }; - submit = e => { this.props.createPermission({ name: this.state.name, @@ -110,7 +86,8 @@ class CreatePermissionForm extends React.Component { this.setState({ name: "", type: "READ", - groupPermission: false + groupPermission: false, + valid: validator.isNameValid("") }); }; @@ -122,14 +99,24 @@ class CreatePermissionForm extends React.Component { handleNameChange = (name: string) => { this.setState({ - name: name + name: name, + valid: validator.isPermissionValid( + name, + this.state.groupPermission, + this.props.currentPermissions + ) }); }; handleGroupPermissionChange = (groupPermission: boolean) => { this.setState({ - groupPermission: groupPermission + groupPermission: groupPermission, + valid: validator.isPermissionValid( + this.state.name, + groupPermission, + this.props.currentPermissions + ) }); }; } -export default translate("permissions")(CreatePermissionForm); +export default translate("repos")(CreatePermissionForm); diff --git a/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js index 05831e9a07..a3ba8616c9 100644 --- a/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js +++ b/scm-ui/src/repos/permissions/components/buttons/DeletePermissionButton.js @@ -34,15 +34,15 @@ class DeletePermissionButton extends React.Component { confirmDelete = () => { const { t } = this.props; confirmAlert({ - title: t("delete-permission-button.confirm-alert.title"), - message: t("delete-permission-button.confirm-alert.message"), + title: t("permission.delete-permission-button.confirm-alert.title"), + message: t("permission.delete-permission-button.confirm-alert.message"), buttons: [ { - label: t("delete-permission-button.confirm-alert.submit"), + label: t("permission.delete-permission-button.confirm-alert.submit"), onClick: () => this.deletePermission() }, { - label: t("delete-permission-button.confirm-alert.cancel"), + label: t("permission.delete-permission-button.confirm-alert.cancel"), onClick: () => null } ] @@ -62,7 +62,7 @@ class DeletePermissionButton extends React.Component { } return ( @@ -70,4 +70,4 @@ class DeletePermissionButton extends React.Component { } } -export default translate("permissions")(DeletePermissionButton); +export default translate("repos")(DeletePermissionButton); diff --git a/scm-ui/src/repos/permissions/components/permissionValidation.js b/scm-ui/src/repos/permissions/components/permissionValidation.js new file mode 100644 index 0000000000..b74ae40988 --- /dev/null +++ b/scm-ui/src/repos/permissions/components/permissionValidation.js @@ -0,0 +1,23 @@ +// @flow +import { validation } from "@scm-manager/ui-components"; +import type { + PermissionCollection, +} from "@scm-manager/ui-types"; +const isNameValid = validation.isNameValid; + +export { isNameValid }; + +export const isPermissionValid = (name: string, groupPermission: boolean, permissions: PermissionCollection) => { + return isNameValid(name) && !currentPermissionIncludeName(name, groupPermission, permissions); +}; + +const currentPermissionIncludeName = (name: string, groupPermission: boolean, permissions: PermissionCollection) => { + for (let i = 0; i < permissions.length; i++) { + if ( + permissions[i].name === name && + permissions[i].groupPermission == groupPermission + ) + return true; + } + return false; +}; diff --git a/scm-ui/src/repos/permissions/components/permissionValidation.test.js b/scm-ui/src/repos/permissions/components/permissionValidation.test.js new file mode 100644 index 0000000000..036375a348 --- /dev/null +++ b/scm-ui/src/repos/permissions/components/permissionValidation.test.js @@ -0,0 +1,66 @@ +//@flow +import * as validator from "./permissionValidation"; + +describe("permission validation", () => { + it("should return true if permission is valid and does not exist", () => { + const permissions = []; + const name = "PermissionName"; + const groupPermission = false; + + expect( + validator.isPermissionValid(name, groupPermission, permissions) + ).toBe(true); + }); + + it("should return true if permission is valid and does not exists with same group permission", () => { + const permissions = [ + { + name: "PermissionName", + groupPermission: true, + type: "READ" + } + ]; + const name = "PermissionName"; + const groupPermission = false; + + expect( + validator.isPermissionValid(name, groupPermission, permissions) + ).toBe(true); + }); + + it("should return false if permission is valid but exists", () => { + const permissions = [ + { + name: "PermissionName", + groupPermission: false, + type: "READ" + } + ]; + const name = "PermissionName"; + const groupPermission = false; + + expect( + validator.isPermissionValid(name, groupPermission, permissions) + ).toBe(false); + }); + + it("should return false if permission does not exist but is invalid", () => { + const permissions = []; + const name = "@PermissionName"; + const groupPermission = false; + + expect( + validator.isPermissionValid(name, groupPermission, permissions) + ).toBe(false); + }); + + it("should return false if permission is not valid and does not exist", () => { + const permissions = []; + const name = "@PermissionName"; + const groupPermission = false; + + expect( + validator.isPermissionValid(name, groupPermission, permissions) + ).toBe(false); + }); +}); diff --git a/scm-ui/src/repos/permissions/containers/Permissions.js b/scm-ui/src/repos/permissions/containers/Permissions.js index ff4a40d6ad..e70e02f443 100644 --- a/scm-ui/src/repos/permissions/containers/Permissions.js +++ b/scm-ui/src/repos/permissions/containers/Permissions.js @@ -92,8 +92,8 @@ class Permissions extends React.Component { if (error) { return ( ); @@ -198,4 +198,4 @@ const mapDispatchToProps = dispatch => { export default connect( mapStateToProps, mapDispatchToProps -)(translate("permissions")(Permissions)); +)(translate("repos")(Permissions)); diff --git a/scm-ui/src/repos/permissions/containers/SinglePermission.js b/scm-ui/src/repos/permissions/containers/SinglePermission.js index 126270f844..9426fbcd9f 100644 --- a/scm-ui/src/repos/permissions/containers/SinglePermission.js +++ b/scm-ui/src/repos/permissions/containers/SinglePermission.js @@ -173,4 +173,4 @@ const mapDispatchToProps = dispatch => { export default connect( mapStateToProps, mapDispatchToProps -)(translate("permissions")(SinglePermission)); +)(translate("repos")(SinglePermission));