Fix queries

This commit is contained in:
Neeraj Gupta
2025-07-16 17:12:33 +05:30
parent 99f4d4ca4d
commit 46ba71a15a
4 changed files with 90 additions and 93 deletions

View File

@@ -7,20 +7,16 @@ type CreateFileUrl struct {
// UpdateFileUrl ..
type UpdateFileUrl struct {
LinkID string `json:"linkID" binding:"required"`
FileID int64 `json:"fileID" binding:"required"`
ValidTill *int64 `json:"validTill"`
DeviceLimit *int `json:"deviceLimit"`
PasswordInfo *PassWordInfo `json:"passHash"`
EnableDownload *bool `json:"enableDownload"`
DisablePassword *bool `json:"disablePassword"`
}
type PassWordInfo struct {
PassHash string `json:"passHash" binding:"required"`
Nonce string `json:"nonce" binding:"required"`
MemLimit int64 `json:"memLimit" binding:"required"`
OpsLimit int64 `json:"opsLimit" binding:"required"`
LinkID string `json:"linkID" binding:"required"`
FileID int64 `json:"fileID" binding:"required"`
ValidTill *int64 `json:"validTill"`
DeviceLimit *int `json:"deviceLimit"`
PassHash *string
Nonce *string
MemLimit *int64
OpsLimit *int64
EnableDownload *bool `json:"enableDownload"`
DisablePassword *bool `json:"disablePassword"`
}
type PublicFileUrlRow struct {
@@ -31,7 +27,10 @@ type PublicFileUrlRow struct {
DeviceLimit int
ValidTill int64
IsDisabled bool
PasswordInfo *PassWordInfo
PassHash *string
Nonce *string
MemLimit *int64
OpsLimit *int64
EnableDownload bool
CreatedAt int64
UpdatedAt int64
@@ -39,11 +38,23 @@ type PublicFileUrlRow struct {
type FileUrl struct {
LinkID string `json:"linkID" binding:"required"`
URL string `json:"url" binding:"required"`
OwnerID int64 `json:"ownerID" binding:"required"`
FileID int64 `json:"fileID" binding:"required"`
ValidTill int64 `json:"validTill"`
DeviceLimit int `json:"deviceLimit"`
PasswordEnabled bool `json:"passwordEnabled"`
EnableDownload bool `json:"enableDownload"`
CreatedAt int64 `json:"createdAt"`
// Nonce contains the nonce value for the password if the link is password protected.
Nonce *string `json:"nonce,omitempty"`
MemLimit *int64 `json:"memLimit,omitempty"`
OpsLimit *int64 `json:"opsLimit,omitempty"`
EnableDownload bool `json:"enableDownload"`
CreatedAt int64 `json:"createdAt"`
}
type PublicFileAccessContext struct {
ID int64
IP string
UserAgent string
CollectionID int64
}

View File

@@ -25,11 +25,12 @@ type PublicFileController struct {
func (c *PublicFileController) CreateFileUrl(ctx *gin.Context, req ente.CreateFileUrl) (*ente.FileUrl, error) {
actorUserID := auth.GetUserID(ctx.Request.Header)
accessToken := shortuuid.New()[0:AccessTokenLength]
err := c.PublicFileRepo.Insert(ctx, req.FileID, actorUserID, accessToken)
id, err := c.PublicFileRepo.Insert(ctx, req.FileID, actorUserID, accessToken)
if err == nil {
return &ente.FileUrl{
LinkID: accessToken,
FileID: req.FileID,
LinkID: *id,
FileID: req.FileID,
OwnerID: actorUserID,
}, nil
}
return nil, stacktrace.NewError("This endpoint is deprecated. Please use CreatePublicCollectionToken instead")

View File

@@ -123,7 +123,7 @@ func (pcr *PublicCollectionRepository) RecordAbuseReport(ctx context.Context, ac
url string, reason string, details ente.AbuseReportDetails) error {
_, err := pcr.DB.ExecContext(ctx, `INSERT INTO public_abuse_report
(share_id, ip, user_agent, url, reason, details) VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT ON CONSTRAINT unique_report_public_collection_id_ip_ua DO UPDATE SET (reason, details) = ($5, $6)`,
ON CONFLICT ON CONSTRAINT unique_report_sid_ip_ua DO UPDATE SET (reason, details) = ($5, $6)`,
accessCtx.ID, accessCtx.IP, accessCtx.UserAgent, url, reason, details)
return stacktrace.Propagate(err, "failed to record abuse report")
}

View File

@@ -8,7 +8,6 @@ import (
"github.com/ente-io/museum/ente"
"github.com/ente-io/stacktrace"
"github.com/lib/pq"
)
// PublicFileRepository defines the methods for inserting, updating and
@@ -38,18 +37,21 @@ func (pcr *PublicFileRepository) Insert(
fileID int64,
ownerID int64,
token string,
) error {
) (*string, error) {
id, err := base.NewID("pft")
if err != nil {
return stacktrace.Propagate(err, "failed to generate new ID for public file token")
return nil, stacktrace.Propagate(err, "failed to generate new ID for public file token")
}
_, err = pcr.DB.ExecContext(ctx, `INSERT INTO public_file_tokens
(id, file_id, owner_id, access_token) VALUES ($1, $2, $3, $4)`,
id, fileID, ownerID, token)
if err != nil && err.Error() == "pq: duplicate key value violates unique constraint \"public_access_token_unique_idx\"" {
return ente.ErrActiveLinkAlreadyExists
if err != nil {
if err.Error() == "pq: duplicate key value violates unique constraint \"public_access_token_unique_idx\"" {
return nil, ente.ErrActiveLinkAlreadyExists
}
return nil, stacktrace.Propagate(err, "failed to insert")
}
return stacktrace.Propagate(err, "failed to insert")
return id, nil
}
func (pcr *PublicFileRepository) DisableSharing(ctx context.Context, fileID int64) error {
@@ -58,90 +60,51 @@ func (pcr *PublicFileRepository) DisableSharing(ctx context.Context, fileID int6
return stacktrace.Propagate(err, "failed to disable sharing")
}
// GetCollectionToActivePublicURLMap will return map of collectionID to PublicURLs which are not disabled yet.
// Note: The url could be expired or deviceLimit is already reached
func (pcr *PublicFileRepository) GetCollectionToActivePublicURLMap(ctx context.Context, collectionIDs []int64) (map[int64][]ente.PublicURL, error) {
rows, err := pcr.DB.QueryContext(ctx, `SELECT collection_id, access_token, valid_till, device_limit, enable_download, enable_collect, enable_join, pw_nonce, mem_limit, ops_limit FROM
public_collection_tokens WHERE collection_id = ANY($1) and is_disabled = FALSE`,
pq.Array(collectionIDs))
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
defer rows.Close()
result := make(map[int64][]ente.PublicURL, 0)
for _, cID := range collectionIDs {
result[cID] = make([]ente.PublicURL, 0)
}
func convertRowToFileUrl(rows *sql.Rows) ([]ente.FileUrl, error) {
var fileUrls []ente.FileUrl
for rows.Next() {
publicUrl := ente.PublicURL{}
var collectionID int64
var accessToken string
fileUrl := ente.FileUrl{}
var nonce *string
var opsLimit, memLimit *int64
if err = rows.Scan(&collectionID, &accessToken, &publicUrl.ValidTill, &publicUrl.DeviceLimit, &publicUrl.EnableDownload, &publicUrl.EnableCollect, &publicUrl.EnableJoin, &nonce, &memLimit, &opsLimit); err != nil {
return nil, stacktrace.Propagate(err, "")
var memLimit, opsLimit *int64
err := rows.Scan(&fileUrl.LinkID, &fileUrl.OwnerID, &fileUrl.FileID, &fileUrl.ValidTill, &fileUrl.DeviceLimit, &nonce, &memLimit, &opsLimit, &fileUrl.EnableDownload, &fileUrl.CreatedAt)
if err != nil {
return nil, stacktrace.Propagate(err, "failed to scan public file url row")
}
publicUrl.URL = pcr.GetAlbumUrl(accessToken)
if nonce != nil {
publicUrl.Nonce = nonce
publicUrl.MemLimit = memLimit
publicUrl.OpsLimit = opsLimit
publicUrl.PasswordEnabled = true
}
result[collectionID] = append(result[collectionID], publicUrl)
fileUrl.Nonce = nonce
fileUrl.MemLimit = memLimit
fileUrl.OpsLimit = opsLimit
fileUrls = append(fileUrls, fileUrl)
}
return result, nil
return fileUrls, nil
}
// GetActivePublicCollectionToken will return ente.PublicCollectionToken for given collection ID
// GetActiveFileUrlToken will return ente.PublicCollectionToken for given collection ID
// Note: The token could be expired or deviceLimit is already reached
func (pcr *PublicFileRepository) GetActivePublicCollectionToken(ctx context.Context, collectionID int64) (ente.PublicCollectionToken, error) {
row := pcr.DB.QueryRowContext(ctx, `SELECT id, collection_id, access_token, valid_till, device_limit,
is_disabled, pw_hash, pw_nonce, mem_limit, ops_limit, enable_download, enable_collect, enable_join FROM
public_collection_tokens WHERE collection_id = $1 and is_disabled = FALSE`,
func (pcr *PublicFileRepository) GetActiveFileUrlToken(ctx context.Context, collectionID int64) (*ente.PublicFileUrlRow, error) {
row := pcr.DB.QueryRowContext(ctx, `SELECT id, file_id, owner_id, access_token, valid_till, device_limit,
is_disabled, pw_hash, pw_nonce, mem_limit, ops_limit, enable_download FROM
public_file_tokens WHERE file_id = $1 and is_disabled = FALSE`,
collectionID)
//defer rows.Close()
ret := ente.PublicCollectionToken{}
err := row.Scan(&ret.ID, &ret.CollectionID, &ret.Token, &ret.ValidTill, &ret.DeviceLimit,
&ret.IsDisabled, &ret.PassHash, &ret.Nonce, &ret.MemLimit, &ret.OpsLimit, &ret.EnableDownload, &ret.EnableCollect, &ret.EnableJoin)
ret := ente.PublicFileUrlRow{}
err := row.Scan(&ret.LinkID, &ret.FileID, ret.OwnerID, &ret.Token, &ret.ValidTill, &ret.DeviceLimit,
&ret.IsDisabled, &ret.PassHash, &ret.Nonce, &ret.MemLimit, &ret.OpsLimit, &ret.EnableDownload)
if err != nil {
return ente.PublicCollectionToken{}, stacktrace.Propagate(err, "")
return nil, stacktrace.Propagate(err, "")
}
return ret, nil
}
// UpdatePublicCollectionToken will update the row for corresponding public collection token
func (pcr *PublicFileRepository) UpdatePublicCollectionToken(ctx context.Context, pct ente.PublicCollectionToken) error {
_, err := pcr.DB.ExecContext(ctx, `UPDATE public_collection_tokens SET valid_till = $1, device_limit = $2,
pw_hash = $3, pw_nonce = $4, mem_limit = $5, ops_limit = $6, enable_download = $7, enable_collect = $8, enable_join = $9
where id = $10`,
pct.ValidTill, pct.DeviceLimit, pct.PassHash, pct.Nonce, pct.MemLimit, pct.OpsLimit, pct.EnableDownload, pct.EnableCollect, pct.EnableJoin, pct.ID)
return stacktrace.Propagate(err, "failed to update public collection token")
}
func (pcr *PublicFileRepository) GetUniqueAccessCount(ctx context.Context, shareId int64) (int64, error) {
panic("not implemented, refactor & public collection")
}
func (pcr *PublicFileRepository) RecordAccessHistory(ctx context.Context, shareID int64, ip string, ua string) error {
panic("not implemented, refactor & public collection")
}
// AccessedInPast returns true if the given ip, ua agent combination has accessed the url in the past
func (pcr *PublicFileRepository) AccessedInPast(ctx context.Context, shareID int64, ip string, ua string) (bool, error) {
panic("not implemented, refactor & public collection")
return &ret, nil
}
func (pcr *PublicFileRepository) GetFileUrlRowByToken(ctx context.Context, accessToken string) (*ente.PublicFileUrlRow, error) {
row := pcr.DB.QueryRowContext(ctx,
`SELECT id, file_id, is_disabled, valid_till, device_limit, password_info,
`SELECT id, file_id, owner_id, is_disabled, valid_till, device_limit, enable_download, pw_hash, pw_nonce, mem_limit, ops_limit
created_at, updated_at
from public_file_tokens
where access_token = $1
`, accessToken)
var result = ente.PublicFileUrlRow{}
err := row.Scan(&result.LinkID, &result.FileID, &result.IsDisabled, &result.ValidTill, &result.DeviceLimit, result.PasswordInfo, &result.CreatedAt, &result.UpdatedAt)
err := row.Scan(&result.LinkID, &result.FileID, &result.OwnerID, &result.IsDisabled, &result.EnableDownload, &result.ValidTill, &result.DeviceLimit, &result.PassHash, &result.Nonce, &result.MemLimit, &result.OpsLimit, &result.CreatedAt, &result.UpdatedAt)
if err != nil {
if err == sql.ErrNoRows {
return nil, ente.ErrNotFound
@@ -151,11 +114,33 @@ func (pcr *PublicFileRepository) GetFileUrlRowByToken(ctx context.Context, acces
return &result, nil
}
// CleanupAccessHistory public_collection_access_history where public_collection_tokens is disabled and the last updated time is older than 30 days
// UpdateLink will update the row for corresponding public file token
func (pcr *PublicFileRepository) UpdateLink(ctx context.Context, pct ente.PublicFileUrlRow) error {
_, err := pcr.DB.ExecContext(ctx, `UPDATE public_file_tokens SET valid_till = $1, device_limit = $2,
pw_hash = $3, pw_nonce = $4, mem_limit = $5, ops_limit = $6, enable_download = $7
where id = $8`,
pct.ValidTill, pct.DeviceLimit, pct.PassHash, pct.Nonce, pct.MemLimit, pct.OpsLimit, pct.EnableDownload, pct.LinkID)
return stacktrace.Propagate(err, "failed to update public file token")
}
func (pcr *PublicFileRepository) GetUniqueAccessCount(ctx context.Context, shareId int64) (int64, error) {
panic("not implemented, refactor & public file")
}
func (pcr *PublicFileRepository) RecordAccessHistory(ctx context.Context, shareID int64, ip string, ua string) error {
panic("not implemented, refactor & public file")
}
// AccessedInPast returns true if the given ip, ua agent combination has accessed the url in the past
func (pcr *PublicFileRepository) AccessedInPast(ctx context.Context, shareID int64, ip string, ua string) (bool, error) {
panic("not implemented, refactor & public file")
}
// CleanupAccessHistory public_file_tokens_access_history where public_collection_tokens is disabled and the last updated time is older than 30 days
func (pcr *PublicFileRepository) CleanupAccessHistory(ctx context.Context) error {
_, err := pcr.DB.ExecContext(ctx, `DELETE FROM public_collection_access_history WHERE share_id IN (SELECT id FROM public_collection_tokens WHERE is_disabled = TRUE AND updated_at < (now_utc_micro_seconds() - (24::BIGINT * 30 * 60 * 60 * 1000 * 1000)))`)
_, err := pcr.DB.ExecContext(ctx, `DELETE FROM public_file_tokens_access_history WHERE id IN (SELECT id FROM public_file_tokens WHERE is_disabled = TRUE AND updated_at < (now_utc_micro_seconds() - (24::BIGINT * 30 * 60 * 60 * 1000 * 1000)))`)
if err != nil {
return stacktrace.Propagate(err, "failed to clean up public collection access history")
return stacktrace.Propagate(err, "failed to clean up public file access history")
}
return nil
}