package auth import ( "fmt" "time" ) type Manager struct { Store *UserStore JWT *JWTManager Enforcer *EnforcerWrapper } func NewManager(jwtSecret string, jwtTTL time.Duration, modelPath, policyPath, userFile string) (*Manager, error) { store, err := NewUserStore(userFile) if err != nil { return nil, fmt.Errorf("init user store: %w", err) } jwtMgr := NewJWTManager(jwtSecret, jwtTTL) enc, err := NewEnforcer(modelPath, policyPath, store) if err != nil { return nil, fmt.Errorf("init casbin: %w", err) } m := &Manager{Store: store, JWT: jwtMgr, Enforcer: enc} return m, nil } func NewManagerWithStore(store *UserStore, jwtSecret string, ttl time.Duration, enforcer *EnforcerWrapper) *Manager { return &Manager{ Store: store, JWT: NewJWTManager(jwtSecret, ttl), Enforcer: enforcer, } } func (m *Manager) Login(username, password string) (string, *User, error) { u, ok := m.Store.Verify(username, password) if !ok { return "", nil, fmt.Errorf("invalid credentials") } _ = m.Enforcer.AddUserRole(u.Username, u.Role) token, err := m.JWT.Sign(u.Username, u.Role) if err != nil { return "", nil, err } ret := &User{Username: u.Username, Role: u.Role, CreatedAt: u.CreatedAt} return token, ret, nil } func (m *Manager) Register(username, password, role string) (string, *User, error) { if role == "" { role = RoleViewer } u, err := m.Store.Create(username, password, role) if err != nil { return "", nil, err } _ = m.Enforcer.AddUserRole(u.Username, u.Role) token, err := m.JWT.Sign(u.Username, u.Role) if err != nil { return "", nil, err } return token, u, nil } func (m *Manager) VerifyToken(token string) (*Claims, *User, error) { claims, err := m.JWT.Verify(token) if err != nil { return nil, nil, err } if u, ok := m.Store.Get(claims.Username); ok { claims.Role = u.Role return claims, &User{Username: u.Username, Role: u.Role, CreatedAt: u.CreatedAt}, nil } return claims, &User{Username: claims.Username, Role: claims.Role}, nil } func (m *Manager) Check(username, role, obj, act string) (bool, error) { if role == "" { if u, ok := m.Store.Get(username); ok { role = u.Role } else { role = RoleGuest } } sub := username if sub == "" { sub = role } return m.Enforcer.Enforce(sub, obj, act) } func (m *Manager) UpdateUserRole(targetUser, newRole string) error { if err := m.Store.UpdateRole(targetUser, newRole); err != nil { return err } return m.Enforcer.AddUserRole(targetUser, newRole) }