2021-03-14 13:08:50 +13:00
|
|
|
package member
|
|
|
|
|
|
|
|
import (
|
2021-08-30 03:09:13 +12:00
|
|
|
"errors"
|
2021-03-15 04:58:18 +13:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
|
2022-07-14 10:58:22 +12:00
|
|
|
"github.com/demodesk/neko/internal/config"
|
|
|
|
"github.com/demodesk/neko/internal/member/file"
|
2023-01-13 12:00:09 +13:00
|
|
|
"github.com/demodesk/neko/internal/member/multiuser"
|
2023-01-13 12:03:59 +13:00
|
|
|
"github.com/demodesk/neko/internal/member/noauth"
|
2022-07-14 10:58:22 +12:00
|
|
|
"github.com/demodesk/neko/internal/member/object"
|
|
|
|
"github.com/demodesk/neko/pkg/types"
|
2021-03-14 13:08:50 +13:00
|
|
|
)
|
|
|
|
|
2021-03-15 07:59:34 +13:00
|
|
|
func New(sessions types.SessionManager, config *config.Member) *MemberManagerCtx {
|
2021-03-15 04:58:18 +13:00
|
|
|
manager := &MemberManagerCtx{
|
2021-03-15 07:59:34 +13:00
|
|
|
logger: log.With().Str("module", "member").Logger(),
|
|
|
|
sessions: sessions,
|
|
|
|
config: config,
|
2021-03-15 04:58:18 +13:00
|
|
|
}
|
|
|
|
|
2021-03-14 13:08:50 +13:00
|
|
|
switch config.Provider {
|
|
|
|
case "file":
|
2021-03-17 03:28:40 +13:00
|
|
|
manager.provider = file.New(config.File)
|
2021-03-14 13:08:50 +13:00
|
|
|
case "object":
|
2021-03-17 03:28:40 +13:00
|
|
|
manager.provider = object.New(config.Object)
|
2023-01-13 12:00:09 +13:00
|
|
|
case "multiuser":
|
|
|
|
manager.provider = multiuser.New(config.Multiuser)
|
2023-01-13 12:03:59 +13:00
|
|
|
case "noauth":
|
2021-03-15 04:58:18 +13:00
|
|
|
fallthrough
|
|
|
|
default:
|
2023-01-13 12:03:59 +13:00
|
|
|
manager.provider = noauth.New()
|
2021-03-14 13:08:50 +13:00
|
|
|
}
|
2021-03-15 08:26:58 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager
|
|
|
|
}
|
|
|
|
|
|
|
|
type MemberManagerCtx struct {
|
2021-03-15 08:26:30 +13:00
|
|
|
logger zerolog.Logger
|
|
|
|
sessions types.SessionManager
|
|
|
|
config *config.Member
|
|
|
|
providerMu sync.Mutex
|
|
|
|
provider types.MemberProvider
|
2021-08-30 03:09:13 +12:00
|
|
|
loginMu sync.Mutex
|
2021-03-15 04:58:18 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Connect() error {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Connect()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Disconnect() error {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Disconnect()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Authenticate(username string, password string) (string, types.MemberProfile, error) {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Authenticate(username, password)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Insert(username, password, profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Select(id string) (types.MemberProfile, error) {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2023-01-13 12:15:19 +13:00
|
|
|
// get primarily from corresponding session, if exists
|
|
|
|
session, ok := manager.sessions.Get(id)
|
|
|
|
if ok {
|
|
|
|
return session.Profile(), nil
|
|
|
|
}
|
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Select(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) SelectAll(limit int, offset int) (map[string]types.MemberProfile, error) {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.SelectAll(limit, offset)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) UpdateProfile(id string, profile types.MemberProfile) error {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 07:59:34 +13:00
|
|
|
// update corresponding session, if exists
|
2021-08-30 03:09:13 +12:00
|
|
|
err := manager.sessions.Update(id, profile)
|
|
|
|
if err != nil && !errors.Is(err, types.ErrSessionNotFound) {
|
|
|
|
manager.logger.Err(err).Msg("error while updating session")
|
2021-03-15 07:59:34 +13:00
|
|
|
}
|
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.UpdateProfile(id, profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) UpdatePassword(id string, password string) error {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.UpdatePassword(id, password)
|
|
|
|
}
|
2021-03-14 13:08:50 +13:00
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
func (manager *MemberManagerCtx) Delete(id string) error {
|
2021-03-15 08:26:30 +13:00
|
|
|
manager.providerMu.Lock()
|
|
|
|
defer manager.providerMu.Unlock()
|
2021-03-15 07:36:30 +13:00
|
|
|
|
2021-03-15 07:59:34 +13:00
|
|
|
// destroy corresponding session, if exists
|
2021-08-30 03:09:13 +12:00
|
|
|
err := manager.sessions.Delete(id)
|
|
|
|
if err != nil && !errors.Is(err, types.ErrSessionNotFound) {
|
|
|
|
manager.logger.Err(err).Msg("error while deleting session")
|
2021-03-15 07:59:34 +13:00
|
|
|
}
|
|
|
|
|
2021-03-15 04:58:18 +13:00
|
|
|
return manager.provider.Delete(id)
|
2021-03-14 13:08:50 +13:00
|
|
|
}
|
2021-03-15 07:59:34 +13:00
|
|
|
|
|
|
|
//
|
|
|
|
// member -> session
|
|
|
|
//
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Login(username string, password string) (types.Session, string, error) {
|
2021-08-30 03:09:13 +12:00
|
|
|
manager.loginMu.Lock()
|
|
|
|
defer manager.loginMu.Unlock()
|
2021-03-15 08:26:30 +13:00
|
|
|
|
2021-03-15 07:59:34 +13:00
|
|
|
id, profile, err := manager.provider.Authenticate(username, password)
|
|
|
|
if err != nil {
|
|
|
|
return nil, "", err
|
|
|
|
}
|
|
|
|
|
2021-03-15 08:26:30 +13:00
|
|
|
session, ok := manager.sessions.Get(id)
|
|
|
|
if ok {
|
|
|
|
if session.State().IsConnected {
|
2021-08-30 03:09:13 +12:00
|
|
|
return nil, "", types.ErrSessionAlreadyConnected
|
2021-03-15 08:26:30 +13:00
|
|
|
}
|
|
|
|
|
2021-03-16 22:53:03 +13:00
|
|
|
// TODO: Replace session.
|
|
|
|
if err := manager.sessions.Delete(id); err != nil {
|
|
|
|
return nil, "", err
|
|
|
|
}
|
2021-03-15 08:26:30 +13:00
|
|
|
}
|
|
|
|
|
2021-03-15 07:59:34 +13:00
|
|
|
return manager.sessions.Create(id, profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *MemberManagerCtx) Logout(id string) error {
|
2021-08-30 03:09:13 +12:00
|
|
|
manager.loginMu.Lock()
|
|
|
|
defer manager.loginMu.Unlock()
|
2021-03-15 07:59:34 +13:00
|
|
|
|
|
|
|
return manager.sessions.Delete(id)
|
|
|
|
}
|