You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.3 KiB

package user
import (
"database/sql"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/imdotdev/im.dev/server/pkg/common"
"github.com/imdotdev/im.dev/server/pkg/config"
"github.com/imdotdev/im.dev/server/pkg/db"
"github.com/imdotdev/im.dev/server/pkg/log"
"github.com/imdotdev/im.dev/server/pkg/models"
)
var logger = log.RootLogger.New("logger", "session")
type Session struct {
Token string `json:"token"`
User *models.User `json:"user"`
CreateTime time.Time `json:"createTime"`
}
func Login(c *gin.Context) {
user := &models.User{}
err := user.Query("", config.Data.User.SuperAdminUsername, "")
if err != nil {
if err == sql.ErrNoRows {
c.String(http.StatusNotFound, "")
return
}
logger.Error("login error", "error", err)
c.JSON(http.StatusInternalServerError, common.RespInternalError())
return
}
// delete old session
token := getToken(c)
deleteSession(token)
token = strconv.FormatInt(time.Now().UnixNano(), 10)
session := &Session{
Token: token,
User: user,
CreateTime: time.Now(),
}
err = storeSession(session)
if err != nil {
c.JSON(500, common.RespInternalError())
return
}
_, err = db.Conn.Exec(`UPDATE user SET last_seen_at=? WHERE id=?`, time.Now(), user.ID)
if err != nil {
logger.Warn("set last login date error", "error", err)
}
c.JSON(http.StatusOK, common.RespSuccess(session))
}
// Logout ...
func Logout(c *gin.Context) {
token := getToken(c)
// 删除用户的session
deleteSession(token)
c.JSON(http.StatusOK, common.RespSuccess(nil))
}
func getToken(c *gin.Context) string {
return c.Request.Header.Get("X-Token")
}
func deleteSession(sid string) {
q := `DELETE FROM sessions WHERE sid=?`
_, err := db.Conn.Exec(q, sid)
if err != nil {
logger.Info("delete session error", "error", err)
}
}
func storeSession(s *Session) error {
q := `insert into sessions (user_id,sid) VALUES (?,?)`
_, err := db.Conn.Exec(q, s.User.ID, s.Token)
if err != nil {
logger.Warn("store session error", "error", err)
return err
}
return nil
}
func CurrentUser(c *gin.Context) *models.User {
token := getToken(c)
createTime, _ := strconv.ParseInt(token, 10, 64)
if createTime != 0 {
// check whether token is expired
if (time.Now().Unix() - createTime/1e9) > config.Data.User.SessionExpire {
deleteSession(token)
return nil
}
}
sess := loadSession(token)
if sess == nil {
// 用户未登陆或者session失效
return nil
}
return sess.User
}
func GetSession(c *gin.Context) *Session {
token := getToken(c)
createTime, _ := strconv.ParseInt(token, 10, 64)
if createTime != 0 {
// check whether token is expired
if (time.Now().Unix() - createTime/1e9) > config.Data.User.SessionExpire {
deleteSession(token)
return nil
}
}
sess := loadSession(token)
if sess == nil {
// 用户未登陆或者session失效
return nil
}
return sess
}
func loadSession(sid string) *Session {
var userid string
q := `SELECT user_id FROM sessions WHERE sid=?`
err := db.Conn.QueryRow(q, sid).Scan(&userid)
if err != nil {
if err != sql.ErrNoRows {
logger.Warn("query session error", "error", err)
}
return nil
}
user := &models.User{}
err = user.Query(userid, "", "")
if err != nil {
logger.Warn("query user error", "error", err)
return nil
}
return &Session{
Token: sid,
User: user,
}
}