website/pkg/models/private_photo.go
Noah de9ba94dd9 Private Photo Sharing
* Add ability to unlock your private photos for others.
    * Link to unlock is on another user's Photos page.
    * You can also access your "Manage Private Photos" page in the User Menu
      or Dashboard and add a user by username.
    * See who you have granted access, and see users who have granted you
      access to their private photos.
* Private photos of users who unlocked them for you may appear on the Site
  Gallery if the photo allows.
* Add new filters to the Site Gallery: you can choose to filter by Explicit,
  limit to a specific Visibility, and order by Newest or Oldest. Non-explicit
  users do not get a filter to see explicit content - they must opt-in in
  their settings.
* Bugfix: Site Gallery was not correctly filtering Explicit photos away from
  users who did not opt-in for explicit!
2022-09-07 21:18:54 -07:00

148 lines
3.9 KiB
Go

package models
import (
"strings"
"time"
"gorm.io/gorm"
)
// PrivatePhoto table to track who you have unlocked your private photos for.
type PrivatePhoto struct {
ID uint64 `gorm:"primaryKey"`
SourceUserID uint64 `gorm:"index"` // the owner of a photo
TargetUserID uint64 `gorm:"index"` // the receiver
CreatedAt time.Time
UpdatedAt time.Time
}
// UnlockPrivatePhotos is sourceUserId allowing targetUserId to see their private photos.
func UnlockPrivatePhotos(sourceUserID, targetUserID uint64) error {
// Did we already allow this user?
var pb *PrivatePhoto
exist := DB.Where(
"source_user_id = ? AND target_user_id = ?",
sourceUserID, targetUserID,
).First(&pb).Error
// Update existing.
if exist == nil {
return nil
}
// Create the PrivatePhoto.
pb = &PrivatePhoto{
SourceUserID: sourceUserID,
TargetUserID: targetUserID,
}
return DB.Create(pb).Error
}
// RevokePrivatePhotos is sourceUserId revoking targetUserId to see their private photos.
func RevokePrivatePhotos(sourceUserID, targetUserID uint64) error {
result := DB.Where(
"source_user_id = ? AND target_user_id = ?",
sourceUserID, targetUserID,
).Delete(&PrivatePhoto{})
return result.Error
}
// RevokePrivatePhotosAll is sourceUserId revoking ALL USERS from their private photos.
func RevokePrivatePhotosAll(sourceUserID uint64) error {
result := DB.Where(
"source_user_id = ?",
sourceUserID,
).Delete(&PrivatePhoto{})
return result.Error
}
// IsPrivateUnlocked quickly sees if sourceUserID has unlocked private photos for targetUserID to see.
func IsPrivateUnlocked(sourceUserID, targetUserID uint64) bool {
pb := &PrivatePhoto{}
result := DB.Where(
"source_user_id = ? AND target_user_id = ?",
sourceUserID, targetUserID,
).First(&pb)
return result.Error == nil
}
// CountPrivateGrantee returns how many users have granted you access to their private photos.
func CountPrivateGrantee(userID uint64) int64 {
var count int64
DB.Model(&PrivatePhoto{}).Where(
"target_user_id = ?",
userID,
).Count(&count)
return count
}
// PrivateGrantedUserIDs returns all user IDs who have granted access for userId to see their private photos.
func PrivateGrantedUserIDs(userId uint64) []uint64 {
var (
ps = []*PrivatePhoto{}
userIDs = []uint64{userId}
)
DB.Where("target_user_id = ?", userId).Find(&ps)
for _, row := range ps {
userIDs = append(userIDs, row.SourceUserID)
}
return userIDs
}
/*
PaginatePrivatePhotoList views a user's list of private photo grants.
If grantee is true, it returns the list of users who have granted YOU access to see THEIR
private photos. If grantee is false, it returns the users that YOU have granted access to
see YOUR OWN private photos.
*/
func PaginatePrivatePhotoList(userID uint64, grantee bool, pager *Pagination) ([]*User, error) {
var (
pbs = []*PrivatePhoto{}
userIDs = []uint64{}
query *gorm.DB
wheres = []string{}
placeholders = []interface{}{}
)
// Which direction are we going?
if grantee {
// Return the private photo grants for whom YOU are the recipient.
wheres = append(wheres, "target_user_id = ?")
placeholders = append(placeholders, userID)
} else {
// Return the users that YOU have granted access to YOUR private pictures.
wheres = append(wheres, "source_user_id = ?")
placeholders = append(placeholders, userID)
}
query = DB.Where(
strings.Join(wheres, " AND "),
placeholders...,
)
query = query.Order(pager.Sort)
query.Model(&PrivatePhoto{}).Count(&pager.Total)
result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&pbs)
if result.Error != nil {
return nil, result.Error
}
// Now of these user IDs get their User objects.
for _, b := range pbs {
if grantee {
userIDs = append(userIDs, b.SourceUserID)
} else {
userIDs = append(userIDs, b.TargetUserID)
}
}
return GetUsers(userIDs)
}
// Save photo.
func (pb *PrivatePhoto) Save() error {
result := DB.Save(pb)
return result.Error
}