| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- package helper
- import (
- "fwh-toolbox-server/domain"
- "fwh-toolbox-server/dto"
- )
- // sanitizeStrong 尝试对已知的强类型做源头脱敏(优化 A)。
- //
- // 返回:
- // - 脱敏后的数据副本 + true:命中强类型,已完成脱敏。
- // - nil + false:未命中强类型,调用方应改走流式脱敏(优化 B)。
- //
- // 设计约束:所有脱敏均作用于输入数据的副本,绝不修改上游对象(这些对象
- // 可能来自 Mongo 缓存或被其他调用方共享)。规则与掩码函数复用 pii_rules.go,
- // 确保 A 与 B 的行为一致。
- func sanitizeStrong(data any) (any, bool) {
- switch v := data.(type) {
- case *dto.SiteInfoDTO:
- if v == nil {
- return v, true
- }
- cp := *v
- sanitizeSiteInfoDTO(&cp)
- return &cp, true
- case dto.SiteInfoDTO:
- sanitizeSiteInfoDTO(&v)
- return v, true
- case *dto.ResPage[dto.SiteInfoDTO]:
- if v == nil {
- return v, true
- }
- cp := *v
- cp.Data = make([]dto.SiteInfoDTO, len(v.Data))
- copy(cp.Data, v.Data)
- for i := range cp.Data {
- sanitizeSiteInfoDTO(&cp.Data[i])
- }
- return &cp, true
- case *domain.SimCardInfo:
- if v == nil {
- return v, true
- }
- cp := *v
- sanitizeDomainSimCardInfo(&cp)
- return &cp, true
- case *dto.SimCardInfo:
- if v == nil {
- return v, true
- }
- cp := *v
- sanitizeDTOSimCardInfo(&cp)
- return &cp, true
- case *dto.ResPage[dto.SimCardInfo]:
- if v == nil {
- return v, true
- }
- cp := *v
- cp.Data = make([]dto.SimCardInfo, len(v.Data))
- copy(cp.Data, v.Data)
- for i := range cp.Data {
- sanitizeDTOSimCardInfo(&cp.Data[i])
- }
- return &cp, true
- case *dto.ResPage[domain.SimCardInfo]:
- if v == nil {
- return v, true
- }
- cp := *v
- cp.Data = make([]domain.SimCardInfo, len(v.Data))
- copy(cp.Data, v.Data)
- for i := range cp.Data {
- sanitizeDomainSimCardInfo(&cp.Data[i])
- }
- return &cp, true
- case *domain.SimCardMonthlyData:
- if v == nil {
- return v, true
- }
- cp := *v
- sanitizeSimCardMonthlyData(&cp)
- return &cp, true
- default:
- return nil, false
- }
- }
- // maskStrPtr 对 *string 字段就地脱敏(作用于副本的指针,需重新分配以免污染原值)。
- func maskStrPtr(p **string, kind MaskKind) {
- if p == nil || *p == nil {
- return
- }
- masked := applyMaskString(kind, **p)
- *p = &masked
- }
- func maskStr(s *string, kind MaskKind) {
- if s == nil {
- return
- }
- *s = applyMaskString(kind, *s)
- }
- // sanitizeSiteInfoDTO 对站点信息做字段级脱敏。
- // 保留:city / province / country(行政区)、iccId(业务标识)、sn、各类版本与状态字段。
- func sanitizeSiteInfoDTO(s *dto.SiteInfoDTO) {
- // 姓名
- maskStrPtr(&s.UserName, MaskName)
- maskStrPtr(&s.FirstName, MaskName)
- maskStrPtr(&s.LastName, MaskName)
- maskStrPtr(&s.AccountName, MaskName)
- maskStrPtr(&s.FinancierName, MaskName)
- // 手机号 —— 完全脱敏
- maskStrPtr(&s.ContactNumber, MaskFull)
- maskStrPtr(&s.FinancierContractNumber, MaskFull)
- // 完整地址串 —— 完全脱敏
- maskStrPtr(&s.Address, MaskFull)
- maskStrPtr(&s.DeviceAddress, MaskFull)
- maskStrPtr(&s.AddressSecondLast, MaskFull)
- // 经纬度 —— 完全脱敏(string 类型)
- s.Longitude = maskFull()
- s.Latitude = maskFull()
- // 账号
- maskStrPtr(&s.Account, MaskAccount)
- maskStrPtr(&s.InstallerAccount, MaskAccount)
- // 设备/网络标识 —— 完全脱敏(保留 ICCID)
- maskStrPtr(&s.Mac, MaskFull)
- maskStrPtr(&s.DeviceIp, MaskFull)
- maskStrPtr(&s.GatewayIp, MaskFull)
- s.IMEI = maskFull()
- // s.ICCID 保留
- }
- // sanitizeDomainSimCardInfo 对 domain.SimCardInfo 脱敏(保留 GICCID)。
- func sanitizeDomainSimCardInfo(s *domain.SimCardInfo) {
- s.IMEI = maskFull()
- s.IMSI = maskFull()
- s.MSISDN = maskFull()
- // s.GICCID 保留
- }
- // sanitizeDTOSimCardInfo 对 dto.SimCardInfo 脱敏(保留 GICCID、SN 列表)。
- func sanitizeDTOSimCardInfo(s *dto.SimCardInfo) {
- s.IMEI = maskFull()
- s.IMSI = maskFull()
- s.MSISDN = maskFull()
- // s.GICCID / s.SN 保留
- }
- // sanitizeSimCardMonthlyData 月用量数据本身不含 IMEI/IMSI/MSISDN,仅含 GICCID(simId) 与用量,
- // 无需脱敏;保留以显式声明该类型已被审阅。
- func sanitizeSimCardMonthlyData(_ *domain.SimCardMonthlyData) {}
|