diff options
author | GitHub Nightly Merge Action <actions@github.com> | 2022-10-05 03:20:11 +0300 |
---|---|---|
committer | GitHub Nightly Merge Action <actions@github.com> | 2022-10-05 03:20:11 +0300 |
commit | a9d0856b3d7c1788bac39ab291ff1e4c87f80061 (patch) | |
tree | 985425dd04e66b6b345a37980a680e799699ddf4 | |
parent | 7bc15efc132d7ad24231fa5438eff2669fc75dbe (diff) | |
parent | df2828c857a5c21cb32d18ec529b1dc07b0d113c (diff) |
Merge branch 'maintenance' into devel
-rw-r--r-- | AUTHORS.md | 1 | ||||
-rw-r--r-- | src/octoprint/access/users.py | 8 | ||||
-rw-r--r-- | src/octoprint/cli/user.py | 3 | ||||
-rw-r--r-- | src/octoprint/plugins/corewizard/static/js/corewizard.js | 11 | ||||
-rw-r--r-- | src/octoprint/plugins/corewizard/templates/corewizard_acl_wizard.jinja2 | 3 | ||||
-rw-r--r-- | src/octoprint/server/api/access.py | 2 | ||||
-rw-r--r-- | src/octoprint/static/js/app/viewmodels/access.js | 13 | ||||
-rw-r--r-- | src/octoprint/templates/snippets/settings/accesscontrol/users.jinja2 | 7 |
8 files changed, 40 insertions, 8 deletions
diff --git a/AUTHORS.md b/AUTHORS.md index 7d4bb1647..3fe4458b3 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -172,6 +172,7 @@ date of first contribution): * [Dawid Pieper](https://github.com/dawidpieper) * ["arrdem"](https://github.com/arrdem) * [Arkadiusz MiĆkiewicz](https://github.com/arekm) + * [Frederik Kemner](https://github.com/040medien) OctoPrint started off as a fork of [Cura](https://github.com/daid/Cura) by [Daid Braam](https://github.com/daid). Parts of its communication layer and diff --git a/src/octoprint/access/users.py b/src/octoprint/access/users.py index f3e96ee09..c7894e813 100644 --- a/src/octoprint/access/users.py +++ b/src/octoprint/access/users.py @@ -657,6 +657,9 @@ class FilebasedUserManager(UserManager): if username in self._users and not overwrite: raise UserAlreadyExists(username) + if not username.strip() or username != username.strip(): + raise InvalidUsername(username) + self._users[username] = User( username, UserManager.create_password_hash(password, settings=self._settings), @@ -1056,6 +1059,11 @@ class UserAlreadyExists(Exception): Exception.__init__(self, "User %s already exists" % username) +class InvalidUsername(Exception): + def __init__(self, username): + Exception.__init__(self, "Username '%s' is invalid" % username) + + class UnknownUser(Exception): def __init__(self, username): Exception.__init__(self, "Unknown user: %s" % username) diff --git a/src/octoprint/cli/user.py b/src/octoprint/cli/user.py index d07d2cba3..d0813464d 100644 --- a/src/octoprint/cli/user.py +++ b/src/octoprint/cli/user.py @@ -11,6 +11,7 @@ from octoprint.access.groups import FilebasedGroupManager from octoprint.access.users import ( CorruptUserStorage, FilebasedUserManager, + InvalidUsername, UnknownUser, UserAlreadyExists, ) @@ -126,6 +127,8 @@ def add_user_command(ctx, username, password, groups, permissions, is_admin): click.echo(f"\t{_user_to_line(user.as_dict())}") except UserAlreadyExists: click.echo(f"A user with the name {username} does already exist!", err=True) + except InvalidUsername: + click.echo(f"The username '{username}' is invalid!", err=True) @cli.command(name="remove") diff --git a/src/octoprint/plugins/corewizard/static/js/corewizard.js b/src/octoprint/plugins/corewizard/static/js/corewizard.js index ba87f2f04..370be77eb 100644 --- a/src/octoprint/plugins/corewizard/static/js/corewizard.js +++ b/src/octoprint/plugins/corewizard/static/js/corewizard.js @@ -16,8 +16,12 @@ $(function () { return self.password() !== self.confirmedPassword(); }); + self.providedUsername = ko.pureComputed(function () { + return self.username() && self.username().trim(); + }); + self.validUsername = ko.pureComputed(function () { - return self.username() && self.username().trim() !== ""; + return !self.username() || self.username() == self.username().trim(); }); self.validPassword = ko.pureComputed(function () { @@ -26,7 +30,10 @@ $(function () { self.validData = ko.pureComputed(function () { return ( - !self.passwordMismatch() && self.validUsername() && self.validPassword() + self.providedUsername() && + self.validUsername() && + !self.passwordMismatch() && + self.validPassword() ); }); diff --git a/src/octoprint/plugins/corewizard/templates/corewizard_acl_wizard.jinja2 b/src/octoprint/plugins/corewizard/templates/corewizard_acl_wizard.jinja2 index 1537989d2..4a98ff790 100644 --- a/src/octoprint/plugins/corewizard/templates/corewizard_acl_wizard.jinja2 +++ b/src/octoprint/plugins/corewizard/templates/corewizard_acl_wizard.jinja2 @@ -7,10 +7,11 @@ OctoPrint's settings: </p>{% endtrans %} <form class="form-horizontal" onsubmit="return false;"> - <div class="control-group" data-bind="css: {success: validUsername()}"> + <div class="control-group" data-bind="css: {error: !validUsername(), success: providedUsername() && validUsername()}"> <label class="control-label" for="first_run_username">{{ _('Username') }}</label> <div class="controls"> <input type="text" class="input-medium" data-bind="value: username, valueUpdate: 'afterkeydown', enable: !setup(), css: {disabled: setup()}"> + <span class="help-inline" data-bind="visible: !validUsername()">{{ _('Invalid username') }}</span> </div> </div> <div class="control-group" data-bind="css: {success: validPassword()}"> diff --git a/src/octoprint/server/api/access.py b/src/octoprint/server/api/access.py index 53d0c99eb..4c8bd86fd 100644 --- a/src/octoprint/server/api/access.py +++ b/src/octoprint/server/api/access.py @@ -152,6 +152,8 @@ def add_user(): userManager.add_user(name, password, active, permissions, groups) except users.UserAlreadyExists: abort(409) + except users.InvalidUsername: + abort(400, "Username invalid") return get_users() diff --git a/src/octoprint/static/js/app/viewmodels/access.js b/src/octoprint/static/js/app/viewmodels/access.js index 24240207d..498cc5748 100644 --- a/src/octoprint/static/js/app/viewmodels/access.js +++ b/src/octoprint/static/js/app/viewmodels/access.js @@ -45,6 +45,15 @@ $(function () { passwordMismatch: ko.pureComputed(function () { return self.editor.password() !== self.editor.repeatedPassword(); }), + providedUsername: ko.pureComputed(function () { + return self.editor.name() && self.editor.name().trim(); + }), + validUsername: ko.pureComputed(function () { + return ( + !self.editor.name() || + self.editor.name() == self.editor.name().trim() + ); + }), currentPasswordMismatch: ko.observable(false), apikey: ko.observable(undefined), active: ko.observable(undefined), @@ -87,8 +96,8 @@ $(function () { confirm: undefined, valid: ko.pureComputed(function () { return ( - self.editor.name() && - self.editor.name().trim() && + self.editor.providedUsername() && + self.editor.validUsername() && (!self.editor.new() || (self.editor.password() && self.editor.password().trim() && diff --git a/src/octoprint/templates/snippets/settings/accesscontrol/users.jinja2 b/src/octoprint/templates/snippets/settings/accesscontrol/users.jinja2 index 9c0ae8794..2e2684dc2 100644 --- a/src/octoprint/templates/snippets/settings/accesscontrol/users.jinja2 +++ b/src/octoprint/templates/snippets/settings/accesscontrol/users.jinja2 @@ -79,10 +79,11 @@ <div class="tab-content"> <div id="settings_accesscontrol_users_add_general" class="tab-pane active"> <form class="form-horizontal" onsubmit="return false;"> - <div class="control-group"> - <label class="control-label" for="settings-usersDialogAddUserName">{{ _('Username') }}</label> + <div class="control-group" data-bind="css: {error: !$root.access.users.editor.validUsername()}"> + <label class="control-label" for="settings-usersDialogAddUsername">{{ _('Username') }}</label> <div class="controls"> - <input type="text" class="input-block-level" id="settings-usersDialogAddUserName" data-bind="disable: !$root.access.users.editor.new(), value: $root.access.users.editor.name" required> + <input type="text" class="input-block-level" id="settings-usersDialogAddUsername" data-bind="disable: !$root.access.users.editor.new(), value: $root.access.users.editor.name, valueUpdate: 'afterkeydown'" required> + <span class="help-inline" data-bind="visible: !$root.access.users.editor.validUsername()">{{ _('Invalid username') }}</span> </div> </div> <div class="control-group" data-bind="visible: $root.access.users.editor.new()"> |