service: add user status

This lists all the users of the instances, along with the number
of networks they have.

Limited to 50 users to avoid flooding with thousands of messages
on large instances.
This commit is contained in:
delthas 2023-01-17 14:25:37 +01:00 committed by Simon Ser
parent 1ad2ee7ef5
commit 959baa964f
2 changed files with 42 additions and 0 deletions

View File

@ -407,6 +407,9 @@ character.
*-network* <name>
Select a network. By default, the current network is selected, if any.
*user status*
Show a list of users on this server. Only admins can query this information.
*user create* -username <username> -password <password> [options...]
Create a new soju user. Only admin users can create new accounts.
The _-username_ and _-password_ flags are mandatory.

View File

@ -272,6 +272,11 @@ func init() {
},
"user": {
children: serviceCommandSet{
"status": {
desc: "show a list of users and their current status",
handle: handleUserStatus,
admin: true,
},
"create": {
usage: "-username <username> -password <password> [-realname <realname>] [-admin]",
desc: "create a new soju user",
@ -874,6 +879,40 @@ func handleServiceSASLReset(ctx *serviceContext, params []string) error {
return nil
}
func handleUserStatus(ctx *serviceContext, params []string) error {
// Limit to a small amount of users to avoid sending
// thousands of messages on large instances.
users := make([]database.User, 0, 50)
ctx.user.srv.lock.Lock()
n := len(ctx.user.srv.users)
for _, user := range ctx.user.srv.users {
if len(users) == cap(users) {
break
}
users = append(users, user.User)
}
ctx.user.srv.lock.Unlock()
for _, user := range users {
line := user.Username
if user.Admin {
line += " (admin)"
}
networks, err := ctx.user.srv.db.ListNetworks(ctx, user.ID)
if err != nil {
return fmt.Errorf("could not get networks of user %q: %v", user.Username, err)
}
line += fmt.Sprintf(": %d networks", len(networks))
ctx.print(line)
}
if n > len(users) {
ctx.print(fmt.Sprintf("(%d more users omitted)", n-len(users)))
}
return nil
}
func handleUserCreate(ctx *serviceContext, params []string) error {
fs := newFlagSet()
username := fs.String("username", "", "")