Skip to content

Commit

Permalink
CLI: add user altname management
Browse files Browse the repository at this point in the history
  • Loading branch information
juliaschroeder committed Nov 21, 2023
1 parent 7c32a58 commit fef7240
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 12 deletions.
2 changes: 1 addition & 1 deletion api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

apiSpec = None # API specification
apiVersion = None # API specification version. Extracted from the OpenAPI document.
backendVersion = "1.14.0" # Backend version number
backendVersion = "1.14.1" # Backend version number


def _loadOpenApiSpec():
Expand Down
15 changes: 14 additions & 1 deletion cli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ def privstr():
cli.print(" "*indent+"aliases:"+(cli.col(" (none)", attrs=["dark"]) if len(user.aliases) == 0 else ""))
for alias in user.aliases:
cli.print(" "*indent+" "+alias.aliasname)
cli.print(" "*indent+"altnames:"+(cli.col(" (none)", attrs=["dark"]) if len(user.altnames) == 0 else ""))
for altname in user.altnames:
cli.print(" "*indent+" "+altname.altname)
cli.print(" "*indent+"roles:"+(cli.col(" (none)", attrs=["dark"]) if len(user.roles) == 0 else ""))
for role in user.roles:
cli.print(" "*indent+" "+role.name)
Expand Down Expand Up @@ -127,6 +130,8 @@ def _splitData(args):
"instead.", "yellow"))
data["aliases"] = attributes.pop("alias", None) or ()
data["aliases_rm"] = attributes.pop("remove_alias", None) or ()
data["altnames"] = attributes.pop("altname", None) or {}
data["altnames_rm"] = attributes.pop("remove_altname", None) or {}
data["props"] = attributes.pop("property", []) + attributes.pop("storeprop", [])
data["props_rm"] = attributes.pop("remove_property", []) + attributes.pop("remove_storeprop", [])
data["noldap"] = attributes.pop("no_ldap", False)
Expand Down Expand Up @@ -185,6 +190,7 @@ def cliUserCreate(args):
props.update(data["attributes"])
props["username"] = args.username
props["aliases"] = data["aliases"]
props["altnames"] = data["altnames"]
properties = data["properties"] = {}
if args.domain:
from .common import domainCandidates
Expand Down Expand Up @@ -400,7 +406,7 @@ def cliUserModify(args):
cli = args._cli
cli.require("DB")
from orm import DB
from orm.users import Aliases
from orm.users import Aliases, Altnames
ret, user = _getUser(args)
if ret:
return ret
Expand All @@ -427,6 +433,11 @@ def cliUserModify(args):
[Aliases(alias, user) for alias in data["aliases"] if alias not in existing]
if data["aliases_rm"]:
user.aliases = [alias for alias in user.aliases if alias.aliasname not in data["aliases_rm"]]
if data["altnames"]:
existing = {a.altname for a in user.altnames}
[Altnames(altname, user) for altname in data["altnames"] if altname not in existing]
if data["altnames_rm"]:
user.altnames = [altname for altname in user.altnames if altname.altname not in data["altnames_rm"]]
except ValueError as err:
cli.print(cli.col("Failed to update user: "+err.args[0], "red"))
return 1
Expand Down Expand Up @@ -524,6 +535,7 @@ def proptagAssignCompleter(*args, **kwargs):
parser.add_argument("--status", type=_cliParseStatus, help="User address status")

parser.add_argument("--alias", action="append", help="Add alias")
parser.add_argument("--altname", action="append", help="Add alternative name")
parser.add_argument("--property", action="append", type=assignment, metavar="propspec=value",
help="Set property defined by propspec to value").completer = proptagAssignCompleter
parser.add_argument("--storeprop", action="append", type=assignment, metavar="propspec=value",
Expand Down Expand Up @@ -583,6 +595,7 @@ def deviceParser(parent, action, handler, **kwargs):
modify.add_argument("--delete-chat-user", action="store_true", help="Permanently delete chat user")
modify.add_argument("--no-ldap", action="store_true", help="Unlink user from ldap object")
modify.add_argument("--remove-alias", metavar="ALIAS", action="append", help="Remove alias")
modify.add_argument("--remove-altname", metavar="ALTNAME", action="append", help="Remove alternative name")
modify.add_argument("--remove-property", action="append", metavar="propspec", help="Remove property from user")
modify.add_argument("--remove-storeprop", action="append", metavar="propspec", help="Remove property from user's store")
modify.add_argument("--username", help="Rename user")
Expand Down
12 changes: 10 additions & 2 deletions doc/man/grommunio-admin-user.1
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ ATTRIBUTE=<value>\f[R]] [\f[I]-s FIELD\f[R]] [\f[I]USERSPEC\f[R]]
.PD
\f[B]grommunio-admin user\f[R] \f[B]modify\f[R] [\f[I]<FIELDS>\f[R]]
[\f[I]--delete-chat-user\f[R]] [\f[I]--no-ldap\f[R]]
[\f[I]--remove-alias ALIAS\f[R]] [\f[I]--remove-property PROPSPEC\f[R]]
[\f[I]--remove-storeprop PROPSPEC\f[R]] \f[I]USERSPEC\f[R]
[\f[I]--remove-alias ALIAS\f[R]] [\f[I]--remove-altname ALTNAME\f[R]]
[\f[I]--remove-property PROPSPEC\f[R]] [\f[I]--remove-storeprop
PROPSPEC\f[R]] \f[I]USERSPEC\f[R]
.PD 0
.P
.PD
Expand Down Expand Up @@ -149,6 +150,9 @@ Detach user from LDAP object
\f[V]--remove-alias ALIAS\f[R]
Remove ALIAS from user (can be given multiple times)
.TP
\f[V]--remove-altname ALTNAME\f[R]
Remove ALTNAME from user (can be given multiple times)
.TP
\f[V]--remove-property PROPSPEC\f[R]
Remove property from user (can be given multiple times)
.TP
Expand Down Expand Up @@ -216,6 +220,10 @@ Either numeric value or one of \f[I]normal\f[R], \f[I]suspended\f[R],
\f[V]--alias ALIAS\f[R]
Add alias
.TP
\f[V]--altname ALTNAME\f[R]
Add ALTNAME to user alternative login name list (can be given multiple
times)
.TP
\f[V]--property propspec=value\f[R]
Set property defined by propspec to value
.TP
Expand Down
8 changes: 6 additions & 2 deletions doc/rst/grommunio-admin-user.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Synopsis
| **grommunio-admin user** **list** [*-f ATTRIBUTE=<value>*] [*-s FIELD*]
[*USERSPEC*]
| **grommunio-admin user** **modify** [*<FIELDS>*] [*--delete-chat-user*]
[*--no-ldap*] [*--remove-alias ALIAS*] [*--remove-property PROPSPEC*]
[*--remove-storeprop PROPSPEC*] *USERSPEC*
[*--no-ldap*] [*--remove-alias ALIAS*] [*--remove-altname ALTNAME*]
[*--remove-property PROPSPEC*] [*--remove-storeprop PROPSPEC*] *USERSPEC*
| **grommunio-admin user** **query** [*-f ATTRIBUTE=<value>*] [*--format FORMAT*]
[*--separator SEPARATOR*] [*-s FIELD*] [*ATTRIBUTE* …]
| **grommunio-admin user** **show** [*-f ATTRIBUTE=<value>*] [*-s FIELD*]
Expand Down Expand Up @@ -95,6 +95,8 @@ Options
Detach user from LDAP object
``--remove-alias ALIAS``
Remove ALIAS from user (can be given multiple times)
``--remove-altname ALTNAME``
Remove ALTNAME from user (can be given multiple times)
``--remove-property PROPSPEC``
Remove property from user (can be given multiple times)
``--remove-storeprop PROPSPEC``
Expand Down Expand Up @@ -140,6 +142,8 @@ Fields
*deleted* or *shared*.
``--alias ALIAS``
Add alias
``--altname ALTNAME``
Add ALTNAME to user alternative login name list (can be given multiple times)
``--property propspec=value``
Set property defined by propspec to value
``--storeprop propspec=value``
Expand Down
10 changes: 4 additions & 6 deletions orm/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,15 +864,13 @@ class Altnames(DataModel, DB.Base):

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

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

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

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

Expand Down

0 comments on commit fef7240

Please sign in to comment.