More docs, more tests, more docs

This commit is contained in:
Philipp Heckel 2022-02-03 20:07:23 -05:00
parent 29c2fc5472
commit d714af43c9
6 changed files with 155 additions and 60 deletions

View file

@ -35,7 +35,7 @@ The command allows you to show the access control list, as well as change it, de
it is called.
Usage:
ntfy access # Shows the entire access control list
ntfy access # Shows access control list (alias: 'ntfy user list')
ntfy access USERNAME # Shows access control entries for USERNAME
ntfy access USERNAME TOPIC PERMISSION # Allow/deny access for USERNAME to TOPIC
@ -50,7 +50,7 @@ Arguments:
- deny (alias: none)
Examples:
ntfy access # Shows entire access control list
ntfy access # Shows access control list (alias: 'ntfy user list')
ntfy access phil # Shows access for user phil
ntfy access phil mytopic rw # Allow read-write access to mytopic for user phil
ntfy access everyone mytopic rw # Allow anonymous read-write access to mytopic
@ -82,6 +82,9 @@ func execUserAccess(c *cli.Context) error {
}
return resetAccess(c, manager, username, topic)
} else if perms == "" {
if topic != "" {
return errors.New("invalid syntax, please check 'ntfy access --help' for usage details")
}
return showAccess(c, manager, username)
}
return changeAccess(c, manager, username, topic, perms)
@ -97,13 +100,13 @@ func changeAccess(c *cli.Context, manager auth.Manager, username string, topic s
return err
}
if read && write {
fmt.Fprintf(c.App.Writer, "Granted read-write access to topic %s\n\n", topic)
fmt.Fprintf(c.App.ErrWriter, "Granted read-write access to topic %s\n\n", topic)
} else if read {
fmt.Fprintf(c.App.Writer, "Granted read-only access to topic %s\n\n", topic)
fmt.Fprintf(c.App.ErrWriter, "Granted read-only access to topic %s\n\n", topic)
} else if write {
fmt.Fprintf(c.App.Writer, "Granted write-only access to topic %s\n\n", topic)
fmt.Fprintf(c.App.ErrWriter, "Granted write-only access to topic %s\n\n", topic)
} else {
fmt.Fprintf(c.App.Writer, "Revoked all access to topic %s\n\n", topic)
fmt.Fprintf(c.App.ErrWriter, "Revoked all access to topic %s\n\n", topic)
}
return showUserAccess(c, manager, username)
}
@ -121,7 +124,7 @@ func resetAllAccess(c *cli.Context, manager auth.Manager) error {
if err := manager.ResetAccess("", ""); err != nil {
return err
}
fmt.Fprintln(c.App.Writer, "Reset access for all users")
fmt.Fprintln(c.App.ErrWriter, "Reset access for all users")
return nil
}
@ -129,7 +132,7 @@ func resetUserAccess(c *cli.Context, manager auth.Manager, username string) erro
if err := manager.ResetAccess(username, ""); err != nil {
return err
}
fmt.Fprintf(c.App.Writer, "Reset access for user %s\n\n", username)
fmt.Fprintf(c.App.ErrWriter, "Reset access for user %s\n\n", username)
return showUserAccess(c, manager, username)
}
@ -137,7 +140,7 @@ func resetUserTopicAccess(c *cli.Context, manager auth.Manager, username string,
if err := manager.ResetAccess(username, topic); err != nil {
return err
}
fmt.Fprintf(c.App.Writer, "Reset access for user %s and topic %s\n\n", username, topic)
fmt.Fprintf(c.App.ErrWriter, "Reset access for user %s and topic %s\n\n", username, topic)
return showUserAccess(c, manager, username)
}
@ -158,7 +161,9 @@ func showAllAccess(c *cli.Context, manager auth.Manager) error {
func showUserAccess(c *cli.Context, manager auth.Manager, username string) error {
users, err := manager.User(username)
if err != nil {
if err == auth.ErrNotFound {
return fmt.Errorf("user %s does not exist", username)
} else if err != nil {
return err
}
return showUsers(c, manager, []*auth.User{users})
@ -166,7 +171,7 @@ func showUserAccess(c *cli.Context, manager auth.Manager, username string) error
func showUsers(c *cli.Context, manager auth.Manager, users []*auth.User) error {
for _, user := range users {
fmt.Fprintf(c.App.Writer, "User %s (%s)\n", user.Name, user.Role)
fmt.Fprintf(c.App.ErrWriter, "User %s (%s)\n", user.Name, user.Role)
if user.Role == auth.RoleAdmin {
fmt.Fprintf(c.App.ErrWriter, "- read-write access to all topics (admin role)\n")
} else if len(user.Grants) > 0 {

View file

@ -99,6 +99,13 @@ Example:
Usage: "Shows a list of users",
Before: inheritRootReaderFunc,
Action: execUserList,
Description: `Shows a list of all configured users, including the everyone ('*') user.
This is a server-only command. It directly reads from the user.db as defined in the server config
file server.yml. The command only works if 'auth-file' is properly defined.
This command is an alias to calling 'ntfy access' (display access control list).
`,
},
},
Description: `Manage users of the ntfy server.
@ -111,7 +118,7 @@ The command allows you to add/remove/change users in the ntfy user database, as
passwords or roles.
Examples:
ntfy user list # Shows list of users
ntfy user list # Shows list of users (alias: 'ntfy access')
ntfy user add phil # Add regular user phil
ntfy user add --role=admin phil # Add admin user phil
ntfy user del phil # Delete user phil

View file

@ -28,7 +28,7 @@ func TestCLI_User_Add_Exists(t *testing.T) {
require.Nil(t, runUserCommand(app, conf, "add", "phil"))
require.Contains(t, stderr.String(), "user phil added with role user")
app, stdin, _, stderr = newTestApp()
app, stdin, _, _ = newTestApp()
stdin.WriteString("mypass\nmypass")
err := runUserCommand(app, conf, "add", "phil")
require.Error(t, err)
@ -73,6 +73,44 @@ func TestCLI_User_ChangePass(t *testing.T) {
require.Contains(t, stderr.String(), "changed password for user phil")
}
func TestCLI_User_ChangeRole(t *testing.T) {
s, conf, port := newTestServerWithAuth(t)
defer test.StopServer(t, s, port)
// Add user
app, stdin, _, stderr := newTestApp()
stdin.WriteString("mypass\nmypass")
require.Nil(t, runUserCommand(app, conf, "add", "phil"))
require.Contains(t, stderr.String(), "user phil added with role user")
// Change role
app, _, _, stderr = newTestApp()
require.Nil(t, runUserCommand(app, conf, "change-role", "phil", "admin"))
require.Contains(t, stderr.String(), "changed role for user phil to admin")
}
func TestCLI_User_Delete(t *testing.T) {
s, conf, port := newTestServerWithAuth(t)
defer test.StopServer(t, s, port)
// Add user
app, stdin, _, stderr := newTestApp()
stdin.WriteString("mypass\nmypass")
require.Nil(t, runUserCommand(app, conf, "add", "phil"))
require.Contains(t, stderr.String(), "user phil added with role user")
// Delete user
app, _, _, stderr = newTestApp()
require.Nil(t, runUserCommand(app, conf, "del", "phil"))
require.Contains(t, stderr.String(), "user phil removed")
// Delete user again (does not exist)
app, _, _, _ = newTestApp()
err := runUserCommand(app, conf, "del", "phil")
require.Error(t, err)
require.Contains(t, err.Error(), "user phil does not exist")
}
func newTestServerWithAuth(t *testing.T) (s *server.Server, conf *server.Config, port int) {
conf = server.NewConfig()
conf.AuthFile = filepath.Join(t.TempDir(), "user.db")