2017-06-28 13:42:38 +02:00
package controllers
import (
"fmt"
"net/http"
"strconv"
"time"
2017-06-29 13:15:23 +02:00
"github.com/NyaaPantsu/nyaa/models"
"github.com/NyaaPantsu/nyaa/models/notifications"
2017-07-02 23:53:23 +02:00
"github.com/NyaaPantsu/nyaa/models/users"
2017-07-02 16:54:55 +02:00
"github.com/NyaaPantsu/nyaa/utils/captcha"
"github.com/NyaaPantsu/nyaa/utils/cookies"
"github.com/NyaaPantsu/nyaa/utils/crypto"
2017-07-02 23:53:23 +02:00
"github.com/NyaaPantsu/nyaa/utils/email"
2017-07-02 16:54:55 +02:00
msg "github.com/NyaaPantsu/nyaa/utils/messages"
"github.com/NyaaPantsu/nyaa/utils/publicSettings"
"github.com/NyaaPantsu/nyaa/utils/search"
2017-07-02 23:53:23 +02:00
"github.com/NyaaPantsu/nyaa/utils/validator"
"github.com/NyaaPantsu/nyaa/utils/validator/user"
2017-06-28 13:42:38 +02:00
"github.com/gin-gonic/gin"
)
// UserRegisterFormHandler : Getting View User Registration
func UserRegisterFormHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
_ , _ , errorUser := cookies . CurrentUser ( c )
2017-06-28 13:42:38 +02:00
// User is already connected, redirect to home
if errorUser == nil {
SearchHandler ( c )
return
}
2017-07-02 23:53:23 +02:00
registrationForm := userValidator . RegistrationForm { }
2017-06-28 13:42:38 +02:00
c . Bind ( & registrationForm )
registrationForm . CaptchaID = captcha . GetID ( )
formTemplate ( c , "site/user/register.jet.html" , registrationForm )
}
// UserLoginFormHandler : Getting View User Login
func UserLoginFormHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
_ , _ , errorUser := cookies . CurrentUser ( c )
2017-06-28 13:42:38 +02:00
// User is already connected, redirect to home
if errorUser == nil {
SearchHandler ( c )
return
}
2017-07-04 02:48:20 +02:00
loginForm := userValidator . LoginForm {
RedirectTo : c . DefaultQuery ( "redirectTo" , "" ) ,
}
2017-06-28 13:42:38 +02:00
formTemplate ( c , "site/user/login.jet.html" , loginForm )
}
// UserProfileHandler : Getting User Profile
func UserProfileHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
id , _ := strconv . ParseUint ( c . Param ( "id" ) , 10 , 32 )
2017-06-28 13:42:38 +02:00
fmt . Printf ( "User ID: %s" , id )
Ts , _ := publicSettings . GetTfuncAndLanguageFromRequest ( c )
messages := msg . GetMessages ( c )
2017-07-02 23:53:23 +02:00
userProfile , _ , errorUser := users . FindForAdmin ( uint ( id ) )
2017-06-28 13:42:38 +02:00
if errorUser == nil {
currentUser := getUser ( c )
follow := c . Request . URL . Query ( ) [ "followed" ]
unfollow := c . Request . URL . Query ( ) [ "unfollowed" ]
deleteVar := c . Request . URL . Query ( ) [ "delete" ]
2017-07-02 23:53:23 +02:00
if ( deleteVar != nil ) && ( currentUser . CurrentOrAdmin ( userProfile . ID ) ) {
_ , err := userProfile . Delete ( currentUser )
if err == nil && currentUser . CurrentUserIdentical ( userProfile . ID ) {
cookies . Clear ( c )
}
2017-07-04 03:02:19 +02:00
staticTemplate ( c , "site/static/delete_success.jet.html" )
2017-06-28 13:42:38 +02:00
} else {
if follow != nil {
messages . AddInfof ( "infos" , Ts ( "user_followed_msg" ) , userProfile . Username )
}
if unfollow != nil {
messages . AddInfof ( "infos" , Ts ( "user_unfollowed_msg" ) , userProfile . Username )
}
userProfile . ParseSettings ( )
query := c . Request . URL . Query ( )
2017-07-02 23:53:23 +02:00
query . Set ( "userID" , strconv . Itoa ( int ( id ) ) )
2017-06-28 13:42:38 +02:00
query . Set ( "max" , "16" )
c . Request . URL . RawQuery = query . Encode ( )
2017-07-01 23:09:35 +02:00
var torrents [ ] models . Torrent
2017-06-28 13:42:38 +02:00
var err error
2017-07-02 23:53:23 +02:00
if currentUser . CurrentOrAdmin ( userProfile . ID ) {
2017-07-05 13:33:12 +02:00
_ , torrents , _ , err = search . ByQuery ( c , 1 )
2017-06-28 13:42:38 +02:00
} else {
2017-07-05 13:33:12 +02:00
_ , torrents , _ , err = search . ByQueryNoHidden ( c , 1 )
2017-06-28 13:42:38 +02:00
}
if err != nil {
messages . AddErrorT ( "errors" , "retrieve_torrents_error" )
}
userProfile . Torrents = torrents
2017-07-02 23:53:23 +02:00
userProfileTemplate ( c , userProfile )
2017-06-28 13:42:38 +02:00
}
} else {
NotFoundHandler ( c )
}
}
// UserDetailsHandler : Getting User Profile Details View
func UserDetailsHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
id , _ := strconv . ParseUint ( c . Param ( "id" ) , 10 , 32 )
2017-06-28 13:42:38 +02:00
currentUser := getUser ( c )
2017-07-02 23:53:23 +02:00
userProfile , _ , errorUser := users . FindForAdmin ( uint ( id ) )
if errorUser == nil && currentUser . CurrentOrAdmin ( userProfile . ID ) {
b := userValidator . UserForm { }
c . Bind ( & b )
availableLanguages := publicSettings . GetAvailableLanguages ( )
userProfile . ParseSettings ( )
userProfileEditTemplate ( c , userProfile , b , availableLanguages )
2017-06-28 13:42:38 +02:00
} else {
NotFoundHandler ( c )
}
}
// UserProfileFormHandler : Getting View User Profile Update
func UserProfileFormHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
id , _ := strconv . ParseUint ( c . Param ( "id" ) , 10 , 32 )
2017-06-28 13:42:38 +02:00
currentUser := getUser ( c )
2017-07-02 23:53:23 +02:00
userProfile , _ , errorUser := users . FindForAdmin ( uint ( id ) )
if errorUser != nil || ! currentUser . CurrentOrAdmin ( userProfile . ID ) || userProfile . ID == 0 {
2017-06-28 13:42:38 +02:00
NotFoundHandler ( c )
return
}
userProfile . ParseSettings ( )
messages := msg . GetMessages ( c )
2017-07-02 23:53:23 +02:00
userForm := userValidator . UserForm { }
userSettingsForm := userValidator . UserSettingsForm { }
2017-06-28 13:42:38 +02:00
if len ( c . PostForm ( "email" ) ) > 0 {
2017-07-03 02:16:39 +02:00
if ! userValidator . EmailValidation ( c . PostForm ( "email" ) ) {
messages . AddErrorT ( "email" , "email_not_valid" )
2017-07-02 23:53:23 +02:00
}
2017-06-28 13:42:38 +02:00
}
if len ( c . PostForm ( "username" ) ) > 0 {
2017-07-03 02:16:39 +02:00
if ! userValidator . ValidateUsername ( c . PostForm ( "username" ) ) {
messages . AddErrorT ( "username" , "username_illegal" )
}
2017-06-28 13:42:38 +02:00
}
if ! messages . HasErrors ( ) {
c . Bind ( & userForm )
c . Bind ( & userSettingsForm )
2017-07-02 23:53:23 +02:00
if ! currentUser . HasAdmin ( ) {
2017-06-28 13:42:38 +02:00
userForm . Username = userProfile . Username
userForm . Status = userProfile . Status
} else {
if userProfile . Status != userForm . Status && userForm . Status == 2 {
messages . AddErrorT ( "errors" , "elevating_user_error" )
}
}
2017-07-02 23:53:23 +02:00
validator . ValidateForm ( & userForm , messages )
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
if userForm . Email != userProfile . Email {
2017-07-02 23:53:23 +02:00
email . SendVerificationToUser ( currentUser , userForm . Email )
2017-06-28 13:42:38 +02:00
messages . AddInfoTf ( "infos" , "email_changed" , userForm . Email )
userForm . Email = userProfile . Email // reset, it will be set when user clicks verification
}
2017-07-02 23:53:23 +02:00
user , _ , err := users . UpdateFromRequest ( c , & userForm , & userSettingsForm , currentUser , uint ( id ) )
if err != nil {
messages . Error ( err )
}
if userForm . Email != user . Email {
// send verification to new email and keep old
email . SendVerificationToUser ( user , userForm . Email )
}
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
messages . AddInfoT ( "infos" , "profile_updated" )
}
}
}
availableLanguages := publicSettings . GetAvailableLanguages ( )
2017-07-02 23:53:23 +02:00
userProfileEditTemplate ( c , userProfile , userForm , availableLanguages )
2017-06-28 13:42:38 +02:00
}
// UserRegisterPostHandler : Post Registration controller, we do some check on the form here, the rest on user service
func UserRegisterPostHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
b := userValidator . RegistrationForm { }
2017-06-28 13:42:38 +02:00
messages := msg . GetMessages ( c )
if ! captcha . Authenticate ( captcha . Extract ( c ) ) {
messages . AddErrorT ( "errors" , "bad_captcha" )
}
if ! messages . HasErrors ( ) {
if len ( c . PostForm ( "email" ) ) > 0 {
2017-07-02 23:53:23 +02:00
if ! userValidator . EmailValidation ( c . PostForm ( "email" ) ) {
messages . AddErrorT ( "email" , "email_not_valid" )
}
}
if ! userValidator . ValidateUsername ( c . PostForm ( "username" ) ) {
messages . AddErrorT ( "username" , "username_illegal" )
2017-06-28 13:42:38 +02:00
}
2017-07-02 23:53:23 +02:00
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
c . Bind ( & b )
2017-07-02 23:53:23 +02:00
validator . ValidateForm ( & b , messages )
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
2017-07-02 23:53:23 +02:00
user , _ := users . CreateUser ( c )
_ , err := cookies . SetLogin ( c , user )
if err != nil {
messages . Error ( err )
}
if b . Email != "" {
email . SendVerificationToUser ( user , b . Email )
}
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
staticTemplate ( c , "site/static/signup_success.jet.html" )
}
}
}
}
if messages . HasErrors ( ) {
UserRegisterFormHandler ( c )
}
}
// UserVerifyEmailHandler : Controller when verifying email, needs a token
func UserVerifyEmailHandler ( c * gin . Context ) {
token := c . Param ( "token" )
messages := msg . GetMessages ( c )
2017-07-02 23:53:23 +02:00
_ , errEmail := email . EmailVerification ( token , c )
2017-06-28 13:42:38 +02:00
if errEmail != nil {
messages . ImportFromError ( "errors" , errEmail )
}
staticTemplate ( c , "site/static/verify_success.jet.html" )
}
// UserLoginPostHandler : Post Login controller
func UserLoginPostHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
b := userValidator . LoginForm { }
2017-06-28 13:42:38 +02:00
c . Bind ( & b )
messages := msg . GetMessages ( c )
2017-07-02 23:53:23 +02:00
validator . ValidateForm ( & b , messages )
2017-06-28 13:42:38 +02:00
if ! messages . HasErrors ( ) {
2017-07-02 23:53:23 +02:00
_ , _ , errorUser := cookies . CreateUserAuthentication ( c , & b )
2017-06-28 13:42:38 +02:00
if errorUser == nil {
2017-07-04 02:48:20 +02:00
url := c . DefaultPostForm ( "redirectTo" , "/" )
c . Redirect ( http . StatusSeeOther , url )
2017-06-28 13:42:38 +02:00
return
}
messages . ErrorT ( errorUser )
}
UserLoginFormHandler ( c )
}
// UserLogoutHandler : Controller to logout users
func UserLogoutHandler ( c * gin . Context ) {
logout := c . PostForm ( "logout" )
if logout != "" {
2017-07-02 23:53:23 +02:00
cookies . Clear ( c )
2017-06-28 13:42:38 +02:00
url := c . DefaultPostForm ( "redirectTo" , "/" )
c . Redirect ( http . StatusSeeOther , url )
} else {
NotFoundHandler ( c )
}
}
// UserFollowHandler : Controller to follow/unfollow users, need user id to follow
func UserFollowHandler ( c * gin . Context ) {
var followAction string
2017-07-02 23:53:23 +02:00
id , _ := strconv . ParseUint ( c . Param ( "id" ) , 10 , 32 )
2017-06-28 13:42:38 +02:00
currentUser := getUser ( c )
2017-07-02 23:53:23 +02:00
user , _ , errorUser := users . FindForAdmin ( uint ( id ) )
2017-06-28 13:42:38 +02:00
if errorUser == nil && user . ID > 0 {
2017-07-02 23:53:23 +02:00
if ! currentUser . IsFollower ( user ) {
2017-06-28 13:42:38 +02:00
followAction = "followed"
2017-07-02 23:53:23 +02:00
currentUser . SetFollow ( user )
2017-06-28 13:42:38 +02:00
} else {
followAction = "unfollowed"
2017-07-02 23:53:23 +02:00
currentUser . RemoveFollow ( user )
2017-06-28 13:42:38 +02:00
}
}
url := "/user/" + strconv . Itoa ( int ( user . ID ) ) + "/" + user . Username + "?" + followAction
c . Redirect ( http . StatusSeeOther , url )
}
// UserNotificationsHandler : Controller to show user notifications
func UserNotificationsHandler ( c * gin . Context ) {
currentUser := getUser ( c )
if currentUser . ID > 0 {
messages := msg . GetMessages ( c )
if c . Request . URL . Query ( ) [ "clear" ] != nil {
2017-07-02 23:53:23 +02:00
notifications . DeleteAllNotifications ( currentUser . ID )
2017-06-28 13:42:38 +02:00
messages . AddInfoT ( "infos" , "notifications_cleared" )
2017-07-01 23:09:35 +02:00
currentUser . Notifications = [ ] models . Notification { }
2017-06-28 13:42:38 +02:00
}
userProfileNotificationsTemplate ( c , currentUser )
} else {
NotFoundHandler ( c )
}
}
// UserAPIKeyResetHandler : Controller to reset user api key
func UserAPIKeyResetHandler ( c * gin . Context ) {
2017-07-02 23:53:23 +02:00
id , _ := strconv . ParseUint ( c . Param ( "id" ) , 10 , 32 )
2017-06-28 13:42:38 +02:00
currentUser := getUser ( c )
messages := msg . GetMessages ( c )
2017-07-02 23:53:23 +02:00
userProfile , _ , errorUser := users . FindForAdmin ( uint ( id ) )
if errorUser != nil || ! currentUser . CurrentOrAdmin ( userProfile . ID ) || userProfile . ID == 0 {
2017-06-28 13:42:38 +02:00
NotFoundHandler ( c )
return
}
userProfile . APIToken , _ = crypto . GenerateRandomToken32 ( )
userProfile . APITokenExpiry = time . Unix ( 0 , 0 )
2017-07-02 23:53:23 +02:00
_ , errorUser = userProfile . UpdateRaw ( )
2017-06-28 13:42:38 +02:00
if errorUser != nil {
messages . Error ( errorUser )
} else {
messages . AddInfoT ( "infos" , "profile_updated" )
}
UserProfileHandler ( c )
}