Rename /access to /reservation

This commit is contained in:
binwiederhier 2023-01-12 10:50:09 -05:00
parent d4ec5eb497
commit 24529bd0ad
5 changed files with 24 additions and 26 deletions

View file

@ -59,8 +59,6 @@ import (
Docs: Docs:
- "expires" field in message - "expires" field in message
- server.yml: enable-X flags - server.yml: enable-X flags
Refactor:
- rename /access -> /reservation
*/ */
// Server is the main server, providing the UI and API for ntfy // Server is the main server, providing the UI and API for ntfy
@ -105,8 +103,8 @@ var (
accountPasswordPath = "/v1/account/password" accountPasswordPath = "/v1/account/password"
accountSettingsPath = "/v1/account/settings" accountSettingsPath = "/v1/account/settings"
accountSubscriptionPath = "/v1/account/subscription" accountSubscriptionPath = "/v1/account/subscription"
accountAccessPath = "/v1/account/access" accountReservationPath = "/v1/account/reservation"
accountAccessSingleRegex = regexp.MustCompile(`/v1/account/access/([-_A-Za-z0-9]{1,64})$`) accountReservationSingleRegex = regexp.MustCompile(`/v1/account/reservation/([-_A-Za-z0-9]{1,64})$`)
accountSubscriptionSingleRegex = regexp.MustCompile(`^/v1/account/subscription/([-_A-Za-z0-9]{16})$`) accountSubscriptionSingleRegex = regexp.MustCompile(`^/v1/account/subscription/([-_A-Za-z0-9]{16})$`)
matrixPushPath = "/_matrix/push/v1/notify" matrixPushPath = "/_matrix/push/v1/notify"
staticRegex = regexp.MustCompile(`^/static/.+`) staticRegex = regexp.MustCompile(`^/static/.+`)
@ -364,10 +362,10 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
return s.ensureUser(s.handleAccountSubscriptionChange)(w, r, v) return s.ensureUser(s.handleAccountSubscriptionChange)(w, r, v)
} else if r.Method == http.MethodDelete && accountSubscriptionSingleRegex.MatchString(r.URL.Path) { } else if r.Method == http.MethodDelete && accountSubscriptionSingleRegex.MatchString(r.URL.Path) {
return s.ensureUser(s.handleAccountSubscriptionDelete)(w, r, v) return s.ensureUser(s.handleAccountSubscriptionDelete)(w, r, v)
} else if r.Method == http.MethodPost && r.URL.Path == accountAccessPath { } else if r.Method == http.MethodPost && r.URL.Path == accountReservationPath {
return s.ensureUser(s.handleAccountAccessAdd)(w, r, v) return s.ensureUser(s.handleAccountReservationAdd)(w, r, v)
} else if r.Method == http.MethodDelete && accountAccessSingleRegex.MatchString(r.URL.Path) { } else if r.Method == http.MethodDelete && accountReservationSingleRegex.MatchString(r.URL.Path) {
return s.ensureUser(s.handleAccountAccessDelete)(w, r, v) return s.ensureUser(s.handleAccountReservationDelete)(w, r, v)
} else if r.Method == http.MethodGet && r.URL.Path == matrixPushPath { } else if r.Method == http.MethodGet && r.URL.Path == matrixPushPath {
return s.handleMatrixDiscovery(w) return s.handleMatrixDiscovery(w)
} else if r.Method == http.MethodGet && staticRegex.MatchString(r.URL.Path) { } else if r.Method == http.MethodGet && staticRegex.MatchString(r.URL.Path) {

View file

@ -316,7 +316,7 @@ func (s *Server) handleAccountSubscriptionDelete(w http.ResponseWriter, r *http.
return nil return nil
} }
func (s *Server) handleAccountAccessAdd(w http.ResponseWriter, r *http.Request, v *visitor) error { func (s *Server) handleAccountReservationAdd(w http.ResponseWriter, r *http.Request, v *visitor) error {
if v.user != nil && v.user.Role == user.RoleAdmin { if v.user != nil && v.user.Role == user.RoleAdmin {
return errHTTPBadRequestMakesNoSenseForAdmin return errHTTPBadRequestMakesNoSenseForAdmin
} }
@ -332,7 +332,7 @@ func (s *Server) handleAccountAccessAdd(w http.ResponseWriter, r *http.Request,
return errHTTPBadRequestPermissionInvalid return errHTTPBadRequestPermissionInvalid
} }
if v.user.Tier == nil { if v.user.Tier == nil {
return errHTTPUnauthorized // FIXME there should always be a plan! return errHTTPUnauthorized
} }
if err := s.userManager.CheckAllowAccess(v.user.Name, req.Topic); err != nil { if err := s.userManager.CheckAllowAccess(v.user.Name, req.Topic); err != nil {
return errHTTPConflictTopicReserved return errHTTPConflictTopicReserved
@ -361,8 +361,8 @@ func (s *Server) handleAccountAccessAdd(w http.ResponseWriter, r *http.Request,
return nil return nil
} }
func (s *Server) handleAccountAccessDelete(w http.ResponseWriter, r *http.Request, v *visitor) error { func (s *Server) handleAccountReservationDelete(w http.ResponseWriter, r *http.Request, v *visitor) error {
matches := accountAccessSingleRegex.FindStringSubmatch(r.URL.Path) matches := accountReservationSingleRegex.FindStringSubmatch(r.URL.Path)
if len(matches) != 2 { if len(matches) != 2 {
return errHTTPInternalErrorInvalidPath return errHTTPInternalErrorInvalidPath
} }

View file

@ -350,7 +350,7 @@ func TestAccount_Reservation_AddWithoutTierFails(t *testing.T) {
rr := request(t, s, "POST", "/v1/account", `{"username":"phil", "password":"mypass"}`, nil) rr := request(t, s, "POST", "/v1/account", `{"username":"phil", "password":"mypass"}`, nil)
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)
rr = request(t, s, "POST", "/v1/account/access", `{"topic":"mytopic", "everyone":"deny-all"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic":"mytopic", "everyone":"deny-all"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 401, rr.Code) require.Equal(t, 401, rr.Code)
@ -362,7 +362,7 @@ func TestAccount_Reservation_AddAdminSuccess(t *testing.T) {
s := newTestServer(t, conf) s := newTestServer(t, conf)
require.Nil(t, s.userManager.AddUser("phil", "adminpass", user.RoleAdmin, "unit-test")) require.Nil(t, s.userManager.AddUser("phil", "adminpass", user.RoleAdmin, "unit-test"))
rr := request(t, s, "POST", "/v1/account/access", `{"topic":"mytopic","everyone":"deny-all"}`, map[string]string{ rr := request(t, s, "POST", "/v1/account/reservation", `{"topic":"mytopic","everyone":"deny-all"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "adminpass"), "Authorization": util.BasicAuth("phil", "adminpass"),
}) })
require.Equal(t, 400, rr.Code) require.Equal(t, 400, rr.Code)
@ -393,24 +393,24 @@ func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
require.Nil(t, s.userManager.ChangeTier("phil", "pro")) require.Nil(t, s.userManager.ChangeTier("phil", "pro"))
// Reserve two topics // Reserve two topics
rr = request(t, s, "POST", "/v1/account/access", `{"topic": "mytopic", "everyone":"deny-all"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic": "mytopic", "everyone":"deny-all"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)
rr = request(t, s, "POST", "/v1/account/access", `{"topic": "another", "everyone":"read-only"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic": "another", "everyone":"read-only"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)
// Trying to reserve a third should fail // Trying to reserve a third should fail
rr = request(t, s, "POST", "/v1/account/access", `{"topic": "yet-another", "everyone":"deny-all"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic": "yet-another", "everyone":"deny-all"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 429, rr.Code) require.Equal(t, 429, rr.Code)
// Modify existing should still work // Modify existing should still work
rr = request(t, s, "POST", "/v1/account/access", `{"topic": "another", "everyone":"write-only"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic": "another", "everyone":"write-only"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)
@ -436,7 +436,7 @@ func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
require.Equal(t, "deny-all", account.Reservations[1].Everyone) require.Equal(t, "deny-all", account.Reservations[1].Everyone)
// Delete and re-check // Delete and re-check
rr = request(t, s, "DELETE", "/v1/account/access/another", "", map[string]string{ rr = request(t, s, "DELETE", "/v1/account/reservation/another", "", map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)
@ -468,7 +468,7 @@ func TestAccount_Reservation_PublishByAnonymousFails(t *testing.T) {
require.Nil(t, s.userManager.ChangeTier("phil", "pro")) require.Nil(t, s.userManager.ChangeTier("phil", "pro"))
// Reserve a topic // Reserve a topic
rr = request(t, s, "POST", "/v1/account/access", `{"topic": "mytopic", "everyone":"deny-all"}`, map[string]string{ rr = request(t, s, "POST", "/v1/account/reservation", `{"topic": "mytopic", "everyone":"deny-all"}`, map[string]string{
"Authorization": util.BasicAuth("phil", "mypass"), "Authorization": util.BasicAuth("phil", "mypass"),
}) })
require.Equal(t, 200, rr.Code) require.Equal(t, 200, rr.Code)

View file

@ -1,6 +1,6 @@
import { import {
accountAccessSingleUrl, accountReservationSingleUrl,
accountAccessUrl, accountReservationUrl,
accountPasswordUrl, accountPasswordUrl,
accountSettingsUrl, accountSettingsUrl,
accountSubscriptionSingleUrl, accountSubscriptionSingleUrl,
@ -229,7 +229,7 @@ class AccountApi {
} }
async upsertAccess(topic, everyone) { async upsertAccess(topic, everyone) {
const url = accountAccessUrl(config.base_url); const url = accountReservationUrl(config.base_url);
console.log(`[AccountApi] Upserting user access to topic ${topic}, everyone=${everyone}`); console.log(`[AccountApi] Upserting user access to topic ${topic}, everyone=${everyone}`);
const response = await fetch(url, { const response = await fetch(url, {
method: "POST", method: "POST",
@ -250,7 +250,7 @@ class AccountApi {
} }
async deleteAccess(topic) { async deleteAccess(topic) {
const url = accountAccessSingleUrl(config.base_url, topic); const url = accountReservationSingleUrl(config.base_url, topic);
console.log(`[AccountApi] Removing topic reservation ${url}`); console.log(`[AccountApi] Removing topic reservation ${url}`);
const response = await fetch(url, { const response = await fetch(url, {
method: "DELETE", method: "DELETE",

View file

@ -24,8 +24,8 @@ export const accountTokenUrl = (baseUrl) => `${baseUrl}/v1/account/token`;
export const accountSettingsUrl = (baseUrl) => `${baseUrl}/v1/account/settings`; export const accountSettingsUrl = (baseUrl) => `${baseUrl}/v1/account/settings`;
export const accountSubscriptionUrl = (baseUrl) => `${baseUrl}/v1/account/subscription`; export const accountSubscriptionUrl = (baseUrl) => `${baseUrl}/v1/account/subscription`;
export const accountSubscriptionSingleUrl = (baseUrl, id) => `${baseUrl}/v1/account/subscription/${id}`; export const accountSubscriptionSingleUrl = (baseUrl, id) => `${baseUrl}/v1/account/subscription/${id}`;
export const accountAccessUrl = (baseUrl) => `${baseUrl}/v1/account/access`; export const accountReservationUrl = (baseUrl) => `${baseUrl}/v1/account/reservation`;
export const accountAccessSingleUrl = (baseUrl, topic) => `${baseUrl}/v1/account/access/${topic}`; export const accountReservationSingleUrl = (baseUrl, topic) => `${baseUrl}/v1/account/reservation/${topic}`;
export const shortUrl = (url) => url.replaceAll(/https?:\/\//g, ""); export const shortUrl = (url) => url.replaceAll(/https?:\/\//g, "");
export const expandUrl = (url) => [`https://${url}`, `http://${url}`]; export const expandUrl = (url) => [`https://${url}`, `http://${url}`];
export const expandSecureUrl = (url) => `https://${url}`; export const expandSecureUrl = (url) => `https://${url}`;