|
@@ -8,6 +8,7 @@ import (
|
|
"net/http"
|
|
"net/http"
|
|
"time"
|
|
"time"
|
|
|
|
|
|
|
|
+ "github.com/gorilla/sessions"
|
|
uuid "github.com/satori/go.uuid"
|
|
uuid "github.com/satori/go.uuid"
|
|
"imuslab.com/arozos/mod/database"
|
|
"imuslab.com/arozos/mod/database"
|
|
"imuslab.com/arozos/mod/utils"
|
|
"imuslab.com/arozos/mod/utils"
|
|
@@ -35,23 +36,31 @@ type SwitchableAccount struct {
|
|
|
|
|
|
type SwitchableAccountsPool struct {
|
|
type SwitchableAccountsPool struct {
|
|
UUID string //UUID of this pool, one pool per browser instance
|
|
UUID string //UUID of this pool, one pool per browser instance
|
|
|
|
+ Creator string //The user who created the pool. When logout, the pool is discarded
|
|
Accounts []*SwitchableAccount //Accounts that is cross switchable in this pool
|
|
Accounts []*SwitchableAccount //Accounts that is cross switchable in this pool
|
|
parent *SwitchableAccountPoolManager
|
|
parent *SwitchableAccountPoolManager
|
|
}
|
|
}
|
|
|
|
|
|
type SwitchableAccountPoolManager struct {
|
|
type SwitchableAccountPoolManager struct {
|
|
- Database *database.Database
|
|
|
|
- ExpireTime int64 //Expire time of the switchable account
|
|
|
|
- authAgent *AuthAgent
|
|
|
|
|
|
+ SessionStore *sessions.CookieStore
|
|
|
|
+ SessionName string
|
|
|
|
+ Database *database.Database
|
|
|
|
+ ExpireTime int64 //Expire time of the switchable account
|
|
|
|
+ authAgent *AuthAgent
|
|
}
|
|
}
|
|
|
|
|
|
// Create a new switchable account pool manager
|
|
// Create a new switchable account pool manager
|
|
-func NewSwitchableAccountPoolManager(sysdb *database.Database, parent *AuthAgent) *SwitchableAccountPoolManager {
|
|
|
|
|
|
+func NewSwitchableAccountPoolManager(sysdb *database.Database, parent *AuthAgent, key []byte) *SwitchableAccountPoolManager {
|
|
|
|
+ //Create new database table
|
|
sysdb.NewTable("auth_acswitch")
|
|
sysdb.NewTable("auth_acswitch")
|
|
|
|
+
|
|
|
|
+ //Create new session store
|
|
thisManager := SwitchableAccountPoolManager{
|
|
thisManager := SwitchableAccountPoolManager{
|
|
- Database: sysdb,
|
|
|
|
- ExpireTime: 604800,
|
|
|
|
- authAgent: parent,
|
|
|
|
|
|
+ SessionStore: sessions.NewCookieStore(key),
|
|
|
|
+ SessionName: "ao_acc",
|
|
|
|
+ Database: sysdb,
|
|
|
|
+ ExpireTime: 604800,
|
|
|
|
+ authAgent: parent,
|
|
}
|
|
}
|
|
|
|
|
|
//Do an initialization cleanup
|
|
//Do an initialization cleanup
|
|
@@ -85,8 +94,9 @@ func (m *SwitchableAccountPoolManager) HandleSwitchableAccountListing(w http.Res
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
- poolid, err := utils.GetPara(r, "pid")
|
|
|
|
- if err != nil {
|
|
|
|
|
|
+ session, _ := m.SessionStore.Get(r, m.SessionName)
|
|
|
|
+ poolid, ok := session.Values["poolid"].(string)
|
|
|
|
+ if !ok {
|
|
utils.SendErrorResponse(w, "invalid pool id given")
|
|
utils.SendErrorResponse(w, "invalid pool id given")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -94,16 +104,25 @@ func (m *SwitchableAccountPoolManager) HandleSwitchableAccountListing(w http.Res
|
|
//Check pool exists
|
|
//Check pool exists
|
|
targetPool, err := m.GetPoolByID(poolid)
|
|
targetPool, err := m.GetPoolByID(poolid)
|
|
if err != nil {
|
|
if err != nil {
|
|
|
|
+ //Pool expired. Unset the session
|
|
|
|
+ session.Values["poolid"] = nil
|
|
|
|
+ session.Save(r, w)
|
|
utils.SendErrorResponse(w, err.Error())
|
|
utils.SendErrorResponse(w, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
//Check if the user can access this pool
|
|
//Check if the user can access this pool
|
|
if !targetPool.IsAccessibleBy(currentUsername) {
|
|
if !targetPool.IsAccessibleBy(currentUsername) {
|
|
- utils.SendErrorResponse(w, "permission denied")
|
|
|
|
|
|
+ //Unset the session
|
|
|
|
+ session.Values["poolid"] = nil
|
|
|
|
+ session.Save(r, w)
|
|
|
|
+ utils.SendErrorResponse(w, "access denied")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //Update the user Last Switch Time
|
|
|
|
+ targetPool.UpdateUserLastSwitchTime(currentUsername)
|
|
|
|
+
|
|
//OK. List all the information about the pool
|
|
//OK. List all the information about the pool
|
|
type AccountInfo struct {
|
|
type AccountInfo struct {
|
|
Username string
|
|
Username string
|
|
@@ -121,6 +140,43 @@ func (m *SwitchableAccountPoolManager) HandleSwitchableAccountListing(w http.Res
|
|
utils.SendJSONResponse(w, string(js))
|
|
utils.SendJSONResponse(w, string(js))
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Handle logout of the current user, return the fallback user if any
|
|
|
|
+func (m *SwitchableAccountPoolManager) HandleLogoutforUser(w http.ResponseWriter, r *http.Request) (string, error) {
|
|
|
|
+ currentUsername, err := m.authAgent.GetUserName(w, r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return "", err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ session, _ := m.SessionStore.Get(r, m.SessionName)
|
|
|
|
+ poolid, ok := session.Values["poolid"].(string)
|
|
|
|
+ if !ok {
|
|
|
|
+ return "", errors.New("user not in a any switchable account pool")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Get the target pool
|
|
|
|
+ targetpool, err := m.GetPoolByID(poolid)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return "", err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Remove the user from the pool
|
|
|
|
+ targetpool.RemoveUser(currentUsername)
|
|
|
|
+
|
|
|
|
+ //Check if the logout user is the creator. If yes, remove the pool
|
|
|
|
+ if targetpool.Creator == currentUsername {
|
|
|
|
+ targetpool.Delete()
|
|
|
|
+
|
|
|
|
+ //Unset the session
|
|
|
|
+ session.Values["poolid"] = nil
|
|
|
|
+ session.Save(r, w)
|
|
|
|
+
|
|
|
|
+ return "", nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //return the creator so after logout, the client is switched back to the master account
|
|
|
|
+ return targetpool.Creator, nil
|
|
|
|
+}
|
|
|
|
+
|
|
// Logout all the accounts in the pool
|
|
// Logout all the accounts in the pool
|
|
func (m *SwitchableAccountPoolManager) HandleLogoutAllAccounts(w http.ResponseWriter, r *http.Request) {
|
|
func (m *SwitchableAccountPoolManager) HandleLogoutAllAccounts(w http.ResponseWriter, r *http.Request) {
|
|
currentUsername, err := m.authAgent.GetUserName(w, r)
|
|
currentUsername, err := m.authAgent.GetUserName(w, r)
|
|
@@ -128,9 +184,12 @@ func (m *SwitchableAccountPoolManager) HandleLogoutAllAccounts(w http.ResponseWr
|
|
utils.SendErrorResponse(w, err.Error())
|
|
utils.SendErrorResponse(w, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- poolid, err := utils.PostPara(r, "pid")
|
|
|
|
- if err != nil {
|
|
|
|
|
|
+
|
|
|
|
+ session, _ := m.SessionStore.Get(r, m.SessionName)
|
|
|
|
+ poolid, ok := session.Values["poolid"].(string)
|
|
|
|
+ if !ok {
|
|
utils.SendErrorResponse(w, "invalid pool id given")
|
|
utils.SendErrorResponse(w, "invalid pool id given")
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
|
|
//Get the target pool
|
|
//Get the target pool
|
|
@@ -148,6 +207,10 @@ func (m *SwitchableAccountPoolManager) HandleLogoutAllAccounts(w http.ResponseWr
|
|
//Remove the pool
|
|
//Remove the pool
|
|
targetpool.Delete()
|
|
targetpool.Delete()
|
|
|
|
|
|
|
|
+ //Unset the session
|
|
|
|
+ session.Values["poolid"] = nil
|
|
|
|
+ session.Save(r, w)
|
|
|
|
+
|
|
utils.SendOK(w)
|
|
utils.SendOK(w)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -158,12 +221,15 @@ func (m *SwitchableAccountPoolManager) HandleAccountSwitch(w http.ResponseWriter
|
|
utils.SendErrorResponse(w, err.Error())
|
|
utils.SendErrorResponse(w, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- poolid, err := utils.PostPara(r, "pid")
|
|
|
|
- if err != nil {
|
|
|
|
|
|
+
|
|
|
|
+ session, _ := m.SessionStore.Get(r, m.SessionName)
|
|
|
|
+ poolid, ok := session.Values["poolid"].(string)
|
|
|
|
+ if !ok {
|
|
//No pool is given. Generate a pool for this request
|
|
//No pool is given. Generate a pool for this request
|
|
poolid = uuid.NewV4().String()
|
|
poolid = uuid.NewV4().String()
|
|
newPool := SwitchableAccountsPool{
|
|
newPool := SwitchableAccountsPool{
|
|
- UUID: poolid,
|
|
|
|
|
|
+ UUID: poolid,
|
|
|
|
+ Creator: previousUserName,
|
|
Accounts: []*SwitchableAccount{
|
|
Accounts: []*SwitchableAccount{
|
|
{
|
|
{
|
|
Username: previousUserName,
|
|
Username: previousUserName,
|
|
@@ -174,6 +240,13 @@ func (m *SwitchableAccountPoolManager) HandleAccountSwitch(w http.ResponseWriter
|
|
}
|
|
}
|
|
|
|
|
|
newPool.Save()
|
|
newPool.Save()
|
|
|
|
+
|
|
|
|
+ session.Values["poolid"] = poolid
|
|
|
|
+ session.Options = &sessions.Options{
|
|
|
|
+ MaxAge: 3600 * 24 * 30, //One month
|
|
|
|
+ Path: "/",
|
|
|
|
+ }
|
|
|
|
+ session.Save(r, w)
|
|
}
|
|
}
|
|
|
|
|
|
//Get switchable pool from manager
|
|
//Get switchable pool from manager
|