[server] Encrich admin api response (#4148)

## Description

## Tests
This commit is contained in:
Neeraj Gupta
2024-11-22 15:29:24 +05:30
committed by GitHub
8 changed files with 65 additions and 6 deletions

View File

@@ -627,6 +627,7 @@ func main() {
QueueRepo: queueRepo,
UserRepo: userRepo,
CollectionRepo: collectionRepo,
AuthenticatorRepo: authRepo,
UserAuthRepo: userAuthRepo,
UserController: userController,
FamilyController: familyController,

View File

@@ -36,6 +36,14 @@ type LogoutSessionReq struct {
UserID int64 `json:"userID" binding:"required"`
}
type TokenInfo struct {
CreationTime int64 `json:"creationTime"`
LastUsedTime int64 `json:"lastUsedTime"`
UA string `json:"ua"`
IsDeleted bool `json:"isDeleted"`
App App `json:"app"`
}
func (a AdminOttReq) Validate() error {
if !a.App.IsValid() {
return errors.New("invalid app")

View File

@@ -195,9 +195,10 @@ type TwoFactorRemovalRequest struct {
type ProfileData struct {
// CanDisableEmailMFA is used to decide if client should show disable email MFA option
CanDisableEmailMFA bool `json:"canDisableEmailMFA"`
IsEmailMFAEnabled bool `json:"isEmailMFAEnabled"`
IsTwoFactorEnabled bool `json:"isTwoFactorEnabled"`
CanDisableEmailMFA bool `json:"canDisableEmailMFA"`
IsEmailMFAEnabled bool `json:"isEmailMFAEnabled"`
IsTwoFactorEnabled bool `json:"isTwoFactorEnabled"`
PasskeyCount int64 `json:"passkeyCount"`
}
type Session struct {

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"github.com/ente-io/museum/pkg/controller/remotestore"
"github.com/ente-io/museum/pkg/repo/authenticator"
"net/http"
"strconv"
"strings"
@@ -39,6 +40,7 @@ type AdminHandler struct {
QueueRepo *repo.QueueRepository
UserRepo *repo.UserRepository
CollectionRepo *repo.CollectionRepository
AuthenticatorRepo *authenticator.Repository
UserAuthRepo *repo.UserAuthRepository
FileRepo *repo.FileRepository
BillingRepo *repo.BillingRepository
@@ -113,7 +115,7 @@ func (h *AdminHandler) GetUsers(c *gin.Context) {
}
func (h *AdminHandler) GetUser(c *gin.Context) {
e := c.Query("email")
e := strings.ToLower(strings.TrimSpace(c.Query("email")))
if e == "" {
id, err := strconv.ParseInt(c.Query("id"), 10, 64)
if err != nil {
@@ -571,6 +573,14 @@ func (h *AdminHandler) attachSubscription(ctx *gin.Context, userID int64, respon
if err == nil {
response["details"] = details
}
tokenInfos, err := h.UserAuthRepo.GetUserTokenInfo(userID)
if err == nil {
response["tokens"] = tokenInfos
}
authEntryCount, err := h.AuthenticatorRepo.GetAuthCodeCount(ctx, userID)
if err == nil {
response["authCodes"] = authEntryCount
}
}
func (h *AdminHandler) ClearOrphanObjects(c *gin.Context) {

View File

@@ -5,7 +5,6 @@ import (
"github.com/ente-io/museum/ente"
"github.com/ente-io/museum/ente/details"
bonus "github.com/ente-io/museum/ente/storagebonus"
"github.com/ente-io/museum/pkg/utils/recover"
"github.com/ente-io/museum/pkg/utils/time"
"github.com/ente-io/stacktrace"
"github.com/gin-gonic/gin"
@@ -27,6 +26,7 @@ func (c *UserController) GetDetailsV2(ctx *gin.Context, userID int64, fetchMemor
var familyData *ente.FamilyMemberResponse
var subscription *ente.Subscription
var canDisableEmailMFA bool
var passkeyCount int64
var fileCount, sharedCollectionCount, usage int64
var bonus *bonus.ActiveStorageBonus
g.Go(func() error {
@@ -69,7 +69,12 @@ func (c *UserController) GetDetailsV2(ctx *gin.Context, userID int64, fetchMemor
return nil
})
g.Go(func() error {
return recover.Int64ToInt64RecoverWrapper(userID, c.FileRepo.GetUsage, &usage)
cnt, err := c.PasskeyRepo.GetPasskeyCount(userID)
if err != nil {
return stacktrace.Propagate(err, "")
}
passkeyCount = cnt
return nil
})
if fetchMemoryCount {
@@ -111,6 +116,7 @@ func (c *UserController) GetDetailsV2(ctx *gin.Context, userID int64, fetchMemor
CanDisableEmailMFA: canDisableEmailMFA,
IsEmailMFAEnabled: *user.IsEmailMFAEnabled,
IsTwoFactorEnabled: *user.IsTwoFactorEnabled,
PasskeyCount: passkeyCount,
},
BonusData: bonus,
}

View File

@@ -89,6 +89,16 @@ func (r *Repository) Update(ctx context.Context, userID int64, req model.UpdateE
return nil
}
// GetAuthCodeCount returns the count of the authenticator entries for the given user
func (r *Repository) GetAuthCodeCount(ctx context.Context, userID int64) (int64, error) {
var count int64
err := r.DB.QueryRowContext(ctx, `SELECT count(*) FROM authenticator_entity WHERE user_id = $1 and is_deleted = FALSE`, userID).Scan(&count)
if err != nil {
return 0, stacktrace.Propagate(err, "failed to get auth code count")
}
return count, nil
}
// GetDiff returns the &{[]ente.TotpEntity} which have been added or
// modified after the given sinceTime
func (r *Repository) GetDiff(ctx context.Context, userID int64, sinceTime int64, limit int16) ([]model.Entity, error) {

View File

@@ -101,6 +101,11 @@ func NewRepository(
return
}
func (r *Repository) GetPasskeyCount(userID int64) (count int64, err error) {
err = r.DB.QueryRow(`SELECT COUNT(*) FROM passkeys WHERE user_id = $1 AND deleted_at IS NULL`, userID).Scan(&count)
return
}
func (r *Repository) GetUserPasskeys(userID int64) (passkeys []ente.Passkey, err error) {
rows, err := r.DB.Query(`
SELECT id, user_id, friendly_name, created_at

View File

@@ -48,6 +48,24 @@ func (repo *UserAuthRepository) GetTokenCreationTime(token string) (int64, error
return result, nil
}
func (repo *UserAuthRepository) GetUserTokenInfo(userID int64) ([]ente.TokenInfo, error) {
rows, err := repo.DB.Query(`SELECT creation_time, last_used_at, user_agent, is_deleted, app FROM tokens WHERE user_id = $1 AND is_deleted = false`, userID)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
defer rows.Close()
tokenInfos := make([]ente.TokenInfo, 0)
for rows.Next() {
var tokenInfo ente.TokenInfo
err := rows.Scan(&tokenInfo.CreationTime, &tokenInfo.LastUsedTime, &tokenInfo.UA, &tokenInfo.IsDeleted, &tokenInfo.App)
if err != nil {
return nil, stacktrace.Propagate(err, "")
}
tokenInfos = append(tokenInfos, tokenInfo)
}
return tokenInfos, nil
}
// GetValidOTTs returns the list of OTTs that haven't expired for a given user
func (repo *UserAuthRepository) GetValidOTTs(emailHash string, app ente.App) ([]string, error) {
rows, err := repo.DB.Query(`SELECT ott FROM otts WHERE email_hash = $1 AND app = $2 AND expiration_time > $3`,