Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Cleanups and fixes (#623)

* Keep naming consistent

* Remove execute bit from files

* Default to DefaultLanguage (without passing it to the func)

* Remove commented code

* Use Content-Type to get language json

* Lines of 400 characters is dumb

* Update new repo in README

* Remove useless script since we fallback to a defaultlang

* Fix fallback language panic

* Fix uninitialized MaxPerPage when not in querystr

The issue was that the req.MaxPerPage was not set (default to 0) when
the query string didn't include "max". This makes the server query the
whole db since the resulting limit is 0.

* Fix creating empty torrents (only worked once)

* Lines of 400 characters is still dumb
Cette révision appartient à :
tomleb 2017-05-18 22:55:59 -04:00 révisé par ewhal
Parent a0d5570cdf
révision babf0a37f0
29 fichiers modifiés avec 325 ajouts et 277 suppressions

Voir le fichier

@ -25,9 +25,9 @@ You may now start the container as such.
``` ```
$ export GOPATH=$HOME/.go $ export GOPATH=$HOME/.go
$ mkdir -p $HOME/.go/src/github.com/ewhal $ mkdir -p $HOME/.go/src/github.com/NyaaPantsu
$ cd $HOME/.go/src/github.com/ewhal $ cd $HOME/.go/src/github.com/NyaaPantsu
$ git clone https://github.com/ewhal/nyaa $ git clone https://github.com/NyaaPantsu/nyaa
$ cd nyaa/deploy $ cd nyaa/deploy
$ docker-compose -f <docker_compose_file> up $ docker-compose -f <docker_compose_file> up
``` ```

Voir le fichier

@ -24,7 +24,8 @@ function loadLanguages() {
} }
} }
} }
xhr.open("GET", "/language?format=json", true) xhr.open("GET", "/language", true)
xhr.setRequestHeader("Content-Type", "application/json")
xhr.send() xhr.send()
} }

Voir le fichier

@ -34,7 +34,7 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
} }
if req.MaxPerPage == 0 { if req.MaxPerPage == 0 {
req.MaxPerPage = 50 req.MaxPerPage = config.TorrentsPerPage
} }
if req.Page == 0 { if req.Page == 0 {
req.Page = 1 req.Page = 1
@ -47,8 +47,10 @@ func ApiHandler(w http.ResponseWriter, r *http.Request) {
if maxString != "" { if maxString != "" {
req.MaxPerPage, err = strconv.Atoi(maxString) req.MaxPerPage, err = strconv.Atoi(maxString)
if !log.CheckError(err) { if !log.CheckError(err) {
req.MaxPerPage = 50 // default Value maxPerPage req.MaxPerPage = config.TorrentsPerPage
} }
} else {
req.MaxPerPage = config.TorrentsPerPage
} }
req.Page = 1 req.Page = 1
@ -125,12 +127,12 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
contentType := r.Header.Get("Content-Type") contentType := r.Header.Get("Content-Type")
if contentType == "application/json" { if contentType == "application/json" {
defer r.Body.Close() defer r.Body.Close()
d := json.NewDecoder(r.Body) d := json.NewDecoder(r.Body)
if err := d.Decode(&upload); err != nil { if err := d.Decode(&upload); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) decodeError := fmt.Errorf("Unable to decode upload data: %s", err).Error()
http.Error(w, decodeError, http.StatusInternalServerError)
return return
} }
err, code := upload.ValidateUpload() err, code := upload.ValidateUpload()
@ -139,7 +141,6 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
} else if strings.HasPrefix(contentType, "multipart/form-data") { } else if strings.HasPrefix(contentType, "multipart/form-data") {
upload.Name = r.FormValue("name") upload.Name = r.FormValue("name")
upload.Category, _ = strconv.Atoi(r.FormValue("category")) upload.Category, _ = strconv.Atoi(r.FormValue("category"))
upload.SubCategory, _ = strconv.Atoi(r.FormValue("sub_category")) upload.SubCategory, _ = strconv.Atoi(r.FormValue("sub_category"))
@ -153,12 +154,17 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), code) http.Error(w, err.Error(), code)
return return
} }
} else {
// TODO What should we do here ? upload is empty so we shouldn't
// create a torrent from it
err := fmt.Errorf("Please provide either of Content-Type: application/json header or multipart/form-data").Error()
http.Error(w, err, http.StatusInternalServerError)
} }
var sameTorrents int var sameTorrents int
db.ORM.Model(&model.Torrent{}).Where("torrent_hash = ?", upload.Hash).Count(&sameTorrents) db.ORM.Model(&model.Torrent{}).Where("torrent_hash = ?", upload.Hash).Count(&sameTorrents)
if sameTorrents == 0 { if sameTorrents == 0 {
torrent := model.Torrent{ torrent := model.Torrent{
Name: upload.Name, Name: upload.Name,
Category: upload.Category, Category: upload.Category,
@ -183,6 +189,7 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
} }
} }
// FIXME Impossible to update a torrent uploaded by user 0
func ApiUpdateHandler(w http.ResponseWriter, r *http.Request) { func ApiUpdateHandler(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization") token := r.Header.Get("Authorization")
user := model.User{} user := model.User{}

Voir le fichier

@ -9,7 +9,14 @@ import (
func FaqHandler(w http.ResponseWriter, r *http.Request) { func FaqHandler(w http.ResponseWriter, r *http.Request) {
languages.SetTranslationFromRequest(faqTemplate, r) languages.SetTranslationFromRequest(faqTemplate, r)
err := faqTemplate.ExecuteTemplate(w, "index.html", FaqTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)}) ftv := FaqTemplateVariables{
Navigation: NewNavigation(),
Search: NewSearchForm(),
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err := faqTemplate.ExecuteTemplate(w, "index.html", ftv)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }

Voir le fichier

@ -52,12 +52,24 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) {
return torrents, nbTorrents, err return torrents, nbTorrents, err
}) })
b := model.TorrentsToJSON(torrents) navigationTorrents := Navigation{
TotalItem: nbTorrents,
navigationTorrents := Navigation{nbTorrents, maxPerPage, pagenum, "search_page"} MaxItemPerPage: maxPerPage,
CurrentPage: pagenum,
Route: "search_page",
}
languages.SetTranslationFromRequest(homeTemplate, r) languages.SetTranslationFromRequest(homeTemplate, r)
htv := HomeTemplateVariables{b, NewSearchForm(), navigationTorrents, GetUser(r), r.URL, mux.CurrentRoute(r)}
torrentsJson := model.TorrentsToJSON(torrents)
htv := HomeTemplateVariables{
ListTorrents: torrentsJson,
Search: NewSearchForm(),
Navigation: navigationTorrents,
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err = homeTemplate.ExecuteTemplate(w, "index.html", htv) err = homeTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil { if err != nil {

Voir le fichier

@ -18,8 +18,8 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
_, Tlang := languages.GetTfuncAndLanguageFromRequest(r) _, Tlang := languages.GetTfuncAndLanguageFromRequest(r)
availableLanguages := languages.GetAvailableLanguages() availableLanguages := languages.GetAvailableLanguages()
format := r.URL.Query().Get("format") contentType := r.Header.Get("Content-Type")
if format == "json" { if contentType == "application/json" {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(LanguagesJSONResponse{Tlang.Tag, availableLanguages}) err := json.NewEncoder(w).Encode(LanguagesJSONResponse{Tlang.Tag, availableLanguages})
if err != nil { if err != nil {
@ -27,7 +27,15 @@ func SeeLanguagesHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
} else { } else {
clv := ChangeLanguageVariables{NewSearchForm(), NewNavigation(), Tlang.Tag, availableLanguages, GetUser(r), r.URL, mux.CurrentRoute(r)} clv := ChangeLanguageVariables{
Search: NewSearchForm(),
Navigation: NewNavigation(),
Language: Tlang.Tag,
Languages: availableLanguages,
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
languages.SetTranslationFromRequest(changeLanguageTemplate, r) languages.SetTranslationFromRequest(changeLanguageTemplate, r)
err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv) err := changeLanguageTemplate.ExecuteTemplate(w, "index.html", clv)
if err != nil { if err != nil {
@ -52,9 +60,8 @@ func ChangeLanguageHandler(w http.ResponseWriter, r *http.Request) {
user.Language = lang user.Language = lang
// I don't know if I should use this... // I don't know if I should use this...
userService.UpdateUserCore(&user) userService.UpdateUserCore(&user)
} else {
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang})
} }
http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang})
url, _ := Router.Get("home").URL() url, _ := Router.Get("home").URL()
http.Redirect(w, r, url.String(), http.StatusSeeOther) http.Redirect(w, r, url.String(), http.StatusSeeOther)

Voir le fichier

@ -8,10 +8,18 @@ import (
) )
func NotFoundHandler(w http.ResponseWriter, r *http.Request) { func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
languages.SetTranslationFromRequest(notFoundTemplate, r)
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
languages.SetTranslationFromRequest(notFoundTemplate, r) nftv := NotFoundTemplateVariables{
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)}) Navigation: NewNavigation(),
Search: NewSearchForm(),
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err := notFoundTemplate.ExecuteTemplate(w, "index.html", nftv)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }

34
router/router.go Fichier exécutable → Fichier normal
Voir le fichier

@ -30,43 +30,9 @@ func init() {
gzipUserProfileFormHandler := http.HandlerFunc(UserProfileFormHandler) gzipUserProfileFormHandler := http.HandlerFunc(UserProfileFormHandler)
gzipDumpsHandler := handlers.CompressHandler(dumpsHandler) gzipDumpsHandler := handlers.CompressHandler(dumpsHandler)
gzipGpgKeyHandler := handlers.CompressHandler(gpgKeyHandler) gzipGpgKeyHandler := handlers.CompressHandler(gpgKeyHandler)
/*
// Enable GZIP compression for all handlers except imgHandler and captcha
gzipCSSHandler := cssHandler)
gzipJSHandler:= jsHandler)
gzipSearchHandler:= http.HandlerFunc(SearchHandler)
gzipAPIUploadHandler := http.HandlerFunc(ApiUploadHandler)
gzipAPIUpdateHandler := http.HandlerFunc(ApiUpdateHandler)
gzipFaqHandler := http.HandlerFunc(FaqHandler)
gzipRSSHandler := http.HandlerFunc(RSSHandler)
gzipUploadHandler := http.HandlerFunc(UploadHandler)
gzipUserRegisterFormHandler := http.HandlerFunc(UserRegisterFormHandler)
gzipUserLoginFormHandler := http.HandlerFunc(UserLoginFormHandler)
gzipUserVerifyEmailHandler := http.HandlerFunc(UserVerifyEmailHandler)
gzipUserRegisterPostHandler := http.HandlerFunc(UserRegisterPostHandler)
gzipUserLoginPostHandler := http.HandlerFunc(UserLoginPostHandler)
gzipUserLogoutHandler := http.HandlerFunc(UserLogoutHandler)
gzipUserFollowHandler := http.HandlerFunc(UserFollowHandler)
gzipIndexModPanel := http.HandlerFunc(IndexModPanel)
gzipTorrentsListPanel := http.HandlerFunc(TorrentsListPanel)
gzipTorrentReportListPanel := http.HandlerFunc(TorrentReportListPanel)
gzipUsersListPanel := http.HandlerFunc(UsersListPanel)
gzipCommentsListPanel := http.HandlerFunc(CommentsListPanel)
gzipTorrentEditModPanel := http.HandlerFunc(TorrentEditModPanel)
gzipTorrentPostEditModPanel := http.HandlerFunc(TorrentPostEditModPanel)
gzipCommentDeleteModPanel := http.HandlerFunc(CommentDeleteModPanel)
gzipTorrentDeleteModPanel := http.HandlerFunc(TorrentDeleteModPanel)
gzipTorrentReportDeleteModPanel := http.HandlerFunc(TorrentReportDeleteModPanel)*/
//gzipTorrentReportCreateHandler := http.HandlerFunc(CreateTorrentReportHandler)
//gzipTorrentReportDeleteHandler := http.HandlerFunc(DeleteTorrentReportHandler)
//gzipTorrentDeleteHandler := http.HandlerFunc(DeleteTorrentHandler)
gzipDatabaseDumpHandler := handlers.CompressHandler(http.HandlerFunc(DatabaseDumpHandler)) gzipDatabaseDumpHandler := handlers.CompressHandler(http.HandlerFunc(DatabaseDumpHandler))
Router = mux.NewRouter() Router = mux.NewRouter()
// Routes
http.Handle("/css/", http.StripPrefix("/css/", cssHandler)) http.Handle("/css/", http.StripPrefix("/css/", cssHandler))
http.Handle("/js/", http.StripPrefix("/js/", jsHandler)) http.Handle("/js/", http.StripPrefix("/js/", jsHandler))
http.Handle("/img/", http.StripPrefix("/img/", imgHandler)) http.Handle("/img/", http.StripPrefix("/img/", imgHandler))

Voir le fichier

@ -7,9 +7,29 @@ import (
var TemplateDir = "templates" var TemplateDir = "templates"
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate, viewProfileEditTemplate, viewUserDeleteTemplate, notFoundTemplate, changeLanguageTemplate, databaseDumpTemplate *template.Template var homeTemplate,
searchTemplate,
faqTemplate,
uploadTemplate,
viewTemplate,
viewRegisterTemplate,
viewLoginTemplate,
viewRegisterSuccessTemplate,
viewVerifySuccessTemplate,
viewProfileTemplate,
viewProfileEditTemplate,
viewUserDeleteTemplate,
notFoundTemplate,
changeLanguageTemplate,
databaseDumpTemplate *template.Template
var panelIndex, panelTorrentList, panelUserList, panelCommentList, panelTorrentEd, panelTorrentReportList, panelTorrentReassign *template.Template var panelIndex,
panelTorrentList,
panelUserList,
panelCommentList,
panelTorrentEd,
panelTorrentReportList,
panelTorrentReassign *template.Template
type templateLoader struct { type templateLoader struct {
templ **template.Template templ **template.Template
@ -93,8 +113,8 @@ func ReloadTemplates() {
}, },
templateLoader{ templateLoader{
templ: &changeLanguageTemplate, templ: &changeLanguageTemplate,
name: "change_language", name: "change_language",
file: "change_language.html", file: "change_language.html",
}, },
} }
for idx := range pubTempls { for idx := range pubTempls {

Voir le fichier

@ -1,118 +0,0 @@
package router
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service/captcha"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/gorilla/mux"
)
func UploadHandler(w http.ResponseWriter, r *http.Request) {
user := GetUser(r)
if config.UploadsDisabled {
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
}
}
var uploadForm UploadForm
if r.Method == "POST" {
defer r.Body.Close()
if userPermission.NeedsCaptcha(user) {
userCaptcha := captcha.Extract(r)
if !captcha.Authenticate(userCaptcha) {
http.Error(w, captcha.ErrInvalidCaptcha.Error(), http.StatusInternalServerError)
return
}
}
// validation is done in ExtractInfo()
err := uploadForm.ExtractInfo(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
status := 1 // normal
if uploadForm.Remake { // overrides trusted
status = 2
} else if user.Status == 1 {
status = 3 // mark as trusted if user is trusted
}
var sameTorrents int
db.ORM.Model(&model.Torrent{}).Table(config.TableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
if sameTorrents == 0 {
// add to db and redirect
torrent := model.Torrent{
Name: uploadForm.Name,
Category: uploadForm.CategoryID,
SubCategory: uploadForm.SubCategoryID,
Status: status,
Hash: uploadForm.Infohash,
Date: time.Now(),
Filesize: uploadForm.Filesize,
Description: uploadForm.Description,
UploaderID: user.ID}
db.ORM.Table(config.TableName).Create(&torrent)
// add filelist to files db, if we have one
if len(uploadForm.FileList) > 0 {
for _, uploadedFile := range uploadForm.FileList {
file := model.File{TorrentID: torrent.ID, Filesize: uploadedFile.Filesize}
err := file.SetPath(uploadedFile.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
db.ORM.Create(&file)
}
}
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, url.String(), 302)
} else {
http.Error(w, fmt.Errorf("Torrent already in database!").Error(), http.StatusInternalServerError)
return
}
} else if r.Method == "GET" {
user := GetUser(r)
if userPermission.NeedsCaptcha(user) {
uploadForm.CaptchaID = captcha.GetID()
} else {
uploadForm.CaptchaID = ""
}
htv := UploadTemplateVariables{uploadForm, NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
languages.SetTranslationFromRequest(uploadTemplate, r)
err := uploadTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
}

134
router/upload_handler.go Fichier normal
Voir le fichier

@ -0,0 +1,134 @@
package router
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service/captcha"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/languages"
"github.com/gorilla/mux"
)
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if config.UploadsDisabled {
user := GetUser(r)
if config.AdminsAreStillAllowedTo && user.Status != 2 && config.TrustedUsersAreStillAllowedTo && user.Status != 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.AdminsAreStillAllowedTo && user.Status == 2 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
} else if !config.TrustedUsersAreStillAllowedTo && user.Status == 1 {
http.Error(w, "Error uploads are disabled", http.StatusInternalServerError)
return
}
}
if r.Method == "POST" {
UploadPostHandler(w, r)
} else if r.Method == "GET" {
UploadGetHandler(w, r)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
}
func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
var uploadForm UploadForm
defer r.Body.Close()
user := GetUser(r)
if userPermission.NeedsCaptcha(user) {
userCaptcha := captcha.Extract(r)
if !captcha.Authenticate(userCaptcha) {
http.Error(w, captcha.ErrInvalidCaptcha.Error(), http.StatusInternalServerError)
return
}
}
// validation is done in ExtractInfo()
err := uploadForm.ExtractInfo(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
status := 1 // normal
if uploadForm.Remake { // overrides trusted
status = 2
} else if user.Status == 1 {
status = 3 // mark as trusted if user is trusted
}
var sameTorrents int
db.ORM.Model(&model.Torrent{}).Table(config.TableName).Where("torrent_hash = ?", uploadForm.Infohash).Count(&sameTorrents)
if sameTorrents == 0 {
// add to db and redirect
torrent := model.Torrent{
Name: uploadForm.Name,
Category: uploadForm.CategoryID,
SubCategory: uploadForm.SubCategoryID,
Status: status,
Hash: uploadForm.Infohash,
Date: time.Now(),
Filesize: uploadForm.Filesize,
Description: uploadForm.Description,
UploaderID: user.ID}
db.ORM.Table(config.TableName).Create(&torrent)
// add filelist to files db, if we have one
if len(uploadForm.FileList) > 0 {
for _, uploadedFile := range uploadForm.FileList {
file := model.File{TorrentID: torrent.ID, Filesize: uploadedFile.Filesize}
err := file.SetPath(uploadedFile.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
db.ORM.Create(&file)
}
}
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, url.String(), 302)
} else {
err = fmt.Errorf("Torrent already in database!")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
languages.SetTranslationFromRequest(uploadTemplate, r)
var uploadForm UploadForm
user := GetUser(r)
if userPermission.NeedsCaptcha(user) {
uploadForm.CaptchaID = captcha.GetID()
} else {
uploadForm.CaptchaID = ""
}
utv := UploadTemplateVariables{
Upload: uploadForm,
Search: NewSearchForm(),
Navigation: NewNavigation(),
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err := uploadTemplate.ExecuteTemplate(w, "index.html", utv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}

151
router/userHandler.go → router/user_handler.go Fichier exécutable → Fichier normal
Voir le fichier

@ -18,30 +18,47 @@ import (
// Getting View User Registration // Getting View User Registration
func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) { func UserRegisterFormHandler(w http.ResponseWriter, r *http.Request) {
_, errorUser := userService.CurrentUser(r) _, errorUser := userService.CurrentUser(r)
if errorUser != nil { // User is already connected, redirect to home
b := form.RegistrationForm{} if errorUser == nil {
modelHelper.BindValueForm(&b, r)
b.CaptchaID = captcha.GetID()
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
htv := UserRegisterTemplateVariables{b, form.NewErrors(), NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)}
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
} else {
HomeHandler(w, r) HomeHandler(w, r)
return
}
registrationForm := form.RegistrationForm{}
modelHelper.BindValueForm(&registrationForm, r)
registrationForm.CaptchaID = captcha.GetID()
languages.SetTranslationFromRequest(viewRegisterTemplate, r)
urtv := UserRegisterTemplateVariables{
RegistrationForm: registrationForm,
FormErrors: form.NewErrors(),
Search: NewSearchForm(),
Navigation: NewNavigation(),
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err := viewRegisterTemplate.ExecuteTemplate(w, "index.html", urtv)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }
// Getting View User Login // Getting View User Login
func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) { func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
b := form.LoginForm{} loginForm := form.LoginForm{}
modelHelper.BindValueForm(&b, r) modelHelper.BindValueForm(&loginForm, r)
languages.SetTranslationFromRequest(viewLoginTemplate, r) languages.SetTranslationFromRequest(viewLoginTemplate, r)
htv := UserLoginFormVariables{b, form.NewErrors(), NewSearchForm(), NewNavigation(), GetUser(r), r.URL, mux.CurrentRoute(r)} ulfv := UserLoginFormVariables{
LoginForm: loginForm,
FormErrors: form.NewErrors(),
Search: NewSearchForm(),
Navigation: NewNavigation(),
User: GetUser(r),
URL: r.URL,
Route: mux.CurrentRoute(r),
}
err := viewLoginTemplate.ExecuteTemplate(w, "index.html", htv) err := viewLoginTemplate.ExecuteTemplate(w, "index.html", ulfv)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
@ -128,64 +145,64 @@ func UserProfileFormHandler(w http.ResponseWriter, r *http.Request) {
id := vars["id"] id := vars["id"]
currentUser := GetUser(r) currentUser := GetUser(r)
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id) userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
if errorUser == nil { if errorUser != nil || !userPermission.CurrentOrAdmin(currentUser, userProfile.ID) {
if userPermission.CurrentOrAdmin(currentUser, userProfile.ID) { NotFoundHandler(w, r)
b := form.UserForm{} return
err := form.NewErrors() }
infos := form.NewInfos()
T := languages.SetTranslationFromRequest(viewProfileEditTemplate, r)
if len(r.PostFormValue("email")) > 0 {
_, err = form.EmailValidation(r.PostFormValue("email"), err)
}
if len(r.PostFormValue("username")) > 0 {
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
}
if len(err) == 0 { userForm := form.UserForm{}
modelHelper.BindValueForm(&b, r) err := form.NewErrors()
if !userPermission.HasAdmin(currentUser) { infos := form.NewInfos()
b.Username = userProfile.Username T := languages.SetTranslationFromRequest(viewProfileEditTemplate, r)
b.Status = userProfile.Status if len(r.PostFormValue("email")) > 0 {
} else { _, err = form.EmailValidation(r.PostFormValue("email"), err)
if userProfile.Status != b.Status && b.Status == 2 { }
err["errors"] = append(err["errors"], "Elevating status to moderator is prohibited") if len(r.PostFormValue("username")) > 0 {
} _, err = form.ValidateUsername(r.PostFormValue("username"), err)
} }
err = modelHelper.ValidateForm(&b, err)
if len(err) == 0 { if len(err) == 0 {
if b.Email != userProfile.Email { modelHelper.BindValueForm(&userForm, r)
userService.SendVerificationToUser(*currentUser, b.Email) if !userPermission.HasAdmin(currentUser) {
infos["infos"] = append(infos["infos"], fmt.Sprintf(T("email_changed"), b.Email)) userForm.Username = userProfile.Username
b.Email = userProfile.Email // reset, it will be set when user clicks verification userForm.Status = userProfile.Status
}
userProfile, _, errorUser = userService.UpdateUser(w, &b, currentUser, id)
if errorUser != nil {
err["errors"] = append(err["errors"], errorUser.Error())
} else {
infos["infos"] = append(infos["infos"], T("profile_updated"))
}
}
}
availableLanguages := languages.GetAvailableLanguages()
htv := UserProfileEditVariables{&userProfile, b, err, infos, availableLanguages, NewSearchForm(), NewNavigation(), currentUser, r.URL, mux.CurrentRoute(r)}
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", htv)
if errorTmpl != nil {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
}
} else { } else {
languages.SetTranslationFromRequest(notFoundTemplate, r) if userProfile.Status != userForm.Status && userForm.Status == 2 {
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)}) err["errors"] = append(err["errors"], "Elevating status to moderator is prohibited")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }
} else { err = modelHelper.ValidateForm(&userForm, err)
languages.SetTranslationFromRequest(notFoundTemplate, r) if len(err) == 0 {
err := notFoundTemplate.ExecuteTemplate(w, "index.html", NotFoundTemplateVariables{NewNavigation(), NewSearchForm(), GetUser(r), r.URL, mux.CurrentRoute(r)}) if userForm.Email != userProfile.Email {
if err != nil { userService.SendVerificationToUser(*currentUser, userForm.Email)
http.Error(w, err.Error(), http.StatusInternalServerError) infos["infos"] = append(infos["infos"], fmt.Sprintf(T("email_changed"), userForm.Email))
userForm.Email = userProfile.Email // reset, it will be set when user clicks verification
}
userProfile, _, errorUser = userService.UpdateUser(w, &userForm, currentUser, id)
if errorUser != nil {
err["errors"] = append(err["errors"], errorUser.Error())
} else {
infos["infos"] = append(infos["infos"], T("profile_updated"))
}
} }
} }
availableLanguages := languages.GetAvailableLanguages()
upev := UserProfileEditVariables{
UserProfile: &userProfile,
UserForm: userForm,
FormErrors: err,
FormInfos: infos,
Languages: availableLanguages,
Search: NewSearchForm(),
Navigation: NewNavigation(),
User: currentUser,
URL: r.URL,
Route: mux.CurrentRoute(r),
}
errorTmpl := viewProfileEditTemplate.ExecuteTemplate(w, "index.html", upev)
if errorTmpl != nil {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
}
} }
// Post Registration controller, we do some check on the form here, the rest on user service // Post Registration controller, we do some check on the form here, the rest on user service

Voir le fichier

@ -74,6 +74,7 @@ func validateName(r *TorrentRequest) (error, int) {
return nil, http.StatusOK return nil, http.StatusOK
} }
// TODO Check category is within accepted range
func validateCategory(r *TorrentRequest) (error, int) { func validateCategory(r *TorrentRequest) (error, int) {
if r.Category == 0 { if r.Category == 0 {
return ErrCategory, http.StatusNotAcceptable return ErrCategory, http.StatusNotAcceptable
@ -81,6 +82,7 @@ func validateCategory(r *TorrentRequest) (error, int) {
return nil, http.StatusOK return nil, http.StatusOK
} }
// TODO Check subCategory is within accepted range
func validateSubCategory(r *TorrentRequest) (error, int) { func validateSubCategory(r *TorrentRequest) (error, int) {
if r.SubCategory == 0 { if r.SubCategory == 0 {
return ErrSubCategory, http.StatusNotAcceptable return ErrSubCategory, http.StatusNotAcceptable

Voir le fichier

@ -1,12 +0,0 @@
#!/bin/bash
set -euo pipefail
id="$1"
translation="$2"
for file in *.json; do
head -n -2 "${file}" > "${file}.tmp"
echo -e " },\n {\n \"id\": \"${id}\",\n \"translation\": \"${translation}\"\n }\n]" >> "${file}.tmp"
mv "${file}.tmp" "${file}"
done

Voir le fichier

@ -29,7 +29,7 @@ func InitI18n(conf config.I18nConfig, retriever UserRetriever) error {
defaultLanguage = conf.DefaultLanguage defaultLanguage = conf.DefaultLanguage
userRetriever = retriever userRetriever = retriever
defaultFilepath := path.Join(conf.TranslationsDirectory, conf.DefaultLanguage+".all.json") defaultFilepath := path.Join(conf.TranslationsDirectory, defaultLanguage+".all.json")
err := i18n.LoadTranslationFile(defaultFilepath) err := i18n.LoadTranslationFile(defaultFilepath)
if err != nil { if err != nil {
panic(fmt.Sprintf("failed to load default translation file '%s': %v", defaultFilepath, err)) panic(fmt.Sprintf("failed to load default translation file '%s': %v", defaultFilepath, err))
@ -57,27 +57,26 @@ func GetDefaultLanguage() string {
// When go-i18n finds a language with >0 translations, it uses it as the Tfunc // When go-i18n finds a language with >0 translations, it uses it as the Tfunc
// However, if said language has a missing translation, it won't fallback to the "main" language // However, if said language has a missing translation, it won't fallback to the "main" language
func TfuncAndLanguageWithFallback(language string, languages ...string) (i18n.TranslateFunc, *language.Language, error) { func TfuncAndLanguageWithFallback(language string, languages ...string) (i18n.TranslateFunc, *language.Language, error) {
// Use the last language on the args as the fallback one. fallbackLanguage := GetDefaultLanguage()
fallbackLanguage := language
if languages != nil {
fallbackLanguage = languages[len(languages)-1]
}
T, Tlang, err1 := i18n.TfuncAndLanguage(language, languages...) tFunc, tLang, err1 := i18n.TfuncAndLanguage(language, languages...)
fallbackT, fallbackTlang, err2 := i18n.TfuncAndLanguage(fallbackLanguage) // If fallbackLanguage fails, it will give the "id" field so we don't
// care about the error
fallbackT, fallbackTlang, _ := i18n.TfuncAndLanguage(fallbackLanguage)
if err1 != nil && err2 != nil { translateFunction := func(translationID string, args ...interface{}) string {
// fallbackT is still a valid function even with the error, it returns translationID. if translated := tFunc(translationID, args...); translated != translationID {
return fallbackT, fallbackTlang, err2
}
return func(translationID string, args ...interface{}) string {
if translated := T(translationID, args...); translated != translationID {
return translated return translated
} }
return fallbackT(translationID, args...) return fallbackT(translationID, args...)
}, Tlang, nil }
if err1 != nil {
tLang = fallbackTlang
}
return translateFunction, tLang, err1
} }
func GetAvailableLanguages() (languages map[string]string) { func GetAvailableLanguages() (languages map[string]string) {
@ -112,8 +111,6 @@ func GetDefaultTfunc() (i18n.TranslateFunc, error) {
} }
func GetTfuncAndLanguageFromRequest(r *http.Request) (T i18n.TranslateFunc, Tlang *language.Language) { func GetTfuncAndLanguageFromRequest(r *http.Request) (T i18n.TranslateFunc, Tlang *language.Language) {
defaultLanguage := GetDefaultLanguage()
userLanguage := "" userLanguage := ""
user, err := getCurrentUser(r) user, err := getCurrentUser(r)
if err == nil { if err == nil {
@ -126,9 +123,9 @@ func GetTfuncAndLanguageFromRequest(r *http.Request) (T i18n.TranslateFunc, Tlan
cookieLanguage = cookie.Value cookieLanguage = cookie.Value
} }
// go-i18n supports the format of the Accept-Language header, thankfully. // go-i18n supports the format of the Accept-Language header
headerLanguage := r.Header.Get("Accept-Language") headerLanguage := r.Header.Get("Accept-Language")
T, Tlang, _ = TfuncAndLanguageWithFallback(userLanguage, cookieLanguage, headerLanguage, defaultLanguage) T, Tlang, _ = TfuncAndLanguageWithFallback(userLanguage, cookieLanguage, headerLanguage)
return return
} }