Skip to content
Snippets Groups Projects
listobjects.go 1.99 KiB
Newer Older
  • Learn to ignore specific revisions
  • package routes
    
    import (
    	"net/http"
    	"strconv"
    
    	"owo.codes/whats-this/api/lib/apierrors"
    	"owo.codes/whats-this/api/lib/db"
    	"owo.codes/whats-this/api/lib/middleware"
    
    Dean's avatar
    Dean committed
    	"owo.codes/whats-this/api/lib/ratelimiter"
    
    
    	"github.com/go-chi/render"
    	"github.com/rs/zerolog/log"
    
    Dean's avatar
    Dean committed
    	"github.com/spf13/viper"
    
    )
    
    // Maximum objects per page
    
    const maxOffset = 100
    
    
    // listObjectsResponse is the response format for ListObjects.
    type listObjectsResponse struct {
    	Success bool        `json:"success"`
    	Data    []db.Object `json:"data"`
    }
    
    // ListObjects returns a paginated list of all objects owned by a user.
    func ListObjects(w http.ResponseWriter, r *http.Request) {
    	// Only authorized users can use this route
    	user := middleware.GetAuthorizedUser(r)
    	if user.ID == "" || user.IsBlocked {
    		panic(apierrors.Unauthorized)
    	}
    
    
    Dean's avatar
    Dean committed
    	// Apply ratelimits
    	bucket := middleware.GetBucket(r)
    	err := bucket.TakeWithHeaders(w, viper.GetInt64("ratelimiter.listObjectsCost"))
    	if err == ratelimiter.InsufficientTokens {
    		panic(apierrors.InsufficientTokens)
    	}
    	if err != nil {
    		panic(apierrors.InternalServerError)
    	}
    
    
    	// Determine offset and limit information
    	query := r.URL.Query()
    	l := query.Get("limit")
    	limit, err := strconv.Atoi(l)
    	if err != nil {
    		panic(apierrors.InvalidOffsetOrLimit)
    	}
    	o := query.Get("offset")
    	offset, err := strconv.Atoi(o)
    	if err != nil {
    		panic(apierrors.InvalidOffsetOrLimit)
    	}
    
    	if limit > maxOffset {
    
    		panic(apierrors.OffsetTooLarge)
    	}
    	asc := false
    	if query.Get("order") == "asc" {
    		asc = true
    	}
    
    	// Get the data
    	objects, err := db.ListObjectsByAssociatedUser(user.ID, asc, offset, limit)
    	if err != nil {
    		log.Error().Err(err).Msg("failed to list objects for user")
    		panic(apierrors.InternalServerError)
    	}
    	associatedWithCurrentUser := true
    	for i := 0; i < len(objects); i++ {
    		objects[i].AssociatedWithCurrentUser = &associatedWithCurrentUser
    	}
    
    	// Return response
    	w.Header().Set("Content-Type", "application/json")
    	w.WriteHeader(http.StatusOK)
    	render.JSON(w, r, listObjectsResponse{true, objects})
    }