Replace read/write flags with Permission
This commit is contained in:
parent
1733323132
commit
4b9d40464c
13 changed files with 194 additions and 152 deletions
|
@ -1,6 +1,7 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"heckel.io/ntfy/user"
|
||||
"io/fs"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
@ -66,8 +67,7 @@ type Config struct {
|
|||
CacheBatchSize int
|
||||
CacheBatchTimeout time.Duration
|
||||
AuthFile string
|
||||
AuthDefaultRead bool
|
||||
AuthDefaultWrite bool
|
||||
AuthDefault user.Permission
|
||||
AttachmentCacheDir string
|
||||
AttachmentTotalSizeLimit int64
|
||||
AttachmentFileSizeLimit int64
|
||||
|
@ -127,8 +127,7 @@ func NewConfig() *Config {
|
|||
CacheBatchSize: 0,
|
||||
CacheBatchTimeout: 0,
|
||||
AuthFile: "",
|
||||
AuthDefaultRead: true,
|
||||
AuthDefaultWrite: true,
|
||||
AuthDefault: user.NewPermission(true, true),
|
||||
AttachmentCacheDir: "",
|
||||
AttachmentTotalSizeLimit: DefaultAttachmentTotalSizeLimit,
|
||||
AttachmentFileSizeLimit: DefaultAttachmentFileSizeLimit,
|
||||
|
|
|
@ -41,8 +41,8 @@ var (
|
|||
errHTTPBadRequestDelayTooLarge = &errHTTP{40006, http.StatusBadRequest, "invalid delay parameter: too large, please refer to the docs", "https://ntfy.sh/docs/publish/#scheduled-delivery"}
|
||||
errHTTPBadRequestPriorityInvalid = &errHTTP{40007, http.StatusBadRequest, "invalid priority parameter", "https://ntfy.sh/docs/publish/#message-priority"}
|
||||
errHTTPBadRequestSinceInvalid = &errHTTP{40008, http.StatusBadRequest, "invalid since parameter", "https://ntfy.sh/docs/subscribe/api/#fetch-cached-messages"}
|
||||
errHTTPBadRequestTopicInvalid = &errHTTP{40009, http.StatusBadRequest, "invalid topic: topic invalid", ""}
|
||||
errHTTPBadRequestTopicDisallowed = &errHTTP{40010, http.StatusBadRequest, "invalid topic: topic name is disallowed", ""}
|
||||
errHTTPBadRequestTopicInvalid = &errHTTP{40009, http.StatusBadRequest, "invalid request: topic invalid", ""}
|
||||
errHTTPBadRequestTopicDisallowed = &errHTTP{40010, http.StatusBadRequest, "invalid request: topic name is disallowed", ""}
|
||||
errHTTPBadRequestMessageNotUTF8 = &errHTTP{40011, http.StatusBadRequest, "invalid message: message must be UTF-8 encoded", ""}
|
||||
errHTTPBadRequestAttachmentURLInvalid = &errHTTP{40013, http.StatusBadRequest, "invalid request: attachment URL is invalid", "https://ntfy.sh/docs/publish/#attachments"}
|
||||
errHTTPBadRequestAttachmentsDisallowed = &errHTTP{40014, http.StatusBadRequest, "invalid request: attachments not allowed", "https://ntfy.sh/docs/config/#attachments"}
|
||||
|
@ -56,6 +56,7 @@ var (
|
|||
errHTTPBadRequestSignupNotEnabled = &errHTTP{40022, http.StatusBadRequest, "invalid request: signup not enabled", "https://ntfy.sh/docs/config"}
|
||||
errHTTPBadRequestNoTokenProvided = &errHTTP{40023, http.StatusBadRequest, "invalid request: no token provided", ""}
|
||||
errHTTPBadRequestJSONInvalid = &errHTTP{40024, http.StatusBadRequest, "invalid request: request body must be valid JSON", ""}
|
||||
errHTTPBadRequestPermissionInvalid = &errHTTP{40025, http.StatusBadRequest, "invalid request: incorrect permission string", ""}
|
||||
errHTTPNotFound = &errHTTP{40401, http.StatusNotFound, "page not found", ""}
|
||||
errHTTPUnauthorized = &errHTTP{40101, http.StatusUnauthorized, "unauthorized", "https://ntfy.sh/docs/publish/#authentication"}
|
||||
errHTTPForbidden = &errHTTP{40301, http.StatusForbidden, "forbidden", "https://ntfy.sh/docs/publish/#authentication"}
|
||||
|
|
|
@ -165,7 +165,7 @@ func New(conf *Config) (*Server, error) {
|
|||
}
|
||||
var userManager *user.Manager
|
||||
if conf.AuthFile != "" {
|
||||
userManager, err = user.NewManager(conf.AuthFile, conf.AuthDefaultRead, conf.AuthDefaultWrite)
|
||||
userManager, err = user.NewManager(conf.AuthFile, conf.AuthDefault)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -101,19 +101,9 @@ func (s *Server) handleAccountGet(w http.ResponseWriter, _ *http.Request, v *vis
|
|||
if len(reservations) > 0 {
|
||||
response.Reservations = make([]*apiAccountReservation, 0)
|
||||
for _, r := range reservations {
|
||||
var everyone string
|
||||
if r.AllowEveryoneRead && r.AllowEveryoneWrite {
|
||||
everyone = "read-write"
|
||||
} else if r.AllowEveryoneRead && !r.AllowEveryoneWrite {
|
||||
everyone = "read-only"
|
||||
} else if !r.AllowEveryoneRead && r.AllowEveryoneWrite {
|
||||
everyone = "write-only"
|
||||
} else {
|
||||
everyone = "deny-all"
|
||||
}
|
||||
response.Reservations = append(response.Reservations, &apiAccountReservation{
|
||||
Topic: r.TopicPattern,
|
||||
Everyone: everyone,
|
||||
Topic: r.Topic,
|
||||
Everyone: r.Everyone.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -345,12 +335,14 @@ func (s *Server) handleAccountAccessAdd(w http.ResponseWriter, r *http.Request,
|
|||
return errHTTPConflictTopicReserved
|
||||
}
|
||||
owner, username := v.user.Name, v.user.Name
|
||||
everyoneRead := util.Contains([]string{"read-write", "rw", "read-only", "read", "ro"}, req.Everyone)
|
||||
everyoneWrite := util.Contains([]string{"read-write", "rw", "write-only", "write", "wo"}, req.Everyone)
|
||||
everyone, err := user.ParsePermission(req.Everyone)
|
||||
if err != nil {
|
||||
return errHTTPBadRequestPermissionInvalid
|
||||
}
|
||||
if err := s.userManager.AllowAccess(owner, username, req.Topic, true, true); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.userManager.AllowAccess(owner, user.Everyone, req.Topic, everyoneRead, everyoneWrite); err != nil {
|
||||
if err := s.userManager.AllowAccess(owner, user.Everyone, req.Topic, everyone.IsRead(), everyone.IsWrite()); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
@ -373,7 +365,7 @@ func (s *Server) handleAccountAccessDelete(w http.ResponseWriter, r *http.Reques
|
|||
}
|
||||
authorized := false
|
||||
for _, r := range reservations {
|
||||
if r.TopicPattern == topic {
|
||||
if r.Topic == topic {
|
||||
authorized = true
|
||||
break
|
||||
}
|
||||
|
|
|
@ -638,8 +638,7 @@ func TestServer_Auth_Success_Admin(t *testing.T) {
|
|||
func TestServer_Auth_Success_User(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = false
|
||||
c.AuthDefaultWrite = false
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||
|
@ -654,8 +653,7 @@ func TestServer_Auth_Success_User(t *testing.T) {
|
|||
func TestServer_Auth_Success_User_MultipleTopics(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = false
|
||||
c.AuthDefaultWrite = false
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||
|
@ -676,8 +674,7 @@ func TestServer_Auth_Success_User_MultipleTopics(t *testing.T) {
|
|||
func TestServer_Auth_Fail_InvalidPass(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = false
|
||||
c.AuthDefaultWrite = false
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("phil", "phil", user.RoleAdmin))
|
||||
|
@ -691,8 +688,7 @@ func TestServer_Auth_Fail_InvalidPass(t *testing.T) {
|
|||
func TestServer_Auth_Fail_Unauthorized(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = false
|
||||
c.AuthDefaultWrite = false
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("ben", "ben", user.RoleUser))
|
||||
|
@ -707,8 +703,7 @@ func TestServer_Auth_Fail_Unauthorized(t *testing.T) {
|
|||
func TestServer_Auth_Fail_CannotPublish(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = true // Open by default
|
||||
c.AuthDefaultWrite = true // Open by default
|
||||
c.AuthDefault = user.PermissionReadWrite // Open by default
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("phil", "phil", user.RoleAdmin))
|
||||
|
@ -739,8 +734,7 @@ func TestServer_Auth_Fail_CannotPublish(t *testing.T) {
|
|||
func TestServer_Auth_ViaQuery(t *testing.T) {
|
||||
c := newTestConfig(t)
|
||||
c.AuthFile = filepath.Join(t.TempDir(), "user.db")
|
||||
c.AuthDefaultRead = false
|
||||
c.AuthDefaultWrite = false
|
||||
c.AuthDefault = user.PermissionDenyAll
|
||||
s := newTestServer(t, c)
|
||||
|
||||
require.Nil(t, s.userManager.AddUser("ben", "some pass", user.RoleAdmin))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue