蓝眼网盘定制版
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.

512 lines
14 KiB

package rest
8 years ago
import (
"net/http"
"regexp"
"strconv"
"time"
"github.com/eyebluecn/tank/code/core"
"github.com/eyebluecn/tank/code/tool/builder"
"github.com/eyebluecn/tank/code/tool/i18n"
"github.com/eyebluecn/tank/code/tool/result"
"github.com/eyebluecn/tank/code/tool/util"
8 years ago
)
type UserController struct {
BaseController
preferenceService *PreferenceService
userService *UserService
matterService *MatterService
8 years ago
}
func (this *UserController) Init() {
this.BaseController.Init()
b := core.CONTEXT.GetBean(this.preferenceService)
if b, ok := b.(*PreferenceService); ok {
this.preferenceService = b
}
b = core.CONTEXT.GetBean(this.userService)
if b, ok := b.(*UserService); ok {
this.userService = b
}
b = core.CONTEXT.GetBean(this.matterService)
if b, ok := b.(*MatterService); ok {
this.matterService = b
}
8 years ago
}
func (this *UserController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
6 years ago
routeMap["/api/user/info"] = this.Wrap(this.Info, USER_ROLE_GUEST)
routeMap["/api/user/login"] = this.Wrap(this.Login, USER_ROLE_GUEST)
routeMap["/api/user/authentication/login"] = this.Wrap(this.AuthenticationLogin, USER_ROLE_GUEST)
routeMap["/api/user/register"] = this.Wrap(this.Register, USER_ROLE_GUEST)
routeMap["/api/user/create"] = this.Wrap(this.Create, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/edit"] = this.Wrap(this.Edit, USER_ROLE_USER)
routeMap["/api/user/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
routeMap["/api/user/logout"] = this.Wrap(this.Logout, USER_ROLE_GUEST)
8 years ago
routeMap["/api/user/change/password"] = this.Wrap(this.ChangePassword, USER_ROLE_USER)
routeMap["/api/user/reset/password"] = this.Wrap(this.ResetPassword, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/page"] = this.Wrap(this.Page, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/toggle/status"] = this.Wrap(this.ToggleStatus, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/transfiguration"] = this.Wrap(this.Transfiguration, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/scan"] = this.Wrap(this.Scan, USER_ROLE_ADMINISTRATOR)
routeMap["/api/user/delete"] = this.Wrap(this.Delete, USER_ROLE_ADMINISTRATOR)
8 years ago
return routeMap
}
func (this *UserController) innerLogin(writer http.ResponseWriter, request *http.Request, user *User) {
8 years ago
7 years ago
if user.Status == USER_STATUS_DISABLED {
panic(result.BadRequestI18n(request, i18n.UserDisabled))
}
handleSessionAndCookie(writer, request, this.sessionDao, user)
8 years ago
//update lastTime and lastIp
//by han: 去掉用户表相关操作
// user.LastTime = time.Now()
// user.LastIp = util.GetIpAddress(request)
// this.userDao.Save(user)
}
// login by username and password
func (this *UserController) Login(writer http.ResponseWriter, request *http.Request) *result.WebResult {
//get from http header
// username := request.Header.Get("user-key")
// password := request.Header.Get("user-token")
uid := request.Header.Get("user-id")
if uid == "" {
uid = "test-user-id"
}
//should redirect to original domain
// if "" == username || "" == password {
// panic(result.BadRequestI18n(request, i18n.UsernameOrPasswordCannotNull))
// }
//by han:todo, 是否需要修改用户表,比如把用户注册到盘这边,最好取消云盘的用户系统依赖
// user := this.userDao.FindByUsername(username)
// if user == nil {
// panic(result.BadRequestI18n(request, i18n.UsernameOrPasswordError))
// }
user := &User{Base: Base{Uuid: uid}, Username: uid}
// if !util.MatchBcrypt(password, user.Password) {
// panic(result.BadRequestI18n(request, i18n.UsernameOrPasswordError))
// }
this.innerLogin(writer, request, user)
return this.Success(user)
}
// login by authentication.
func (this *UserController) AuthenticationLogin(writer http.ResponseWriter, request *http.Request) *result.WebResult {
authentication := request.FormValue("authentication")
if authentication == "" {
panic(result.BadRequest("authentication cannot be null"))
}
session := this.sessionDao.FindByUuid(authentication)
if session == nil {
panic(result.BadRequest("authentication error"))
}
duration := session.ExpireTime.Sub(time.Now())
if duration <= 0 {
panic(result.BadRequest("login info has expired"))
}
user := this.userDao.CheckByUuid(session.UserUuid)
this.innerLogin(writer, request, user)
8 years ago
return this.Success(user)
}
// fetch current user's info.
6 years ago
func (this *UserController) Info(writer http.ResponseWriter, request *http.Request) *result.WebResult {
user := this.checkUser(request)
return this.Success(user)
}
// register by username and password. After registering, will auto login.
func (this *UserController) Register(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
username := request.FormValue("username")
password := request.FormValue("password")
preference := this.preferenceService.Fetch()
if !preference.AllowRegister {
panic(result.BadRequestI18n(request, i18n.UserRegisterNotAllowd))
}
if m, _ := regexp.MatchString(USERNAME_PATTERN, username); !m {
panic(result.BadRequestI18n(request, i18n.UsernameError))
8 years ago
}
8 years ago
if len(password) < 6 {
panic(result.BadRequestI18n(request, i18n.UserPasswordLengthError))
8 years ago
}
if this.userDao.CountByUsername(username) > 0 {
panic(result.BadRequestI18n(request, i18n.UsernameExist, username))
8 years ago
}
user := &User{
6 years ago
Role: USER_ROLE_USER,
Username: username,
Password: util.GetBcrypt(password),
TotalSizeLimit: preference.DefaultTotalSizeLimit,
6 years ago
Status: USER_STATUS_OK,
8 years ago
}
user = this.userDao.Create(user)
//auto login
this.innerLogin(writer, request, user)
8 years ago
return this.Success(user)
}
func (this *UserController) Create(writer http.ResponseWriter, request *http.Request) *result.WebResult {
username := request.FormValue("username")
password := request.FormValue("password")
role := request.FormValue("role")
sizeLimitStr := request.FormValue("sizeLimit")
totalSizeLimitStr := request.FormValue("totalSizeLimit")
//only admin can edit user's sizeLimit
var sizeLimit int64 = 0
if sizeLimitStr == "" {
panic("user's limit size is required")
} else {
intSizeLimit, err := strconv.Atoi(sizeLimitStr)
if err != nil {
this.PanicError(err)
}
sizeLimit = int64(intSizeLimit)
}
var totalSizeLimit int64 = 0
if totalSizeLimitStr == "" {
panic("user's total limit size is required")
} else {
intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr)
if err != nil {
this.PanicError(err)
}
totalSizeLimit = int64(intTotalSizeLimit)
}
if m, _ := regexp.MatchString(USERNAME_PATTERN, username); !m {
panic(result.BadRequestI18n(request, i18n.UsernameError))
}
if len(password) < 6 {
panic(result.BadRequestI18n(request, i18n.UserPasswordLengthError))
}
if this.userDao.CountByUsername(username) > 0 {
panic(result.BadRequestI18n(request, i18n.UsernameExist, username))
}
if role != USER_ROLE_USER && role != USER_ROLE_ADMINISTRATOR {
role = USER_ROLE_USER
}
user := &User{
Username: username,
Password: util.GetBcrypt(password),
Role: role,
SizeLimit: sizeLimit,
TotalSizeLimit: totalSizeLimit,
Status: USER_STATUS_OK,
}
user = this.userDao.Create(user)
return this.Success(user)
}
func (this *UserController) Edit(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
uuid := request.FormValue("uuid")
7 years ago
avatarUrl := request.FormValue("avatarUrl")
sizeLimitStr := request.FormValue("sizeLimit")
7 years ago
totalSizeLimitStr := request.FormValue("totalSizeLimit")
role := request.FormValue("role")
8 years ago
user := this.checkUser(request)
currentUser := this.userDao.CheckByUuid(uuid)
7 years ago
currentUser.AvatarUrl = avatarUrl
if user.Role == USER_ROLE_ADMINISTRATOR {
//only admin can edit user's sizeLimit
var sizeLimit int64 = 0
if sizeLimitStr == "" {
panic("user's limit size is required")
} else {
intSizeLimit, err := strconv.Atoi(sizeLimitStr)
if err != nil {
this.PanicError(err)
}
sizeLimit = int64(intSizeLimit)
8 years ago
}
currentUser.SizeLimit = sizeLimit
7 years ago
var totalSizeLimit int64 = 0
if totalSizeLimitStr == "" {
panic("user's total limit size is required")
} else {
intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr)
if err != nil {
this.PanicError(err)
}
totalSizeLimit = int64(intTotalSizeLimit)
}
currentUser.TotalSizeLimit = totalSizeLimit
if role == USER_ROLE_USER || role == USER_ROLE_ADMINISTRATOR {
currentUser.Role = role
}
} else if user.Uuid != uuid {
panic(result.UNAUTHORIZED)
8 years ago
}
currentUser = this.userDao.Save(currentUser)
8 years ago
//remove cache user.
this.userService.RemoveCacheUserByUuid(currentUser.Uuid)
return this.Success(currentUser)
8 years ago
}
func (this *UserController) Detail(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
uuid := request.FormValue("uuid")
user := this.userDao.CheckByUuid(uuid)
return this.Success(user)
}
func (this *UserController) Logout(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
//try to find from SessionCache.
sessionId := util.GetSessionUuidFromRequest(request, core.COOKIE_AUTH_KEY)
if sessionId == "" {
return nil
}
8 years ago
user := this.findUser(request)
if user != nil {
session := this.sessionDao.FindByUuid(sessionId)
session.ExpireTime = time.Now()
this.sessionDao.Save(session)
}
//delete session.
_, err := core.CONTEXT.GetSessionCache().Delete(sessionId)
if err != nil {
this.logger.Error("error while deleting session.")
}
8 years ago
//clear cookie.
8 years ago
expiration := time.Now()
expiration = expiration.AddDate(-1, 0, 0)
cookie := http.Cookie{
Name: core.COOKIE_AUTH_KEY,
8 years ago
Path: "/",
Value: sessionId,
8 years ago
Expires: expiration}
http.SetCookie(writer, &cookie)
return this.Success("OK")
8 years ago
}
func (this *UserController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
pageStr := request.FormValue("page")
pageSizeStr := request.FormValue("pageSize")
orderCreateTime := request.FormValue("orderCreateTime")
orderUpdateTime := request.FormValue("orderUpdateTime")
orderSort := request.FormValue("orderSort")
8 years ago
username := request.FormValue("username")
status := request.FormValue("status")
8 years ago
orderLastTime := request.FormValue("orderLastTime")
var page int
if pageStr != "" {
page, _ = strconv.Atoi(pageStr)
}
pageSize := 200
if pageSizeStr != "" {
tmp, err := strconv.Atoi(pageSizeStr)
if err == nil {
pageSize = tmp
}
}
sortArray := []builder.OrderPair{
8 years ago
{
Key: "create_time",
Value: orderCreateTime,
8 years ago
},
{
Key: "update_time",
Value: orderUpdateTime,
},
{
Key: "sort",
Value: orderSort,
},
{
Key: "last_time",
Value: orderLastTime,
},
8 years ago
}
pager := this.userDao.Page(page, pageSize, username, status, sortArray)
8 years ago
return this.Success(pager)
}
func (this *UserController) ToggleStatus(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
uuid := request.FormValue("uuid")
currentUser := this.userDao.CheckByUuid(uuid)
user := this.checkUser(request)
if uuid == user.Uuid {
panic(result.BadRequest("You cannot disable yourself."))
}
8 years ago
if currentUser.Status == USER_STATUS_OK {
currentUser.Status = USER_STATUS_DISABLED
} else if currentUser.Status == USER_STATUS_DISABLED {
currentUser.Status = USER_STATUS_OK
8 years ago
}
currentUser = this.userDao.Save(currentUser)
8 years ago
//remove cache user.
this.userService.RemoveCacheUserByUuid(currentUser.Uuid)
return this.Success(currentUser)
8 years ago
}
func (this *UserController) Transfiguration(writer http.ResponseWriter, request *http.Request) *result.WebResult {
uuid := request.FormValue("uuid")
currentUser := this.userDao.CheckByUuid(uuid)
//expire after 10 minutes.
expiration := time.Now()
expiration = expiration.Add(10 * time.Minute)
session := &Session{
UserUuid: currentUser.Uuid,
Ip: util.GetIpAddress(request),
ExpireTime: expiration,
}
session.UpdateTime = time.Now()
session.CreateTime = time.Now()
session = this.sessionDao.Create(session)
return this.Success(session.Uuid)
}
// scan user's physics files. create index into EyeblueTank
func (this *UserController) Scan(writer http.ResponseWriter, request *http.Request) *result.WebResult {
uuid := request.FormValue("uuid")
currentUser := this.userDao.CheckByUuid(uuid)
this.matterService.DeleteByPhysics(request, currentUser)
this.matterService.ScanPhysics(request, currentUser)
return this.Success("OK")
}
func (this *UserController) Delete(writer http.ResponseWriter, request *http.Request) *result.WebResult {
uuid := request.FormValue("uuid")
currentUser := this.userDao.CheckByUuid(uuid)
user := this.checkUser(request)
if currentUser.Status != USER_STATUS_DISABLED {
panic(result.BadRequest("Only disabled user can be deleted."))
}
if currentUser.Uuid == user.Uuid {
panic(result.BadRequest("You cannot delete yourself."))
}
this.userService.DeleteUser(request, currentUser)
return this.Success("OK")
}
func (this *UserController) ChangePassword(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
oldPassword := request.FormValue("oldPassword")
newPassword := request.FormValue("newPassword")
if oldPassword == "" || newPassword == "" {
panic(result.BadRequest("oldPassword and newPassword cannot be null"))
8 years ago
}
user := this.checkUser(request)
8 years ago
//if username is demo, cannot change password.
if user.Username == USERNAME_DEMO {
return this.Success(user)
}
if !util.MatchBcrypt(oldPassword, user.Password) {
panic(result.BadRequestI18n(request, i18n.UserOldPasswordError))
8 years ago
}
user.Password = util.GetBcrypt(newPassword)
8 years ago
user = this.userDao.Save(user)
return this.Success(user)
}
// admin reset password.
func (this *UserController) ResetPassword(writer http.ResponseWriter, request *http.Request) *result.WebResult {
8 years ago
userUuid := request.FormValue("userUuid")
password := request.FormValue("password")
if userUuid == "" {
panic(result.BadRequest("userUuid cannot be null"))
8 years ago
}
if password == "" {
panic(result.BadRequest("password cannot be null"))
8 years ago
}
currentUser := this.checkUser(request)
8 years ago
if currentUser.Role != USER_ROLE_ADMINISTRATOR {
panic(result.UNAUTHORIZED)
8 years ago
}
user := this.userDao.CheckByUuid(userUuid)
user.Password = util.GetBcrypt(password)
8 years ago
user = this.userDao.Save(user)
return this.Success(currentUser)
}