Skip to content

Commit

Permalink
main: add role info
Browse files Browse the repository at this point in the history
- add list roles command
- add roles associated with users in list users
  • Loading branch information
frederikhs committed Nov 2, 2022
1 parent 4239225 commit 4cd8816
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ Features
- Deleting existing users
- Extending the validity of existing users
- Resetting passwords of existing users
- Listing of existing users
- Listing existing users and their associated roles
- Listing all configured hosts
- Listing existing roles

## Installation

Expand Down
5 changes: 3 additions & 2 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"os"
"strings"
)

var listCmd = &cobra.Command{
Expand Down Expand Up @@ -36,11 +37,11 @@ func listUsersForConnection(conn *database.DBConn) {
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"username", "valid until"})
table.SetHeader([]string{"username", "valid until", "roles"})

for _, u := range users {
table.Append([]string{
u.Username, *u.ValidUntil,
u.Username, *u.ValidUntil, strings.Join(u.Roles, ", "),
})
}

Expand Down
52 changes: 52 additions & 0 deletions cmd/roles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"github.com/hiperdk/pg_user/database"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"
"os"
)

var rolesCmd = &cobra.Command{
Use: "roles [host]",
Short: "List database roles",
Long: `List database roles for a specific database`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
cmd.Println(cmd.UsageString())
os.Exit(1)
}

host := args[0]

conn := database.GetDatabaseEntryConnection(host)
if conn == nil {
cmd.Println("no hosts found by that name")
os.Exit(1)
}

listRolesForConnection(conn)
},
}

func listRolesForConnection(conn *database.DBConn) {
roles, err := conn.GetAllRoles()
if err != nil {
panic(err)
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"rolename"})

for _, r := range roles {
table.Append([]string{
r,
})
}

table.Render()
}

func init() {
rootCmd.AddCommand(rolesCmd)
}
37 changes: 34 additions & 3 deletions database/query.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package database

import (
"encoding/json"
"fmt"
"github.com/jmoiron/sqlx"
"time"
)

type User struct {
Username string `db:"usename"`
ValidUntil *string `db:"valuntil"`
Username string `db:"usename"`
ValidUntil *string `db:"valuntil"`
RolesJson string `db:"roles"`
Roles []string `db:"-"`
}

func (u *User) ParseValidUntil() (*string, error) {
Expand All @@ -30,7 +33,16 @@ func (u *User) ParseValidUntil() (*string, error) {

func (conn *DBConn) GetAllUsers() ([]User, error) {
var users []User
err := conn.db.Select(&users, "SELECT usename, valuntil FROM pg_catalog.pg_user WHERE usesuper = false ORDER BY valuntil, usename")
err := conn.db.Select(&users, `
SELECT a.rolname AS usename,
a.rolvaliduntil AS valuntil,
json_agg(c.rolname) AS roles
FROM pg_roles a
INNER JOIN pg_auth_members b ON a.oid = b.member
INNER JOIN pg_roles c ON b.roleid = c.oid
GROUP BY 1, 2
ORDER BY 2, 1
`)
if err != nil {
return nil, err
}
Expand All @@ -42,11 +54,30 @@ func (conn *DBConn) GetAllUsers() ([]User, error) {
}

users[i].ValidUntil = validUntil

// convert postgres json aggregation to string slice
var roles []string
err = json.Unmarshal([]byte(users[i].RolesJson), &roles)
if err != nil {
return nil, err
}

users[i].Roles = roles
}

return users, nil
}

func (conn *DBConn) GetAllRoles() ([]string, error) {
var roles []string
err := conn.db.Select(&roles, "SELECT rolname FROM pg_roles ORDER BY rolname")
if err != nil {
return nil, err
}

return roles, nil
}

func (conn *DBConn) CreateUser(username string, validDuration time.Duration, roles []string) (string, time.Time, error) {
tx := conn.db.MustBegin()

Expand Down

0 comments on commit 4cd8816

Please sign in to comment.