Skip to content

Commit fef7240

Browse files
CLI: add user altname management
1 parent 7c32a58 commit fef7240

File tree

5 files changed

+35
-12
lines changed

5 files changed

+35
-12
lines changed

api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
apiSpec = None # API specification
99
apiVersion = None # API specification version. Extracted from the OpenAPI document.
10-
backendVersion = "1.14.0" # Backend version number
10+
backendVersion = "1.14.1" # Backend version number
1111

1212

1313
def _loadOpenApiSpec():

cli/user.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ def privstr():
8888
cli.print(" "*indent+"aliases:"+(cli.col(" (none)", attrs=["dark"]) if len(user.aliases) == 0 else ""))
8989
for alias in user.aliases:
9090
cli.print(" "*indent+" "+alias.aliasname)
91+
cli.print(" "*indent+"altnames:"+(cli.col(" (none)", attrs=["dark"]) if len(user.altnames) == 0 else ""))
92+
for altname in user.altnames:
93+
cli.print(" "*indent+" "+altname.altname)
9194
cli.print(" "*indent+"roles:"+(cli.col(" (none)", attrs=["dark"]) if len(user.roles) == 0 else ""))
9295
for role in user.roles:
9396
cli.print(" "*indent+" "+role.name)
@@ -127,6 +130,8 @@ def _splitData(args):
127130
"instead.", "yellow"))
128131
data["aliases"] = attributes.pop("alias", None) or ()
129132
data["aliases_rm"] = attributes.pop("remove_alias", None) or ()
133+
data["altnames"] = attributes.pop("altname", None) or {}
134+
data["altnames_rm"] = attributes.pop("remove_altname", None) or {}
130135
data["props"] = attributes.pop("property", []) + attributes.pop("storeprop", [])
131136
data["props_rm"] = attributes.pop("remove_property", []) + attributes.pop("remove_storeprop", [])
132137
data["noldap"] = attributes.pop("no_ldap", False)
@@ -185,6 +190,7 @@ def cliUserCreate(args):
185190
props.update(data["attributes"])
186191
props["username"] = args.username
187192
props["aliases"] = data["aliases"]
193+
props["altnames"] = data["altnames"]
188194
properties = data["properties"] = {}
189195
if args.domain:
190196
from .common import domainCandidates
@@ -400,7 +406,7 @@ def cliUserModify(args):
400406
cli = args._cli
401407
cli.require("DB")
402408
from orm import DB
403-
from orm.users import Aliases
409+
from orm.users import Aliases, Altnames
404410
ret, user = _getUser(args)
405411
if ret:
406412
return ret
@@ -427,6 +433,11 @@ def cliUserModify(args):
427433
[Aliases(alias, user) for alias in data["aliases"] if alias not in existing]
428434
if data["aliases_rm"]:
429435
user.aliases = [alias for alias in user.aliases if alias.aliasname not in data["aliases_rm"]]
436+
if data["altnames"]:
437+
existing = {a.altname for a in user.altnames}
438+
[Altnames(altname, user) for altname in data["altnames"] if altname not in existing]
439+
if data["altnames_rm"]:
440+
user.altnames = [altname for altname in user.altnames if altname.altname not in data["altnames_rm"]]
430441
except ValueError as err:
431442
cli.print(cli.col("Failed to update user: "+err.args[0], "red"))
432443
return 1
@@ -524,6 +535,7 @@ def proptagAssignCompleter(*args, **kwargs):
524535
parser.add_argument("--status", type=_cliParseStatus, help="User address status")
525536

526537
parser.add_argument("--alias", action="append", help="Add alias")
538+
parser.add_argument("--altname", action="append", help="Add alternative name")
527539
parser.add_argument("--property", action="append", type=assignment, metavar="propspec=value",
528540
help="Set property defined by propspec to value").completer = proptagAssignCompleter
529541
parser.add_argument("--storeprop", action="append", type=assignment, metavar="propspec=value",
@@ -583,6 +595,7 @@ def deviceParser(parent, action, handler, **kwargs):
583595
modify.add_argument("--delete-chat-user", action="store_true", help="Permanently delete chat user")
584596
modify.add_argument("--no-ldap", action="store_true", help="Unlink user from ldap object")
585597
modify.add_argument("--remove-alias", metavar="ALIAS", action="append", help="Remove alias")
598+
modify.add_argument("--remove-altname", metavar="ALTNAME", action="append", help="Remove alternative name")
586599
modify.add_argument("--remove-property", action="append", metavar="propspec", help="Remove property from user")
587600
modify.add_argument("--remove-storeprop", action="append", metavar="propspec", help="Remove property from user's store")
588601
modify.add_argument("--username", help="Rename user")

doc/man/grommunio-admin-user.1

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ ATTRIBUTE=<value>\f[R]] [\f[I]-s FIELD\f[R]] [\f[I]USERSPEC\f[R]]
4949
.PD
5050
\f[B]grommunio-admin user\f[R] \f[B]modify\f[R] [\f[I]<FIELDS>\f[R]]
5151
[\f[I]--delete-chat-user\f[R]] [\f[I]--no-ldap\f[R]]
52-
[\f[I]--remove-alias ALIAS\f[R]] [\f[I]--remove-property PROPSPEC\f[R]]
53-
[\f[I]--remove-storeprop PROPSPEC\f[R]] \f[I]USERSPEC\f[R]
52+
[\f[I]--remove-alias ALIAS\f[R]] [\f[I]--remove-altname ALTNAME\f[R]]
53+
[\f[I]--remove-property PROPSPEC\f[R]] [\f[I]--remove-storeprop
54+
PROPSPEC\f[R]] \f[I]USERSPEC\f[R]
5455
.PD 0
5556
.P
5657
.PD
@@ -149,6 +150,9 @@ Detach user from LDAP object
149150
\f[V]--remove-alias ALIAS\f[R]
150151
Remove ALIAS from user (can be given multiple times)
151152
.TP
153+
\f[V]--remove-altname ALTNAME\f[R]
154+
Remove ALTNAME from user (can be given multiple times)
155+
.TP
152156
\f[V]--remove-property PROPSPEC\f[R]
153157
Remove property from user (can be given multiple times)
154158
.TP
@@ -216,6 +220,10 @@ Either numeric value or one of \f[I]normal\f[R], \f[I]suspended\f[R],
216220
\f[V]--alias ALIAS\f[R]
217221
Add alias
218222
.TP
223+
\f[V]--altname ALTNAME\f[R]
224+
Add ALTNAME to user alternative login name list (can be given multiple
225+
times)
226+
.TP
219227
\f[V]--property propspec=value\f[R]
220228
Set property defined by propspec to value
221229
.TP

doc/rst/grommunio-admin-user.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ Synopsis
2323
| **grommunio-admin user** **list** [*-f ATTRIBUTE=<value>*] [*-s FIELD*]
2424
[*USERSPEC*]
2525
| **grommunio-admin user** **modify** [*<FIELDS>*] [*--delete-chat-user*]
26-
[*--no-ldap*] [*--remove-alias ALIAS*] [*--remove-property PROPSPEC*]
27-
[*--remove-storeprop PROPSPEC*] *USERSPEC*
26+
[*--no-ldap*] [*--remove-alias ALIAS*] [*--remove-altname ALTNAME*]
27+
[*--remove-property PROPSPEC*] [*--remove-storeprop PROPSPEC*] *USERSPEC*
2828
| **grommunio-admin user** **query** [*-f ATTRIBUTE=<value>*] [*--format FORMAT*]
2929
[*--separator SEPARATOR*] [*-s FIELD*] [*ATTRIBUTE* …]
3030
| **grommunio-admin user** **show** [*-f ATTRIBUTE=<value>*] [*-s FIELD*]
@@ -95,6 +95,8 @@ Options
9595
Detach user from LDAP object
9696
``--remove-alias ALIAS``
9797
Remove ALIAS from user (can be given multiple times)
98+
``--remove-altname ALTNAME``
99+
Remove ALTNAME from user (can be given multiple times)
98100
``--remove-property PROPSPEC``
99101
Remove property from user (can be given multiple times)
100102
``--remove-storeprop PROPSPEC``
@@ -140,6 +142,8 @@ Fields
140142
*deleted* or *shared*.
141143
``--alias ALIAS``
142144
Add alias
145+
``--altname ALTNAME``
146+
Add ALTNAME to user alternative login name list (can be given multiple times)
143147
``--property propspec=value``
144148
Set property defined by propspec to value
145149
``--storeprop propspec=value``

orm/users.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -864,15 +864,13 @@ class Altnames(DataModel, DB.Base):
864864

865865
userID = Column("user_id", INTEGER(unsigned=True), ForeignKey(Users.ID, ondelete="cascade", onupdate="cascade"), primary_key=True)
866866
altname = Column("altname", VARCHAR(320), primary_key=True)
867-
magic = Column("magic", INTEGER(unsigned=True), primary_key=True, server_default="0")
867+
magic = Column("magic", INTEGER(unsigned=True), server_default="0")
868868

869869
user = relationship(Users, back_populates="altnames")
870870

871-
@validates("altname")
872-
def validateAltname(self, key, value, *args):
873-
if Altnames.query.filter(Altnames.altname == value, Altnames.userID != self.userID).count():
874-
raise ValueError("Alternative name is already in use")
875-
return value or None
871+
def __init__(self, altname, user, *args, **kwargs):
872+
self.user = user
873+
self.altname = altname
876874

877875
_dictmapping_ = ((Text("altname", flags="patch"), Int("magic"),),)
878876

0 commit comments

Comments
 (0)