iris/context/context_user.go
2020-10-12 15:52:53 +03:00

145 lines
3.8 KiB
Go

package context
import (
"errors"
"time"
)
// ErrNotSupported is fired when a specific method is not implemented
// or not supported entirely.
// Can be used by User implementations when
// an authentication system does not implement a specific, but required,
// method of the User interface.
var ErrNotSupported = errors.New("not supported")
// User is a generic view of an authorized client.
// See `Context.User` and `SetUser` methods for more.
//
// The informational methods starts with a "Get" prefix
// in order to allow the implementation to contain exported
// fields such as `Username` so they can be JSON encoded when necessary.
//
// The caller is free to cast this with the implementation directly
// when special features are offered by the authorization system.
type User interface {
// GetAuthorization should return the authorization method,
// e.g. Basic Authentication.
GetAuthorization() string
// GetAuthorizedAt should return the exact time the
// client has been authorized for the "first" time.
GetAuthorizedAt() time.Time
// GetUsername should return the name of the User.
GetUsername() string
// GetPassword should return the encoded or raw password
// (depends on the implementation) of the User.
GetPassword() string
// GetEmail should return the e-mail of the User.
GetEmail() string
}
// FeaturedUser optional interface that a User can implement.
type FeaturedUser interface {
User
// GetFeatures should optionally return a list of features
// the User implementation offers.
GetFeatures() []UserFeature
}
// UserFeature a type which represents a user's optional feature.
// See `HasUserFeature` function for more.
type UserFeature uint32
// The list of standard UserFeatures.
const (
AuthorizedAtFeature UserFeature = iota
UsernameFeature
PasswordFeature
EmailFeature
)
// HasUserFeature reports whether the "u" User
// implements a specific "feature" User Feature.
//
// It returns ErrNotSupported if a user does not implement
// the FeaturedUser interface.
func HasUserFeature(user User, feature UserFeature) (bool, error) {
if u, ok := user.(FeaturedUser); ok {
for _, f := range u.GetFeatures() {
if f == feature {
return true, nil
}
}
return false, nil
}
return false, ErrNotSupported
}
// SimpleUser is a simple implementation of the User interface.
type SimpleUser struct {
Authorization string `json:"authorization"`
AuthorizedAt time.Time `json:"authorized_at"`
Username string `json:"username"`
Password string `json:"-"`
Email string `json:"email,omitempty"`
Features []UserFeature `json:"-"`
}
var _ User = (*SimpleUser)(nil)
// GetAuthorization returns the authorization method,
// e.g. Basic Authentication.
func (u *SimpleUser) GetAuthorization() string {
return u.Authorization
}
// GetAuthorizedAt returns the exact time the
// client has been authorized for the "first" time.
func (u *SimpleUser) GetAuthorizedAt() time.Time {
return u.AuthorizedAt
}
// GetUsername returns the name of the User.
func (u *SimpleUser) GetUsername() string {
return u.Username
}
// GetPassword returns the raw password of the User.
func (u *SimpleUser) GetPassword() string {
return u.Password
}
// GetEmail returns the e-mail of the User.
func (u *SimpleUser) GetEmail() string {
return u.Email
}
// GetFeatures returns a list of features
// this User implementation offers.
func (u *SimpleUser) GetFeatures() []UserFeature {
if u.Features != nil {
return u.Features
}
var features []UserFeature
if !u.AuthorizedAt.IsZero() {
features = append(features, AuthorizedAtFeature)
}
if u.Username != "" {
features = append(features, UsernameFeature)
}
if u.Password != "" {
features = append(features, PasswordFeature)
}
if u.Email != "" {
features = append(features, EmailFeature)
}
return features
}