Use max select query for user last access time

This commit is contained in:
Akshay Gaikwad
2022-11-03 18:16:22 +05:30
parent 1d850cb409
commit bde018a3c7
8 changed files with 56 additions and 79 deletions
+23 -16
View File
@@ -548,29 +548,19 @@ func (s *userService) GetByName(ctx context.Context, user *userv3.User) (*userv3
return &userv3.User{}, err
}
err = s.updateLastLogin(ctx, user, usr.ID)
lastLogin, err := s.getUserLastLogin(ctx, usr.ID)
if err != nil {
return &userv3.User{}, err
}
if lastLogin != "" {
user.GetSpec().LastLogin = lastLogin
}
return user, nil
}
return user, nil
}
// updateLastLogin updates the last login field of the user provided.
func (s *userService) updateLastLogin(ctx context.Context, user *userv3.User, userId uuid.UUID) error {
lastLogin := "NA"
sessions, err := dao.GetUserSessions(ctx, s.db, userId)
if err != nil {
return err
}
if len(sessions) != 0 {
lastLogin = getLastLoginTime(sessions).Format(time.RFC3339)
}
user.GetSpec().LastLogin = lastLogin
return nil
}
func (s *userService) GetUserInfo(ctx context.Context, user *userv3.User) (*userv3.UserInfo, error) {
username := ""
if s.dev {
@@ -911,10 +901,15 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U
if err != nil {
return userList, err
}
err = s.updateLastLogin(ctx, user, usr.ID)
lastLogin, err := s.getUserLastLogin(ctx, usr.ID)
if err != nil {
return userList, err
}
if lastLogin != "" {
user.GetSpec().LastLogin = lastLogin
}
users = append(users, user)
}
@@ -1072,3 +1067,15 @@ func (s *userService) ForgotPassword(ctx context.Context, req *userrpcv3.UserFor
return &userrpcv3.UserForgotPasswordResponse{}, fmt.Errorf("unable to generate recovery url")
}
}
func (s *userService) getUserLastLogin(ctx context.Context, userId uuid.UUID) (string, error) {
var lastLogin string
authTime, err := dao.GetUserLastAuthTime(ctx, s.db, userId)
if err != nil {
return "", err
}
if !authTime.IsZero() {
lastLogin = authTime.Format(time.RFC3339)
}
return lastLogin, nil
}
+9 -9
View File
@@ -404,9 +404,9 @@ func TestUserGetByName(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+pruuid))
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid + `'`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, "ns"))
mock.ExpectQuery(`SELECT "sessions"."id", "sessions"."authenticated_at", "sessions"."identity_id".* FROM "sessions" WHERE .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "authenticated_at", "identity_id"}).
AddRow(uuuid, authenticated, uuuid))
mock.ExpectQuery(`select .* from sessions where .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"max"}).
AddRow(authenticated))
user := &userv3.User{
Metadata: &v3.Metadata{Partner: "partner-" + puuid, Organization: "org-" + ouuid, Name: "user-" + uuuid},
@@ -631,16 +631,16 @@ func TestUserList(t *testing.T) {
guuid := addUsersGroupFetchExpectation(mock, uuuid1)
addGroupRoleMappingsFetchExpectation(mock, guuid, pruuid)
addUserRoleMappingsFetchExpectation(mock, uuuid1, pruuid)
mock.ExpectQuery(`SELECT "sessions"."id", "sessions"."authenticated_at", "sessions"."identity_id".* FROM "sessions" WHERE .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "authenticated_at", "identity_id"}).
AddRow(uuuid1, authenticated, uuuid1))
mock.ExpectQuery(`select .* from sessions where .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"max"}).
AddRow(authenticated))
guuid = addUsersGroupFetchExpectation(mock, uuuid2)
addGroupRoleMappingsFetchExpectation(mock, guuid, pruuid)
addUserRoleMappingsFetchExpectation(mock, uuuid2, pruuid)
mock.ExpectQuery(`SELECT "sessions"."id", "sessions"."authenticated_at", "sessions"."identity_id".* FROM "sessions" WHERE .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "authenticated_at", "identity_id"}).
AddRow(uuuid1, authenticated, uuuid1))
mock.ExpectQuery(`select .* from sessions where .*`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"max"}).
AddRow(authenticated))
qo := &commonv3.QueryOptions{
Q: tc.q,
-17
View File
@@ -2,11 +2,9 @@ package service
import (
"context"
"time"
"github.com/google/uuid"
"github.com/paralus/paralus/internal/dao"
"github.com/paralus/paralus/internal/models"
"github.com/paralus/paralus/pkg/common"
commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3"
"github.com/uptrace/bun"
@@ -35,18 +33,3 @@ func IsInternalRequest(ctx context.Context) bool {
b, ok := v.(bool)
return ok && b
}
// getLastLoginTime return latest authenticated time from sessions.
func getLastLoginTime(sessions []models.KratosSessions) time.Time {
var auths []int64
for _, s := range sessions {
auths = append(auths, s.AuthenticatedAt.UnixMilli())
}
latest := auths[0]
for _, auth := range auths {
if auth > latest {
latest = auth
}
}
return time.UnixMilli(latest)
}