code.gitea.io/gitea@v1.21.7/models/user/list.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package user
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"code.gitea.io/gitea/models/auth"
    11  	"code.gitea.io/gitea/models/db"
    12  )
    13  
    14  // UserList is a list of user.
    15  // This type provide valuable methods to retrieve information for a group of users efficiently.
    16  type UserList []*User //revive:disable-line:exported
    17  
    18  // GetUserIDs returns a slice of user's id
    19  func (users UserList) GetUserIDs() []int64 {
    20  	userIDs := make([]int64, 0, len(users))
    21  	for _, user := range users {
    22  		userIDs = append(userIDs, user.ID) // Considering that user id are unique in the list
    23  	}
    24  	return userIDs
    25  }
    26  
    27  // GetTwoFaStatus return state of 2FA enrollement
    28  func (users UserList) GetTwoFaStatus(ctx context.Context) map[int64]bool {
    29  	results := make(map[int64]bool, len(users))
    30  	for _, user := range users {
    31  		results[user.ID] = false // Set default to false
    32  	}
    33  
    34  	if tokenMaps, err := users.loadTwoFactorStatus(ctx); err == nil {
    35  		for _, token := range tokenMaps {
    36  			results[token.UID] = true
    37  		}
    38  	}
    39  
    40  	if ids, err := users.userIDsWithWebAuthn(ctx); err == nil {
    41  		for _, id := range ids {
    42  			results[id] = true
    43  		}
    44  	}
    45  
    46  	return results
    47  }
    48  
    49  func (users UserList) loadTwoFactorStatus(ctx context.Context) (map[int64]*auth.TwoFactor, error) {
    50  	if len(users) == 0 {
    51  		return nil, nil
    52  	}
    53  
    54  	userIDs := users.GetUserIDs()
    55  	tokenMaps := make(map[int64]*auth.TwoFactor, len(userIDs))
    56  	if err := db.GetEngine(ctx).In("uid", userIDs).Find(&tokenMaps); err != nil {
    57  		return nil, fmt.Errorf("find two factor: %w", err)
    58  	}
    59  	return tokenMaps, nil
    60  }
    61  
    62  func (users UserList) userIDsWithWebAuthn(ctx context.Context) ([]int64, error) {
    63  	if len(users) == 0 {
    64  		return nil, nil
    65  	}
    66  	ids := make([]int64, 0, len(users))
    67  	if err := db.GetEngine(ctx).Table(new(auth.WebAuthnCredential)).In("user_id", users.GetUserIDs()).Select("user_id").Distinct("user_id").Find(&ids); err != nil {
    68  		return nil, fmt.Errorf("find two factor: %w", err)
    69  	}
    70  	return ids, nil
    71  }
    72  
    73  // GetUsersByIDs returns all resolved users from a list of Ids.
    74  func GetUsersByIDs(ctx context.Context, ids []int64) (UserList, error) {
    75  	ous := make([]*User, 0, len(ids))
    76  	if len(ids) == 0 {
    77  		return ous, nil
    78  	}
    79  	err := db.GetEngine(ctx).In("id", ids).
    80  		Asc("name").
    81  		Find(&ous)
    82  	return ous, err
    83  }