mirror of https://github.com/cloudreve/Cloudreve
93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package manager
|
|
|
|
import (
|
|
"context"
|
|
"encoding/gob"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
|
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
|
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs/dbfs"
|
|
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
|
"github.com/gofrs/uuid"
|
|
)
|
|
|
|
type (
|
|
ViewerSession struct {
|
|
ID string `json:"id"`
|
|
AccessToken string `json:"access_token"`
|
|
Expires int64 `json:"expires"`
|
|
File fs.File `json:"-"`
|
|
}
|
|
ViewerSessionCache struct {
|
|
ID string
|
|
Uri string
|
|
UserID int
|
|
FileID int
|
|
ViewerID string
|
|
Version string
|
|
Token string
|
|
}
|
|
ViewerSessionCacheCtx struct{}
|
|
ViewerCtx struct{}
|
|
)
|
|
|
|
const (
|
|
ViewerSessionCachePrefix = "viewer_session_"
|
|
|
|
sessionExpiresPadding = 10
|
|
)
|
|
|
|
func init() {
|
|
gob.Register(ViewerSessionCache{})
|
|
}
|
|
|
|
func (m *manager) CreateViewerSession(ctx context.Context, uri *fs.URI, version string, viewer *types.Viewer) (*ViewerSession, error) {
|
|
file, err := m.fs.Get(ctx, uri, dbfs.WithFileEntities(), dbfs.WithNotRoot())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
versionType := types.EntityTypeVersion
|
|
found, desired := fs.FindDesiredEntity(file, version, m.hasher, &versionType)
|
|
if !found {
|
|
return nil, fs.ErrEntityNotExist
|
|
}
|
|
|
|
if desired.Size() > m.settings.MaxOnlineEditSize(ctx) {
|
|
return nil, fs.ErrFileSizeTooBig
|
|
}
|
|
|
|
sessionID := uuid.Must(uuid.NewV4()).String()
|
|
token := util.RandStringRunes(128)
|
|
sessionCache := &ViewerSessionCache{
|
|
ID: sessionID,
|
|
Uri: file.Uri(false).String(),
|
|
UserID: m.user.ID,
|
|
ViewerID: viewer.ID,
|
|
FileID: file.ID(),
|
|
Version: version,
|
|
Token: fmt.Sprintf("%s.%s", sessionID, token),
|
|
}
|
|
ttl := m.settings.ViewerSessionTTL(ctx)
|
|
if err := m.kv.Set(ViewerSessionCachePrefix+sessionID, *sessionCache, ttl); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ViewerSession{
|
|
File: file,
|
|
ID: sessionID,
|
|
AccessToken: sessionCache.Token,
|
|
Expires: time.Now().Add(time.Duration(ttl-sessionExpiresPadding) * time.Second).UnixMilli(),
|
|
}, nil
|
|
}
|
|
|
|
func ViewerSessionFromContext(ctx context.Context) *ViewerSessionCache {
|
|
return ctx.Value(ViewerSessionCacheCtx{}).(*ViewerSessionCache)
|
|
}
|
|
|
|
func ViewerFromContext(ctx context.Context) *types.Viewer {
|
|
return ctx.Value(ViewerCtx{}).(*types.Viewer)
|
|
}
|