Files
user-system/sdk/go/user-management/device.go
long-agent 765a50b7d4 fix: 生产安全修复 + Go SDK + CAS SSO框架
安全修复:
- CRITICAL: SSO重定向URL注入漏洞 - 修复redirect_uri白名单验证
- HIGH: SSO ClientSecret未验证 - 使用crypto/subtle.ConstantTimeCompare验证
- HIGH: 邮件验证码熵值过低(3字节) - 提升到6字节(48位熵)
- HIGH: 短信验证码熵值过低(4字节) - 提升到6字节
- HIGH: Goroutine使用已取消上下文 - auth_email.go使用独立context+超时
- HIGH: SQL LIKE查询注入风险 - permission/role仓库使用escapeLikePattern

新功能:
- Go SDK: sdk/go/user-management/ 完整SDK实现
- CAS SSO框架: internal/auth/cas.go CAS协议支持

其他:
- L1Cache实例问题修复 - AuthMiddleware共享l1Cache
- 设备指纹XSS防护 - 内存存储替代localStorage
- 响应格式协议中间件
- 导出无界查询修复
2026-04-03 17:38:31 +08:00

139 lines
3.5 KiB
Go

package userManagement
import (
"context"
"fmt"
)
// ListDevicesParams 设备列表查询参数
type ListDevicesParams struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
UserID int64 `json:"user_id,omitempty"`
IsActive *bool `json:"is_active,omitempty"`
IsTrusted *bool `json:"is_trusted,omitempty"`
}
// GetMyDevices 获取当前用户的设备列表
func (c *Client) GetMyDevices(ctx context.Context) ([]*Device, error) {
resp, err := c.doRequest(ctx, "GET", "/api/v1/devices/me", nil)
if err != nil {
return nil, err
}
var result []*Device
if err := c.parseResponse(resp, &result); err != nil {
return nil, err
}
return result, nil
}
// GetTrustedDevices 获取信任设备列表
func (c *Client) GetTrustedDevices(ctx context.Context) ([]*Device, error) {
resp, err := c.doRequest(ctx, "GET", "/api/v1/devices/me/trusted", nil)
if err != nil {
return nil, err
}
var result []*Device
if err := c.parseResponse(resp, &result); err != nil {
return nil, err
}
return result, nil
}
// GetDevice 获取设备详情
func (c *Client) GetDevice(ctx context.Context, id int64) (*Device, error) {
resp, err := c.doRequest(ctx, "GET", fmt.Sprintf("/api/v1/devices/%d", id), nil)
if err != nil {
return nil, err
}
var result Device
if err := c.parseResponse(resp, &result); err != nil {
return nil, err
}
return &result, nil
}
// ListDevices 获取设备列表(管理员用)
func (c *Client) ListDevices(ctx context.Context, params *ListDevicesParams) (*PaginatedResponse, error) {
if params.Page <= 0 {
params.Page = 1
}
if params.PageSize <= 0 {
params.PageSize = 20
}
path := fmt.Sprintf("/api/v1/admin/devices?page=%d&page_size=%d", params.Page, params.PageSize)
if params.UserID > 0 {
path += fmt.Sprintf("&user_id=%d", params.UserID)
}
resp, err := c.doRequest(ctx, "GET", path, nil)
if err != nil {
return nil, err
}
var result PaginatedResponse
if err := c.parseResponse(resp, &result); err != nil {
return nil, err
}
return &result, nil
}
// TrustDevice 信任设备
func (c *Client) TrustDevice(ctx context.Context, deviceID int64) error {
resp, err := c.doRequest(ctx, "POST", fmt.Sprintf("/api/v1/devices/%d/trust", deviceID), nil)
if err != nil {
return err
}
return c.parseResponse(resp, nil)
}
// UntrustDevice 取消设备信任
func (c *Client) UntrustDevice(ctx context.Context, deviceID int64) error {
resp, err := c.doRequest(ctx, "DELETE", fmt.Sprintf("/api/v1/devices/%d/trust", deviceID), nil)
if err != nil {
return err
}
return c.parseResponse(resp, nil)
}
// TrustDeviceByDeviceID 通过 device_id 信任设备
func (c *Client) TrustDeviceByDeviceID(ctx context.Context, deviceID string) error {
resp, err := c.doRequest(ctx, "POST", fmt.Sprintf("/api/v1/devices/by-device-id/%s/trust", deviceID), nil)
if err != nil {
return err
}
return c.parseResponse(resp, nil)
}
// RevokeDevice 撤销设备
func (c *Client) RevokeDevice(ctx context.Context, deviceID int64) error {
resp, err := c.doRequest(ctx, "DELETE", fmt.Sprintf("/api/v1/devices/%d", deviceID), nil)
if err != nil {
return err
}
return c.parseResponse(resp, nil)
}
// LogoutOtherDevices 登出其他设备
func (c *Client) LogoutOtherDevices(ctx context.Context, currentDeviceID string) error {
req := map[string]string{"current_device_id": currentDeviceID}
resp, err := c.doRequest(ctx, "POST", "/api/v1/devices/me/logout-others", req)
if err != nil {
return err
}
return c.parseResponse(resp, nil)
}