mirror of
https://github.com/weloe/token-go.git
synced 2025-10-05 15:36:50 +08:00
feat: add param device, update LoginByModel
This commit is contained in:
92
enforcer.go
92
enforcer.go
@@ -183,10 +183,13 @@ func (e *Enforcer) IsLogEnable() bool {
|
||||
|
||||
// Login login by id and default loginModel, return tokenValue and error
|
||||
func (e *Enforcer) Login(id string, ctx ctx.Context) (string, error) {
|
||||
return e.LoginByModel(id, model.DefaultLoginModel(), ctx)
|
||||
return e.LoginByModel(id, model.CreateLoginModelByDevice(""), ctx)
|
||||
}
|
||||
|
||||
func (e *Enforcer) LoginById(id string) (string, error) {
|
||||
func (e *Enforcer) LoginById(id string, device ...string) (string, error) {
|
||||
if len(device) > 0 && device[0] != "" {
|
||||
return e.LoginByModel(id, model.CreateLoginModelByDevice(device[0]), nil)
|
||||
}
|
||||
return e.Login(id, nil)
|
||||
}
|
||||
|
||||
@@ -256,38 +259,37 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
|
||||
if session = e.GetSession(id); session != nil {
|
||||
// get by login device
|
||||
tokenSignList := session.GetFilterTokenSign(device)
|
||||
if tokenSignList.Len() <= int(tokenConfig.DeviceMaxLoginCount) {
|
||||
return tokenValue, nil
|
||||
}
|
||||
// if loginCount > maxLoginCount, logout account until single device Login count is equal to DeviceMaxLoginCount
|
||||
for element := tokenSignList.Front(); element != nil; element = element.Next() {
|
||||
if tokenSign, ok := element.Value.(*model.TokenSign); ok {
|
||||
if session.TokenSignSize() > int(tokenConfig.DeviceMaxLoginCount) {
|
||||
// delete tokenSign
|
||||
tokenSignValue := tokenSign.Value
|
||||
session.RemoveTokenSign(tokenSignValue)
|
||||
err = e.UpdateSession(id, session)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// delete token-id
|
||||
err = e.deleteIdByToken(tokenSignValue)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
e.logger.Logout(e.loginType, id, tokenSignValue)
|
||||
if tokenSignList.Len() > int(tokenConfig.DeviceMaxLoginCount) {
|
||||
// if loginCount > maxLoginCount, logout account until single device Login count is equal to DeviceMaxLoginCount
|
||||
for element := tokenSignList.Front(); element != nil; element = element.Next() {
|
||||
if tokenSign, ok := element.Value.(*model.TokenSign); ok {
|
||||
if session.TokenSignSize() > int(tokenConfig.DeviceMaxLoginCount) {
|
||||
// delete tokenSign
|
||||
tokenSignValue := tokenSign.Value
|
||||
session.RemoveTokenSign(tokenSignValue)
|
||||
err = e.UpdateSession(id, session)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// delete token-id
|
||||
err = e.deleteIdByToken(tokenSignValue)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
e.logger.Logout(e.loginType, id, tokenSignValue)
|
||||
|
||||
if e.watcher != nil {
|
||||
e.watcher.Logout(e.loginType, id, tokenSignValue)
|
||||
if e.watcher != nil {
|
||||
e.watcher.Logout(e.loginType, id, tokenSignValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check TokenSignList length, if length == 0, delete this session
|
||||
if session != nil && session.TokenSignSize() == 0 {
|
||||
err = e.DeleteSession(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
// check TokenSignList length, if length == 0, delete this session
|
||||
if session != nil && session.TokenSignSize() == 0 {
|
||||
err = e.DeleteSession(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,13 +360,20 @@ func (e *Enforcer) Logout(ctx ctx.Context) error {
|
||||
}
|
||||
|
||||
// LogoutById force user to logout
|
||||
func (e *Enforcer) LogoutById(id string) error {
|
||||
func (e *Enforcer) LogoutById(id string, device ...string) error {
|
||||
session := e.GetSession(id)
|
||||
if session != nil {
|
||||
for _, tokenSign := range session.TokenSignList {
|
||||
err := e.LogoutByToken(tokenSign.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(device) > 0 && device[0] != "" && tokenSign.Device == device[0] {
|
||||
err := e.LogoutByToken(tokenSign.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err := e.LogoutByToken(tokenSign.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,11 +421,16 @@ func (e *Enforcer) LogoutByToken(token string) error {
|
||||
|
||||
// IsLoginById check if user logged in by loginId.
|
||||
// check all tokenValue and if one is validated return true
|
||||
func (e *Enforcer) IsLoginById(id string) (bool, error) {
|
||||
func (e *Enforcer) IsLoginById(id string, device ...string) (bool, error) {
|
||||
var err error
|
||||
session := e.GetSession(id)
|
||||
if session != nil {
|
||||
l := session.TokenSignList
|
||||
var l []*model.TokenSign
|
||||
if len(device) > 0 && device[0] != "" {
|
||||
l = session.GetFilterTokenSignSlice(device[0])
|
||||
} else {
|
||||
l = session.TokenSignList
|
||||
}
|
||||
for _, tokenSign := range l {
|
||||
err = e.CheckLoginByToken(tokenSign.Value)
|
||||
if err != nil {
|
||||
@@ -500,8 +514,12 @@ func (e *Enforcer) GetLoginIdByToken(token string) (string, error) {
|
||||
return str, nil
|
||||
}
|
||||
|
||||
func (e *Enforcer) GetLoginCount(id string) int {
|
||||
func (e *Enforcer) GetLoginCount(id string, device ...string) int {
|
||||
if session := e.GetSession(id); session != nil {
|
||||
if len(device) > 0 && device[0] != "" {
|
||||
return session.GetFilterTokenSign(device[0]).Len()
|
||||
}
|
||||
|
||||
return session.TokenSignSize()
|
||||
}
|
||||
return 0
|
||||
|
@@ -26,16 +26,16 @@ type IEnforcer interface {
|
||||
|
||||
// Login login api
|
||||
Login(id string, ctx ctx.Context) (string, error)
|
||||
LoginById(id string) (string, error)
|
||||
LoginById(id string, device ...string) (string, error)
|
||||
LoginByModel(id string, loginModel *model.Login, ctx ctx.Context) (string, error)
|
||||
|
||||
Logout(ctx ctx.Context) error
|
||||
LogoutById(id string) error
|
||||
LogoutById(id string, device ...string) error
|
||||
LogoutByToken(token string) error
|
||||
|
||||
IsLogin(ctx ctx.Context) (bool, error)
|
||||
IsLoginByToken(token string) (bool, error)
|
||||
IsLoginById(id string) (bool, error)
|
||||
IsLoginById(id string, device ...string) (bool, error)
|
||||
CheckLogin(ctx ctx.Context) error
|
||||
CheckLoginByToken(token string) error
|
||||
|
||||
@@ -43,7 +43,7 @@ type IEnforcer interface {
|
||||
GetLoginIdByToken(token string) (string, error)
|
||||
GetId(ctx ctx.Context) string
|
||||
GetIdByToken(token string) string
|
||||
GetLoginCount(id string) int
|
||||
GetLoginCount(id string, device ...string) int
|
||||
|
||||
GetLoginCounts() (int, error)
|
||||
GetLoginTokenCounts() (int, error)
|
||||
|
@@ -13,7 +13,7 @@ func (e *Enforcer) Replaced(id string, device ...string) error {
|
||||
var err error
|
||||
if session := e.GetSession(id); session != nil {
|
||||
var tokenSignList *list.List
|
||||
if len(device) == 0 {
|
||||
if len(device) == 0 || device[0] == "" {
|
||||
tokenSignList = session.GetTokenSignListCopy()
|
||||
} else {
|
||||
// get by login device
|
||||
@@ -52,7 +52,7 @@ func (e *Enforcer) Kickout(id string, device ...string) error {
|
||||
session := e.GetSession(id)
|
||||
if session != nil {
|
||||
var tokenSignList *list.List
|
||||
if len(device) == 0 {
|
||||
if len(device) == 0 || device[0] == "" {
|
||||
tokenSignList = session.GetTokenSignListCopy()
|
||||
} else {
|
||||
// get by login device
|
||||
|
@@ -189,6 +189,10 @@ func TestEnforcer_Login(t *testing.T) {
|
||||
if !login {
|
||||
t.Errorf("IsLoginById() failed: IsLoginById() = %v", login)
|
||||
}
|
||||
err = enforcer.Replaced("1")
|
||||
if err != nil {
|
||||
t.Errorf("Replaced() failed: %v", err)
|
||||
}
|
||||
err = enforcer.Replaced("1", loginModel.Device)
|
||||
if err != nil {
|
||||
t.Errorf("Replaced() failed: %v", err)
|
||||
@@ -365,6 +369,46 @@ func TestEnforcer_ConcurrentNotShareMultiLogin(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestEnforcer_ConcurrentNotShareMultiDeviceLogin(t *testing.T) {
|
||||
var err error
|
||||
err, enforcer, _ := NewTestConcurrentEnforcer(t)
|
||||
t.Logf("concurrent: %v, share: %v", enforcer.config.IsConcurrent, enforcer.config.IsShare)
|
||||
if err != nil {
|
||||
t.Errorf("InitWithConfig() failed: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 14; i++ {
|
||||
_, err = enforcer.LoginById("id", fmt.Sprintf("device%v", i))
|
||||
if err != nil {
|
||||
t.Errorf("Login() failed: %v", err)
|
||||
}
|
||||
}
|
||||
session := enforcer.GetSession("id")
|
||||
if session.TokenSignSize() != 12 {
|
||||
t.Errorf("Login() failed: unexpected session.TokenSignList length = %v", session.TokenSignSize())
|
||||
}
|
||||
b, err := enforcer.IsLoginById("id")
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
if b == false {
|
||||
t.Errorf("IsLoginById = %v, want is true", false)
|
||||
}
|
||||
b, err = enforcer.IsLoginById("id", "device0")
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
if b == true {
|
||||
t.Errorf("IsLoginById = %v, want is false", true)
|
||||
}
|
||||
if count := enforcer.GetLoginCount("id"); count != 12 {
|
||||
t.Errorf("Login() failed: unexpected login count = %v", count)
|
||||
}
|
||||
if count := enforcer.GetLoginCount("id", "device1"); count != 0 {
|
||||
t.Errorf("Login() failed: unexpected login count = %v", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDefaultEnforcer(t *testing.T) {
|
||||
err, ctx := NewTestHttpContext(t)
|
||||
if ctx == nil {
|
||||
|
@@ -19,3 +19,14 @@ func DefaultLoginModel() *Login {
|
||||
IsWriteHeader: true,
|
||||
}
|
||||
}
|
||||
|
||||
func CreateLoginModelByDevice(device string) *Login {
|
||||
return &Login{
|
||||
Device: device,
|
||||
IsLastingCookie: true,
|
||||
Timeout: 60 * 60 * 24 * 30,
|
||||
JwtData: nil,
|
||||
Token: "",
|
||||
IsWriteHeader: true,
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,17 @@ func NewSession(id string, sessionType string, loginId string) *Session {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) GetFilterTokenSignSlice(device string) []*TokenSign {
|
||||
l := make([]*TokenSign, 0)
|
||||
|
||||
for _, tokenSign := range s.TokenSignList {
|
||||
if tokenSign.Device == device {
|
||||
l = append(l, tokenSign)
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// GetFilterTokenSign filter by TokenSign.Device from all TokenSign
|
||||
func (s *Session) GetFilterTokenSign(device string) *list.List {
|
||||
copyList := list.New()
|
||||
@@ -111,6 +122,9 @@ func (s *Session) RemoveTokenSignByIndex(i int) {
|
||||
// GetLastTokenByDevice get TokenSign.Value by device
|
||||
func (s *Session) GetLastTokenByDevice(device string) string {
|
||||
tokenSignList := s.GetFilterTokenSign(device)
|
||||
if tokenSignList.Len() == 0 {
|
||||
return ""
|
||||
}
|
||||
if tokenSign, ok := tokenSignList.Back().Value.(*TokenSign); ok {
|
||||
return tokenSign.Value
|
||||
}
|
||||
|
Reference in New Issue
Block a user