103 lines
2.8 KiB
Go
103 lines
2.8 KiB
Go
package shorturlimpl
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/grafana/grafana/pkg/api/dtos"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
|
"github.com/grafana/grafana/pkg/services/shorturls"
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
var getTime = time.Now
|
|
|
|
type ShortURLService struct {
|
|
SQLStore store
|
|
}
|
|
|
|
func ProvideService(db db.DB) *ShortURLService {
|
|
return &ShortURLService{
|
|
SQLStore: &sqlStore{
|
|
db: db,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (s ShortURLService) GetShortURLByUID(ctx context.Context, user identity.Requester, uid string) (*shorturls.ShortUrl, error) {
|
|
return s.SQLStore.Get(ctx, user, uid)
|
|
}
|
|
|
|
func (s ShortURLService) UpdateLastSeenAt(ctx context.Context, shortURL *shorturls.ShortUrl) error {
|
|
return s.SQLStore.Update(ctx, shortURL)
|
|
}
|
|
|
|
func (s ShortURLService) List(ctx context.Context, orgID int64) ([]*shorturls.ShortUrl, error) {
|
|
return s.SQLStore.List(ctx, orgID)
|
|
}
|
|
|
|
func (s ShortURLService) CreateShortURL(ctx context.Context, user identity.Requester, cmd *dtos.CreateShortURLCmd) (*shorturls.ShortUrl, error) {
|
|
relPath := strings.TrimSpace(cmd.Path)
|
|
|
|
if path.IsAbs(relPath) {
|
|
return nil, shorturls.ErrShortURLAbsolutePath.Errorf("expected relative path: %s", relPath)
|
|
}
|
|
if strings.Contains(relPath, "../") {
|
|
return nil, shorturls.ErrShortURLInvalidPath.Errorf("path cannot contain '../': %s", relPath)
|
|
}
|
|
|
|
uid := cmd.UID
|
|
if uid == "" {
|
|
uid = util.GenerateShortUID()
|
|
} else {
|
|
// Ensure the UID is valid
|
|
if !util.IsValidShortUID(uid) {
|
|
return nil, shorturls.ErrShortURLBadRequest.Errorf("invalid UID: %s", uid)
|
|
}
|
|
|
|
// Check if the UID already exists
|
|
existingShortURL, err := s.SQLStore.Get(ctx, user, uid)
|
|
if err != nil {
|
|
if !shorturls.ErrShortURLNotFound.Is(err) {
|
|
return nil, shorturls.ErrShortURLInternal.Errorf("failed to check existing short URL: %w", err)
|
|
}
|
|
}
|
|
if existingShortURL != nil {
|
|
// If the UID already exists, we return an error
|
|
return nil, shorturls.ErrShortURLConflict.Errorf("short URL with UID '%s' already exists", uid)
|
|
}
|
|
}
|
|
|
|
now := time.Now().Unix()
|
|
shortURL := shorturls.ShortUrl{
|
|
OrgId: user.GetOrgID(),
|
|
Uid: uid,
|
|
Path: relPath,
|
|
CreatedAt: now,
|
|
}
|
|
shortURL.CreatedBy, _ = user.GetInternalID()
|
|
|
|
if err := s.SQLStore.Insert(ctx, &shortURL); err != nil {
|
|
return nil, shorturls.ErrShortURLInternal.Errorf("failed to insert shorturl: %w", err)
|
|
}
|
|
|
|
return &shortURL, nil
|
|
}
|
|
|
|
func (s ShortURLService) DeleteStaleShortURLs(ctx context.Context, cmd *shorturls.DeleteShortUrlCommand) error {
|
|
return s.SQLStore.Delete(ctx, cmd)
|
|
}
|
|
|
|
func (s ShortURLService) ConvertShortURLToDTO(shortURL *shorturls.ShortUrl, appURL string) *dtos.ShortURL {
|
|
url := fmt.Sprintf("%s/goto/%s?orgId=%d", strings.TrimSuffix(appURL, "/"), shortURL.Uid, shortURL.OrgId)
|
|
|
|
return &dtos.ShortURL{
|
|
UID: shortURL.Uid,
|
|
URL: url,
|
|
}
|
|
}
|