84 lines
1.7 KiB
Go
84 lines
1.7 KiB
Go
package realname
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Provider interface {
|
|
Name() string
|
|
Start(ctx context.Context, req StartRequest) (ProviderResult, error)
|
|
}
|
|
|
|
type StartRequest struct {
|
|
UserID uint64
|
|
Name string
|
|
IDNo string
|
|
}
|
|
|
|
type ProviderResult struct {
|
|
ProviderOrderNo string
|
|
Status string
|
|
MaskedName string
|
|
MaskedIDNo string
|
|
VerifiedAt *time.Time
|
|
FailReason string
|
|
}
|
|
|
|
type MockProvider struct{}
|
|
|
|
func NewMockProvider() *MockProvider {
|
|
return &MockProvider{}
|
|
}
|
|
|
|
func (p *MockProvider) Name() string {
|
|
return "mock"
|
|
}
|
|
|
|
func (p *MockProvider) Start(_ context.Context, req StartRequest) (ProviderResult, error) {
|
|
if strings.TrimSpace(req.Name) == "" || strings.TrimSpace(req.IDNo) == "" {
|
|
return ProviderResult{}, errors.New("name and id no are required")
|
|
}
|
|
orderNo, err := randomOrderNo()
|
|
if err != nil {
|
|
return ProviderResult{}, err
|
|
}
|
|
now := time.Now()
|
|
return ProviderResult{
|
|
ProviderOrderNo: orderNo,
|
|
Status: StatusVerified,
|
|
MaskedName: maskName(req.Name),
|
|
MaskedIDNo: maskIDNo(req.IDNo),
|
|
VerifiedAt: &now,
|
|
}, nil
|
|
}
|
|
|
|
func randomOrderNo() (string, error) {
|
|
buf := make([]byte, 8)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
return "", err
|
|
}
|
|
return "mock_rn_" + hex.EncodeToString(buf), nil
|
|
}
|
|
|
|
func maskName(name string) string {
|
|
name = strings.TrimSpace(name)
|
|
if len([]rune(name)) <= 1 {
|
|
return name
|
|
}
|
|
runes := []rune(name)
|
|
return string(runes[0]) + strings.Repeat("*", len(runes)-1)
|
|
}
|
|
|
|
func maskIDNo(idNo string) string {
|
|
idNo = strings.TrimSpace(idNo)
|
|
if len(idNo) <= 8 {
|
|
return idNo
|
|
}
|
|
return idNo[:4] + strings.Repeat("*", len(idNo)-8) + idNo[len(idNo)-4:]
|
|
}
|