Skip to content

Commit

Permalink
Merge pull request #70 from ianmcorvidae/user-instant-launches
Browse files Browse the repository at this point in the history
Add non-admin/admin version split for instant launches, to allow users to create/update/delete
  • Loading branch information
ianmcorvidae authored Oct 21, 2024
2 parents 7504aa5 + 54c2cc1 commit 96f8ed0
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 15 deletions.
10 changes: 8 additions & 2 deletions instantlaunches/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,14 @@ func New(db *sqlx.DB, group *echo.Group, init *Init) *App {
instance.Group.DELETE("/:id", instance.DeleteInstantLaunchHandler)
instance.Group.GET("/:id/full", instance.FullInstantLaunchHandler)
instance.Group.GET("/:id/metadata", instance.GetMetadataHandler)
instance.Group.POST("/:id/metadata", instance.AddOrUpdateMetadataHandler)
instance.Group.PUT("/:id/metadata", instance.SetAllMetadataHandler)

iladmin := instance.Group.Group("/admin")
iladmin.PUT("/", instance.AdminAddInstantLaunchHandler)
iladmin.PUT("", instance.AdminAddInstantLaunchHandler)
iladmin.POST("/:id", instance.AdminUpdateInstantLaunchHandler)
iladmin.DELETE("/:id", instance.AdminDeleteInstantLaunchHandler)
iladmin.POST("/:id/metadata", instance.AdminAddOrUpdateMetadataHandler)
iladmin.PUT("/:id/metadata", instance.AdminSetAllMetadataHandler)

return instance
}
16 changes: 8 additions & 8 deletions instantlaunches/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ func (a *App) GetMetadataHandler(c echo.Context) error {
return c.Blob(resp.StatusCode, resp.Header.Get("content-type"), body)
}

// AddOrUpdateMetadataHandler adds or updates one or more AVUs on an instant
// launch.
func (a *App) AddOrUpdateMetadataHandler(c echo.Context) error {
// AdminAddOrUpdateMetadataHandler adds or updates one or more AVUs on an instant
// launch as an admin
func (a *App) AdminAddOrUpdateMetadataHandler(c echo.Context) error {
ctx := c.Request().Context()

log.Debug("in AddOrUpdateMetadataHandler")
log.Debug("in AdminAddOrUpdateMetadataHandler")

id := c.Param("id")
if id == "" {
Expand Down Expand Up @@ -260,12 +260,12 @@ func (a *App) AddOrUpdateMetadataHandler(c echo.Context) error {
return c.Blob(resp.StatusCode, resp.Header.Get("content-type"), body)
}

// SetAllMetadataHandler sets all of the AVUs associated with an instant
// launch to the set contained in the body of the request.
func (a *App) SetAllMetadataHandler(c echo.Context) error {
// AdminSetAllMetadataHandler sets all of the AVUs associated with an instant
// launch to the set contained in the body of the request (as an admin).
func (a *App) AdminSetAllMetadataHandler(c echo.Context) error {
ctx := c.Request().Context()

log.Debug("in SetAllMetadataHandler")
log.Debug("in AdminSetAllMetadataHandler")

id := c.Param("id")
if id == "" {
Expand Down
127 changes: 122 additions & 5 deletions instantlaunches/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,62 @@ import (
"database/sql"
"fmt"
"net/http"
"regexp"
"strings"

"github.com/labstack/echo/v4"
)

// AddInstantLaunchHandler is the HTTP handler for adding a new instant launch.
// suffixUsername takes a possibly-already-suffixed username, strips any suffix, and adds the provided one, to ensure proper suffixing
func suffixUsername(username, suffix string) string {
re, _ := regexp.Compile(`@.*$`)
return fmt.Sprintf("%s@%s", re.ReplaceAllString(username, ""), strings.Trim(suffix, "@"))
}

// checkUserMatches ensures that `first` and `second` match when both suffixed the same.
func checkUserMatches(first, second, suffix string) bool {
return (suffixUsername(first, suffix) == suffixUsername(second, suffix))
}

// AddInstantLaunchHandler is the HTTP handler for adding a new instant launch
// as a regular user
func (a *App) AddInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
user := c.QueryParam("user")
if user == "" {
return echo.NewHTTPError(http.StatusBadRequest, "user query parameter must be set")
}

il, err := NewInstantLaunchFromJSON(c.Request().Body)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "cannot parse JSON")
}

if il.AddedBy == "" {
return echo.NewHTTPError(http.StatusBadRequest, "username was not set")
}

if !checkUserMatches(il.AddedBy, user, a.UserSuffix) {
return echo.NewHTTPError(http.StatusBadRequest, "not authorized to create instant launches as another user")
}

if !strings.HasSuffix(il.AddedBy, a.UserSuffix) {
il.AddedBy = suffixUsername(il.AddedBy, a.UserSuffix)
}

newil, err := a.AddInstantLaunch(ctx, il.QuickLaunchID, il.AddedBy)
if err != nil {
if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return err
}

return c.JSON(http.StatusOK, newil)
}

// AdminAddInstantLaunchHandler is the HTTP handler for adding a new instant launch as an admin.
func (a *App) AdminAddInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
il, err := NewInstantLaunchFromJSON(c.Request().Body)
if err != nil {
Expand Down Expand Up @@ -77,8 +126,49 @@ func (a *App) FullInstantLaunchHandler(c echo.Context) error {
return c.JSON(http.StatusOK, il)
}

// UpdateInstantLaunchHandler is the HTTP handler for updating an instant launch.
// UpdateInstantLaunchHandler is the HTTP handler for updating an instant launch as a regular user
func (a *App) UpdateInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
user := c.QueryParam("user")
if user == "" {
return echo.NewHTTPError(http.StatusBadRequest, "user query parameter must be set")
}

id := c.Param("id")
if id == "" {
return echo.NewHTTPError(http.StatusNotFound, "id is missing")
}

il, err := a.GetInstantLaunch(ctx, id)
if err != nil {
if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return err
}

updated, err := NewInstantLaunchFromJSON(c.Request().Body)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "cannot parse JSON")
}

if !checkUserMatches(il.AddedBy, user, a.UserSuffix) || !checkUserMatches(il.AddedBy, updated.AddedBy, a.UserSuffix) {
return echo.NewHTTPError(http.StatusBadRequest, "not authorized to edit other users' instant launches")
}

newvalue, err := a.UpdateInstantLaunch(ctx, id, updated.QuickLaunchID)
if err != nil {
if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return err
}

return c.JSON(http.StatusOK, newvalue)
}

// AdminUpdateInstantLaunchHandler is the HTTP handler for updating an instant launch as an admin.
func (a *App) AdminUpdateInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
id := c.Param("id")
if id == "" {
Expand All @@ -102,17 +192,44 @@ func (a *App) UpdateInstantLaunchHandler(c echo.Context) error {
}

// DeleteInstantLaunchHandler is the HTTP handler for deleting an Instant Launch
// based on its UUID.
// based on its UUID as a regular user
func (a *App) DeleteInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
user := c.QueryParam("user")
if user == "" {
return echo.NewHTTPError(http.StatusBadRequest, "user query parameter must be set")
}

id := c.Param("id")
if id == "" {
return echo.NewHTTPError(http.StatusNotFound, "id is missing")
}

err := a.DeleteInstantLaunch(ctx, id)
return err
il, err := a.GetInstantLaunch(ctx, id)
if err != nil {
if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusNotFound, err.Error())
}
return err
}

if !checkUserMatches(il.AddedBy, user, a.UserSuffix) {
return echo.NewHTTPError(http.StatusBadRequest, "not authorized to delete other users' instant launches")
}

return a.DeleteInstantLaunch(ctx, id)
}

// AdminDeleteInstantLaunchHandler is the HTTP handler for deleting an Instant Launch
// based on its UUID as an admin
func (a *App) AdminDeleteInstantLaunchHandler(c echo.Context) error {
ctx := c.Request().Context()
id := c.Param("id")
if id == "" {
return echo.NewHTTPError(http.StatusNotFound, "id is missing")
}

return a.DeleteInstantLaunch(ctx, id)
}

// ListInstantLaunchesHandler is the HTTP handler for listing all of the
Expand Down

0 comments on commit 96f8ed0

Please sign in to comment.