feat: 完善用户治理与登录白名单
This commit is contained in:
@@ -270,12 +270,13 @@ func internalAdminQuerySpec(resource string) (*internalQuerySpec, bool) {
|
||||
func usersInternalQuerySpec() *internalQuerySpec {
|
||||
return &internalQuerySpec{
|
||||
Select: `SELECT CAST(u.id AS CHAR) AS user_id,u.username,u.phone,u.state,u.stateat AS state_at,u.access,u.lastseen AS last_seen,u.useragent AS user_agent,u.public,u.trusted,
|
||||
p.nickname,p.public_account,p.gender,p.region,p.avatar_file_id,p.signature,sec.auth_version,sec.password_updated_at,u.createdat AS created_at,u.updatedat AS updated_at,
|
||||
p.nickname,p.public_account,p.gender,p.region,p.avatar_file_id,COALESCE(avatar.location,'') AS avatar,p.signature,sec.auth_version,sec.password_updated_at,u.createdat AS created_at,u.updatedat AS updated_at,
|
||||
CASE WHEN EXISTS(SELECT 1 FROM im_registration_invite_uses AS invite_use WHERE invite_use.user_id=u.id) THEN 'invite_code' WHEN COALESCE(u.phone,'')<>'' THEN 'mobile' ELSE 'admin' END AS register_type,
|
||||
(SELECT JSON_ARRAYAGG(JSON_OBJECT('method',c.method,'value',c.value,'done',c.done,'updated_at',c.updatedat)) FROM im_credentials AS c WHERE c.userid=u.id AND c.deletedat IS NULL) AS credentials`,
|
||||
From: "FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id LEFT JOIN im_user_security AS sec ON sec.user_id=u.id",
|
||||
From: "FROM im_users AS u LEFT JOIN im_user_profiles AS p ON p.user_id=u.id LEFT JOIN im_user_security AS sec ON sec.user_id=u.id LEFT JOIN im_fileuploads AS avatar ON avatar.id=CAST(p.avatar_file_id AS UNSIGNED) AND p.avatar_file_id REGEXP '^[0-9]+$'",
|
||||
DefaultSort: "ORDER BY u.id DESC",
|
||||
DetailKey: "u.id",
|
||||
Filters: []internalQueryFilter{{"user_id", "u.id", "=", "uid"}, {"nickname", "p.nickname", "LIKE", "string"}, {"auth_name", "u.username", "LIKE", "string"}, {"state", "u.state", "=", "int"}, {"created_at_start", "u.createdat", ">=", "time"}, {"created_at_end", "u.createdat", "<=", "time"}, {"last_seen_start", "u.lastseen", ">=", "time"}, {"last_seen_end", "u.lastseen", "<=", "time"}},
|
||||
Filters: []internalQueryFilter{{"user_id", "u.id", "=", "uid"}, {"user_ids", "u.id", "IN", "uid_list"}, {"keyword", "CONCAT_WS(' ',u.username,p.nickname,u.phone)", "LIKE", "string"}, {"nickname", "p.nickname", "LIKE", "string"}, {"auth_name", "u.username", "LIKE", "string"}, {"state", "u.state", "=", "int"}, {"created_at_start", "u.createdat", ">=", "time"}, {"created_at_end", "u.createdat", "<=", "time"}, {"last_seen_start", "u.lastseen", ">=", "time"}, {"last_seen_end", "u.lastseen", "<=", "time"}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +405,16 @@ func buildInternalAdminListQuery(req *http.Request, spec *internalQuerySpec, sco
|
||||
if err != nil {
|
||||
return "", "", nil, 0, 0, err
|
||||
}
|
||||
if filter.Kind == "uid_list" {
|
||||
ids := value.([]any)
|
||||
placeholders := make([]string, len(ids))
|
||||
for i := range ids {
|
||||
placeholders[i] = "?"
|
||||
}
|
||||
where = append(where, filter.Column+" IN ("+strings.Join(placeholders, ",")+")")
|
||||
args = append(args, ids...)
|
||||
continue
|
||||
}
|
||||
op := filter.Op
|
||||
if op == "" {
|
||||
op = "="
|
||||
@@ -430,6 +441,20 @@ func internalAdminFilterValue(_ string, raw, kind string) (any, error) {
|
||||
return id, nil
|
||||
case "int":
|
||||
return strconv.ParseInt(raw, 10, 64)
|
||||
case "uid_list":
|
||||
parts := strings.Split(raw, ",")
|
||||
if len(parts) == 0 || len(parts) > 5000 {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
ids := make([]any, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
id, ok := parseInternalAdminDBID(strings.TrimSpace(part))
|
||||
if !ok {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return ids, nil
|
||||
default:
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user