mirror of
https://github.com/weloe/token-go.git
synced 2025-10-13 03:03:41 +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
|
// Login login by id and default loginModel, return tokenValue and error
|
||||||
func (e *Enforcer) Login(id string, ctx ctx.Context) (string, 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)
|
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 {
|
if session = e.GetSession(id); session != nil {
|
||||||
// get by login device
|
// get by login device
|
||||||
tokenSignList := session.GetFilterTokenSign(device)
|
tokenSignList := session.GetFilterTokenSign(device)
|
||||||
if tokenSignList.Len() <= int(tokenConfig.DeviceMaxLoginCount) {
|
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 loginCount > maxLoginCount, logout account until single device Login count is equal to DeviceMaxLoginCount
|
if tokenSign, ok := element.Value.(*model.TokenSign); ok {
|
||||||
for element := tokenSignList.Front(); element != nil; element = element.Next() {
|
if session.TokenSignSize() > int(tokenConfig.DeviceMaxLoginCount) {
|
||||||
if tokenSign, ok := element.Value.(*model.TokenSign); ok {
|
// delete tokenSign
|
||||||
if session.TokenSignSize() > int(tokenConfig.DeviceMaxLoginCount) {
|
tokenSignValue := tokenSign.Value
|
||||||
// delete tokenSign
|
session.RemoveTokenSign(tokenSignValue)
|
||||||
tokenSignValue := tokenSign.Value
|
err = e.UpdateSession(id, session)
|
||||||
session.RemoveTokenSign(tokenSignValue)
|
if err != nil {
|
||||||
err = e.UpdateSession(id, session)
|
return "", err
|
||||||
if err != nil {
|
}
|
||||||
return "", err
|
// delete token-id
|
||||||
}
|
err = e.deleteIdByToken(tokenSignValue)
|
||||||
// delete token-id
|
if err != nil {
|
||||||
err = e.deleteIdByToken(tokenSignValue)
|
return "", err
|
||||||
if err != nil {
|
}
|
||||||
return "", err
|
e.logger.Logout(e.loginType, id, tokenSignValue)
|
||||||
}
|
|
||||||
e.logger.Logout(e.loginType, id, tokenSignValue)
|
|
||||||
|
|
||||||
if e.watcher != nil {
|
if e.watcher != nil {
|
||||||
e.watcher.Logout(e.loginType, id, tokenSignValue)
|
e.watcher.Logout(e.loginType, id, tokenSignValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// check TokenSignList length, if length == 0, delete this session
|
||||||
// check TokenSignList length, if length == 0, delete this session
|
if session != nil && session.TokenSignSize() == 0 {
|
||||||
if session != nil && session.TokenSignSize() == 0 {
|
err = e.DeleteSession(id)
|
||||||
err = e.DeleteSession(id)
|
if err != nil {
|
||||||
if err != nil {
|
return "", err
|
||||||
return "", err
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,13 +360,20 @@ func (e *Enforcer) Logout(ctx ctx.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LogoutById force user to logout
|
// 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)
|
session := e.GetSession(id)
|
||||||
if session != nil {
|
if session != nil {
|
||||||
for _, tokenSign := range session.TokenSignList {
|
for _, tokenSign := range session.TokenSignList {
|
||||||
err := e.LogoutByToken(tokenSign.Value)
|
if len(device) > 0 && device[0] != "" && tokenSign.Device == device[0] {
|
||||||
if err != nil {
|
err := e.LogoutByToken(tokenSign.Value)
|
||||||
return err
|
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.
|
// IsLoginById check if user logged in by loginId.
|
||||||
// check all tokenValue and if one is validated return true
|
// 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
|
var err error
|
||||||
session := e.GetSession(id)
|
session := e.GetSession(id)
|
||||||
if session != nil {
|
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 {
|
for _, tokenSign := range l {
|
||||||
err = e.CheckLoginByToken(tokenSign.Value)
|
err = e.CheckLoginByToken(tokenSign.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -500,8 +514,12 @@ func (e *Enforcer) GetLoginIdByToken(token string) (string, error) {
|
|||||||
return str, nil
|
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 session := e.GetSession(id); session != nil {
|
||||||
|
if len(device) > 0 && device[0] != "" {
|
||||||
|
return session.GetFilterTokenSign(device[0]).Len()
|
||||||
|
}
|
||||||
|
|
||||||
return session.TokenSignSize()
|
return session.TokenSignSize()
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
@@ -26,16 +26,16 @@ type IEnforcer interface {
|
|||||||
|
|
||||||
// Login login api
|
// Login login api
|
||||||
Login(id string, ctx ctx.Context) (string, error)
|
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)
|
LoginByModel(id string, loginModel *model.Login, ctx ctx.Context) (string, error)
|
||||||
|
|
||||||
Logout(ctx ctx.Context) error
|
Logout(ctx ctx.Context) error
|
||||||
LogoutById(id string) error
|
LogoutById(id string, device ...string) error
|
||||||
LogoutByToken(token string) error
|
LogoutByToken(token string) error
|
||||||
|
|
||||||
IsLogin(ctx ctx.Context) (bool, error)
|
IsLogin(ctx ctx.Context) (bool, error)
|
||||||
IsLoginByToken(token string) (bool, error)
|
IsLoginByToken(token string) (bool, error)
|
||||||
IsLoginById(id string) (bool, error)
|
IsLoginById(id string, device ...string) (bool, error)
|
||||||
CheckLogin(ctx ctx.Context) error
|
CheckLogin(ctx ctx.Context) error
|
||||||
CheckLoginByToken(token string) error
|
CheckLoginByToken(token string) error
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ type IEnforcer interface {
|
|||||||
GetLoginIdByToken(token string) (string, error)
|
GetLoginIdByToken(token string) (string, error)
|
||||||
GetId(ctx ctx.Context) string
|
GetId(ctx ctx.Context) string
|
||||||
GetIdByToken(token string) string
|
GetIdByToken(token string) string
|
||||||
GetLoginCount(id string) int
|
GetLoginCount(id string, device ...string) int
|
||||||
|
|
||||||
GetLoginCounts() (int, error)
|
GetLoginCounts() (int, error)
|
||||||
GetLoginTokenCounts() (int, error)
|
GetLoginTokenCounts() (int, error)
|
||||||
|
@@ -13,7 +13,7 @@ func (e *Enforcer) Replaced(id string, device ...string) error {
|
|||||||
var err error
|
var err error
|
||||||
if session := e.GetSession(id); session != nil {
|
if session := e.GetSession(id); session != nil {
|
||||||
var tokenSignList *list.List
|
var tokenSignList *list.List
|
||||||
if len(device) == 0 {
|
if len(device) == 0 || device[0] == "" {
|
||||||
tokenSignList = session.GetTokenSignListCopy()
|
tokenSignList = session.GetTokenSignListCopy()
|
||||||
} else {
|
} else {
|
||||||
// get by login device
|
// get by login device
|
||||||
@@ -52,7 +52,7 @@ func (e *Enforcer) Kickout(id string, device ...string) error {
|
|||||||
session := e.GetSession(id)
|
session := e.GetSession(id)
|
||||||
if session != nil {
|
if session != nil {
|
||||||
var tokenSignList *list.List
|
var tokenSignList *list.List
|
||||||
if len(device) == 0 {
|
if len(device) == 0 || device[0] == "" {
|
||||||
tokenSignList = session.GetTokenSignListCopy()
|
tokenSignList = session.GetTokenSignListCopy()
|
||||||
} else {
|
} else {
|
||||||
// get by login device
|
// get by login device
|
||||||
|
@@ -189,6 +189,10 @@ func TestEnforcer_Login(t *testing.T) {
|
|||||||
if !login {
|
if !login {
|
||||||
t.Errorf("IsLoginById() failed: IsLoginById() = %v", 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)
|
err = enforcer.Replaced("1", loginModel.Device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Replaced() failed: %v", err)
|
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) {
|
func TestNewDefaultEnforcer(t *testing.T) {
|
||||||
err, ctx := NewTestHttpContext(t)
|
err, ctx := NewTestHttpContext(t)
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
|
@@ -19,3 +19,14 @@ func DefaultLoginModel() *Login {
|
|||||||
IsWriteHeader: true,
|
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
|
// GetFilterTokenSign filter by TokenSign.Device from all TokenSign
|
||||||
func (s *Session) GetFilterTokenSign(device string) *list.List {
|
func (s *Session) GetFilterTokenSign(device string) *list.List {
|
||||||
copyList := list.New()
|
copyList := list.New()
|
||||||
@@ -111,6 +122,9 @@ func (s *Session) RemoveTokenSignByIndex(i int) {
|
|||||||
// GetLastTokenByDevice get TokenSign.Value by device
|
// GetLastTokenByDevice get TokenSign.Value by device
|
||||||
func (s *Session) GetLastTokenByDevice(device string) string {
|
func (s *Session) GetLastTokenByDevice(device string) string {
|
||||||
tokenSignList := s.GetFilterTokenSign(device)
|
tokenSignList := s.GetFilterTokenSign(device)
|
||||||
|
if tokenSignList.Len() == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
if tokenSign, ok := tokenSignList.Back().Value.(*TokenSign); ok {
|
if tokenSign, ok := tokenSignList.Back().Value.(*TokenSign); ok {
|
||||||
return tokenSign.Value
|
return tokenSign.Value
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user