mirror of
https://github.com/wisplite/raster.git
synced 2026-05-01 14:42:44 -05:00
c7d478271d
previously guest users would cause a response 500 if a private album existed, meaning they couldn't see any albums they also couldn't load media in any album due to requiring an access token
154 lines
4.3 KiB
Go
154 lines
4.3 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/wisplite/raster/internal/db"
|
|
"github.com/wisplite/raster/internal/models"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func GetAlbumsInParent(parentID string, authToken string) ([]models.Album, error) {
|
|
userID, err := ValidateAccessToken(authToken)
|
|
if err != nil {
|
|
if err != gorm.ErrRecordNotFound { //if record not found, assume user is guest
|
|
return []models.Album{}, err
|
|
}
|
|
}
|
|
accessLevel, err := CheckUserAlbumAccess(userID, parentID)
|
|
if err != nil {
|
|
if err != gorm.ErrRecordNotFound { //if record not found, assume user is guest
|
|
return []models.Album{}, err
|
|
}
|
|
accessLevel = 1
|
|
}
|
|
if accessLevel < 0 {
|
|
return []models.Album{}, fmt.Errorf("user does not have permission to view albums in this parent")
|
|
}
|
|
albums := []models.Album{}
|
|
result := db.GetDB().Where("parent_id = ?", parentID).Find(&albums)
|
|
if result.Error != nil {
|
|
return []models.Album{}, result.Error
|
|
}
|
|
filteredAlbums := []models.Album{}
|
|
for _, album := range albums {
|
|
if album.Private {
|
|
accessLevel, err := CheckUserAlbumAccess(userID, album.ID)
|
|
if err != nil {
|
|
continue // if user is not found, assume user is guest
|
|
}
|
|
if accessLevel < 0 {
|
|
continue
|
|
}
|
|
}
|
|
filteredAlbums = append(filteredAlbums, album)
|
|
}
|
|
return filteredAlbums, nil
|
|
}
|
|
|
|
func GetAlbum(id string, authToken string) (models.Album, error) {
|
|
// TODO: Add authentication
|
|
album := models.Album{}
|
|
result := db.GetDB().First(&album, "id = ?", id)
|
|
if result.Error != nil {
|
|
return models.Album{}, result.Error
|
|
}
|
|
return album, nil
|
|
}
|
|
|
|
func CreateAlbum(accessToken string, title string, description string, parentID string) (models.Album, error) {
|
|
userID, err := ValidateAccessToken(accessToken)
|
|
if err != nil {
|
|
return models.Album{}, err
|
|
}
|
|
if userID == "" {
|
|
return models.Album{}, fmt.Errorf("invalid access token")
|
|
}
|
|
accessLevel, err := CheckUserAlbumAccess(userID, parentID)
|
|
if err != nil {
|
|
return models.Album{}, err
|
|
}
|
|
if accessLevel < 2 {
|
|
return models.Album{}, fmt.Errorf("user does not have permission to create albums in this parent")
|
|
}
|
|
if !regexp.MustCompile(`^[a-zA-Z0-9\s\-_]+$`).MatchString(title) {
|
|
return models.Album{}, fmt.Errorf("title can only contain alphanumeric characters, spaces, and hyphens/underscores")
|
|
}
|
|
// check for duplicate title in parent
|
|
existingAlbum := models.Album{}
|
|
result := db.GetDB().First(&existingAlbum, "title = ? AND parent_id = ?", title, parentID)
|
|
if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
|
|
return models.Album{}, result.Error
|
|
}
|
|
if existingAlbum.ID != "" {
|
|
return models.Album{}, fmt.Errorf("album with this title already exists in this parent")
|
|
}
|
|
albumID := uuid.New().String()
|
|
newAlbum := models.Album{
|
|
ID: albumID,
|
|
Title: title,
|
|
Description: description,
|
|
ParentID: parentID,
|
|
Thumbnail: "",
|
|
}
|
|
newAlbumResult := db.GetDB().Create(&newAlbum)
|
|
if newAlbumResult.Error != nil {
|
|
return models.Album{}, result.Error
|
|
}
|
|
return newAlbum, nil
|
|
}
|
|
|
|
func CheckUserAlbumAccess(userID string, albumID string) (int, error) {
|
|
userAccess := models.UserAlbumAccess{}
|
|
result := db.GetDB().First(&userAccess, "user_id = ? AND album_id = ?", userID, albumID)
|
|
if result.Error != nil {
|
|
if result.Error == gorm.ErrRecordNotFound {
|
|
userData, err := GetUserByID(userID)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
if userData.IsAdmin || userData.IsRoot {
|
|
return 4, nil // Admin access
|
|
}
|
|
return -1, nil // No access
|
|
}
|
|
return -1, result.Error
|
|
}
|
|
return userAccess.AccessLevel, nil
|
|
}
|
|
|
|
func GetIDFromPath(path string) (string, error) {
|
|
currentParentID := ""
|
|
segments := strings.Split(path, "/")
|
|
|
|
for _, segment := range segments {
|
|
if segment == "" {
|
|
continue
|
|
}
|
|
|
|
var album models.Album
|
|
result := db.GetDB().Where("title = ? AND parent_id = ?", segment, currentParentID).First(&album)
|
|
if result.Error != nil {
|
|
return "", result.Error
|
|
}
|
|
currentParentID = album.ID
|
|
}
|
|
|
|
return currentParentID, nil
|
|
}
|
|
|
|
func IsAlbumPublic(albumID string) (bool, error) {
|
|
if albumID == "" {
|
|
return true, nil
|
|
}
|
|
album := models.Album{}
|
|
result := db.GetDB().First(&album, "id = ?", albumID)
|
|
if result.Error != nil {
|
|
return false, result.Error
|
|
}
|
|
return !album.Private, nil
|
|
}
|