Audio captcha (#995)
* Megacheck friendly applied megacheck and fixed some unwanted behaviour (markdown) * Forgot this file * Captcha Audio Should make #993 happen * Fix style issue in comments * Added margin auto and width on input * Moved width on captcha div instead * fixing width issue with audio tag * Captcha final style fix
Cette révision appartient à :
Parent
963879f7aa
révision
0662b3fb41
15 fichiers modifiés avec 87 ajouts et 90 suppressions
4
main.go
4
main.go
|
@ -28,9 +28,9 @@ var buildversion string
|
|||
// RunServer runs webapp mainloop
|
||||
func RunServer(conf *config.Config) {
|
||||
// TODO Use config from cli
|
||||
os.Mkdir(router.DatabaseDumpPath, 700)
|
||||
os.Mkdir(router.DatabaseDumpPath, 0700)
|
||||
// TODO Use config from cli
|
||||
os.Mkdir(router.GPGPublicKeyPath, 700)
|
||||
os.Mkdir(router.GPGPublicKeyPath, 0700)
|
||||
|
||||
http.Handle("/", router.CSRFRouter)
|
||||
|
||||
|
|
|
@ -965,3 +965,7 @@ input.filelist-checkbox:checked + table.table-filelist {
|
|||
input.nav-btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment-captcha {
|
||||
width: 240px;
|
||||
}
|
|
@ -24,7 +24,7 @@ func DatabaseDumpHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// db params url
|
||||
var err error
|
||||
// TODO Use config from cli
|
||||
files, err := filepath.Glob(filepath.Join(DatabaseDumpPath, "*.torrent"))
|
||||
files, _ := filepath.Glob(filepath.Join(DatabaseDumpPath, "*.torrent"))
|
||||
defer r.Body.Close()
|
||||
var dumpsJSON []model.DatabaseDumpJSON
|
||||
// TODO Filter *.torrent files
|
||||
|
|
|
@ -163,6 +163,9 @@ func TorrentsListPanel(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
searchParam, torrents, count, err := search.SearchByQueryWithUser(r, pagenum)
|
||||
if err != nil {
|
||||
messages.ImportFromError("errors", err)
|
||||
}
|
||||
searchForm := searchForm{
|
||||
SearchParam: searchParam,
|
||||
Category: searchParam.Category.String(),
|
||||
|
@ -469,6 +472,9 @@ func DeletedTorrentsModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
searchParam, torrents, count, err := search.SearchByQueryDeleted(r, pagenum)
|
||||
if err != nil {
|
||||
messages.ImportFromError("errors", err)
|
||||
}
|
||||
searchForm := searchForm{
|
||||
SearchParam: searchParam,
|
||||
Category: searchParam.Category.String(),
|
||||
|
|
|
@ -76,12 +76,6 @@ type changeLanguageVariables struct {
|
|||
Languages map[string]string
|
||||
}
|
||||
|
||||
type publicSettingsVariables struct {
|
||||
commonTemplateVariables
|
||||
Language string
|
||||
Languages map[string]string
|
||||
}
|
||||
|
||||
/* MODERATION Variables */
|
||||
|
||||
type panelIndexVbs struct {
|
||||
|
|
|
@ -117,6 +117,9 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
comment := model.Comment{TorrentID: torrent.ID, UserID: userID, Content: content, CreatedAt: time.Now()}
|
||||
err := db.ORM.Create(&comment).Error
|
||||
if err != nil {
|
||||
messages.ImportFromError("errors", err)
|
||||
}
|
||||
comment.Torrent = &torrent
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.ID), 10))
|
||||
|
@ -147,7 +150,7 @@ func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
if !messages.HasErrors() {
|
||||
idNum, err := strconv.Atoi(id)
|
||||
idNum, _ := strconv.Atoi(id)
|
||||
userID := currentUser.ID
|
||||
|
||||
report := model.TorrentReport{
|
||||
|
@ -157,7 +160,7 @@ func ReportTorrentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
err = db.ORM.Create(&report).Error
|
||||
err := db.ORM.Create(&report).Error
|
||||
messages.AddInfoTf("infos", "report_msg", id)
|
||||
if err != nil {
|
||||
messages.ImportFromError("errors", err)
|
||||
|
@ -268,12 +271,12 @@ func DownloadTorrent(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
//Check if file exists and open
|
||||
Openfile, err := os.Open(fmt.Sprintf("%s%c%s.torrent", config.Conf.Torrents.FileStorage, os.PathSeparator, hash))
|
||||
defer Openfile.Close() //Close after function return
|
||||
if err != nil {
|
||||
//File not found, send 404
|
||||
http.Error(w, "File not found.", 404)
|
||||
return
|
||||
}
|
||||
defer Openfile.Close() //Close after function return
|
||||
|
||||
//Get the file size
|
||||
FileStat, _ := Openfile.Stat() //Get info from file
|
||||
|
|
|
@ -158,31 +158,15 @@ func (r *TorrentRequest) validateDescription() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO Check category is within accepted range
|
||||
func validateCategory(r *TorrentRequest) (error, int) {
|
||||
if r.CategoryID == 0 {
|
||||
return ErrCategory, http.StatusNotAcceptable
|
||||
}
|
||||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
// TODO Check subCategory is within accepted range
|
||||
func validateSubCategory(r *TorrentRequest) (error, int) {
|
||||
if r.SubCategory == 0 {
|
||||
return ErrSubCategory, http.StatusNotAcceptable
|
||||
}
|
||||
return nil, http.StatusOK
|
||||
}
|
||||
|
||||
func validateWebsiteLink(r *TorrentRequest) (error, int) {
|
||||
func (r *TorrentRequest) validateWebsiteLink() error {
|
||||
if r.WebsiteLink != "" {
|
||||
// WebsiteLink
|
||||
urlRegexp, _ := regexp.Compile(`^(https?:\/\/|ircs?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`)
|
||||
if !urlRegexp.MatchString(r.WebsiteLink) {
|
||||
return ErrWebsiteLink, http.StatusNotAcceptable
|
||||
return errInvalidWebsiteLink
|
||||
}
|
||||
}
|
||||
return nil, http.StatusOK
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *TorrentRequest) validateMagnet() error {
|
||||
|
@ -252,25 +236,24 @@ func (r *TorrentRequest) ExtractEditInfo(req *http.Request) error {
|
|||
func (r *TorrentRequest) ExtractCategory(req *http.Request) error {
|
||||
catsSplit := strings.Split(r.Category, "_")
|
||||
// need this to prevent out of index panics
|
||||
if len(catsSplit) == 2 {
|
||||
CatID, err := strconv.Atoi(catsSplit[0])
|
||||
if err != nil {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
SubCatID, err := strconv.Atoi(catsSplit[1])
|
||||
if err != nil {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
|
||||
if !categories.CategoryExists(r.Category) {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
|
||||
r.CategoryID = CatID
|
||||
r.SubCategoryID = SubCatID
|
||||
} else {
|
||||
if len(catsSplit) != 2 {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
CatID, err := strconv.Atoi(catsSplit[0])
|
||||
if err != nil {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
SubCatID, err := strconv.Atoi(catsSplit[1])
|
||||
if err != nil {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
|
||||
if !categories.CategoryExists(r.Category) {
|
||||
return errInvalidTorrentCategory
|
||||
}
|
||||
|
||||
r.CategoryID = CatID
|
||||
r.SubCategoryID = SubCatID
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -354,14 +337,8 @@ func (r *TorrentRequest) ExtractBasicValue(req *http.Request) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if r.WebsiteLink != "" {
|
||||
// WebsiteLink
|
||||
urlRegexp, _ := regexp.Compile(`^(https?:\/\/|ircs?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`)
|
||||
if !urlRegexp.MatchString(r.WebsiteLink) {
|
||||
return errInvalidWebsiteLink
|
||||
}
|
||||
}
|
||||
return nil
|
||||
err = r.validateWebsiteLink()
|
||||
return err
|
||||
}
|
||||
|
||||
// ExtractInfo : takes an http request and computes all fields for this form
|
||||
|
|
|
@ -124,32 +124,38 @@ func (sc *Scraper) RunWorker(pc net.PacketConn) (err error) {
|
|||
break
|
||||
}
|
||||
tid, err := ev.TID()
|
||||
if err != nil {
|
||||
log.Warnf("failed: %s", err)
|
||||
break
|
||||
}
|
||||
action, err := ev.Action()
|
||||
if err != nil {
|
||||
log.Warnf("failed: %s", err)
|
||||
break
|
||||
}
|
||||
log.Debugf("transaction = %d action = %d", tid, action)
|
||||
if err == nil {
|
||||
bucket, ok = sc.trackers[ev.From.String()]
|
||||
if ok && bucket != nil {
|
||||
bucket.VisitTransaction(tid, func(t *Transaction) {
|
||||
if t == nil {
|
||||
log.Warnf("no transaction %d", tid)
|
||||
} else {
|
||||
if t.GotData(ev.Data) {
|
||||
err := t.Sync()
|
||||
if err != nil {
|
||||
log.Warnf("failed to sync swarm: %s", err)
|
||||
}
|
||||
t.Done()
|
||||
log.Debugf("transaction %d done", tid)
|
||||
} else {
|
||||
sc.sendQueue <- t.SendEvent(ev.From)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
log.Warnf("bucket not found for %s", ev.From)
|
||||
}
|
||||
bucket, ok = sc.trackers[ev.From.String()]
|
||||
if !ok || bucket == nil {
|
||||
log.Warnf("bucket not found for %s", ev.From)
|
||||
break
|
||||
}
|
||||
|
||||
bucket.VisitTransaction(tid, func(t *Transaction) {
|
||||
if t == nil {
|
||||
log.Warnf("no transaction %d", tid)
|
||||
return
|
||||
}
|
||||
if t.GotData(ev.Data) {
|
||||
err := t.Sync()
|
||||
if err != nil {
|
||||
log.Warnf("failed to sync swarm: %s", err)
|
||||
}
|
||||
t.Done()
|
||||
log.Debugf("transaction %d done", tid)
|
||||
} else {
|
||||
sc.sendQueue <- t.SendEvent(ev.From)
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ const stateTransact = 2
|
|||
|
||||
const actionError = 3
|
||||
const actionScrape = 2
|
||||
const actionAnnounce = 1
|
||||
|
||||
//const actionAnnounce = 1
|
||||
const actionConnect = 0
|
||||
|
||||
// Transaction a scrape transaction on a udp tracker
|
||||
|
|
|
@ -62,10 +62,8 @@ func CheckEmail(email string) bool {
|
|||
}
|
||||
var count int
|
||||
db.ORM.Model(model.User{}).Where("email = ?", email).Count(&count)
|
||||
if count != 0 {
|
||||
return true // error: duplicate
|
||||
}
|
||||
return false
|
||||
|
||||
return count != 0
|
||||
}
|
||||
|
||||
// CreateUserFromForm creates a user from a registration form.
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
{{define "captcha"}}
|
||||
{{/* unset if user doesn't need captcha */}}
|
||||
{{if ne .CaptchaID ""}}
|
||||
<div class="form-group captcha-container">
|
||||
<div class="form-group captcha-container" style="width: 240px;margin: auto;">
|
||||
<h3>{{call $.T "captcha"}}</h3>
|
||||
<input type="text" name="captchaID" value="{{.CaptchaID}}" hidden>
|
||||
<img src="/captcha/{{.CaptchaID}}.png"><br>
|
||||
<input class="form-input up-input" type="text" name="solution" id="solution" class="form-control" style="width: 240px;" placeholder="{{call $.T "captcha"}}" autocomplete="off" required>
|
||||
<audio src="/captcha/{{.CaptchaID}}.wav" controls style="width: 240px;">
|
||||
<a href="/captcha/{{.CaptchaID}}.wav?lang={{ call $.T "language_code" }}">{{ call $.T "captcha_audio" }}</a>
|
||||
</audio>
|
||||
<input class="form-input up-input" type="text" name="solution" id="solution" class="form-control" style="display:block;" placeholder="{{call $.T "captcha"}}" autocomplete="off" required>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
@ -131,8 +131,8 @@
|
|||
</div>
|
||||
<div class="comment-captcha">
|
||||
{{block "captcha" (makeCaptchaData .CaptchaID $.T)}}{{end}}
|
||||
<button type="submit" class="form-input up-btn">{{call $.T "submit" }}</button>
|
||||
</div>
|
||||
<button type="submit" class="form-input up-btn">{{call $.T "submit" }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -154,7 +154,9 @@
|
|||
<input type="radio" name="report_type" value="spam_garbage" id="spam" required> <label for="spam">{{ call $.T "spam_garbage" }}</label><br />
|
||||
<input type="radio" name="report_type" value="wrong_category" id="wrongcat" required> <label for="wrongcat">{{ call $.T "wrong_category" }}</label><br />
|
||||
<input type="radio" name="report_type" value="duplicate_deprecated" id="dup" required> <label for="dup">{{ call $.T "duplicate_deprecated" }}</label><br />
|
||||
<div class="comment-captcha">
|
||||
{{template "captcha" (makeCaptchaData $.CaptchaID $.T)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span><button id="confirm_changes" type="submit">{{ call $.T "yes"}}</button>
|
||||
|
|
|
@ -727,6 +727,10 @@
|
|||
"id": "captcha",
|
||||
"translation": "Captcha"
|
||||
},
|
||||
{
|
||||
"id": "captcha_audio",
|
||||
"translation": "Captcha Audio"
|
||||
},
|
||||
{
|
||||
"id": "file_name",
|
||||
"translation": "File Name"
|
||||
|
|
|
@ -50,7 +50,7 @@ func FileListToFolder(fileList []model.File, folderName string) (out *FileListFo
|
|||
return strings.ToLower(out.Folders[i].FolderName) < strings.ToLower(out.Folders[j].FolderName)
|
||||
})
|
||||
slice.Sort(out.Files, func(i, j int) bool {
|
||||
return strings.ToLower(out.Files[i].Filename()) < strings.ToLower(out.Files[i].Filename())
|
||||
return strings.ToLower(out.Files[i].Filename()) < strings.ToLower(out.Files[j].Filename())
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -67,4 +67,3 @@ func (f *FileListFolder) TotalSize() (out int64) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ var HtmlMdRenderer md.Renderer
|
|||
// MarkdownToHTML : convert markdown to html
|
||||
// TODO: restrict certain types of markdown
|
||||
func MarkdownToHTML(markdown string) template.HTML {
|
||||
if len(markdown) >= 3 && markdown[:3] == ">" {
|
||||
markdown = ">" + markdown[3:]
|
||||
if len(markdown) >= 3 && markdown[:4] == ">" {
|
||||
markdown = ">" + markdown[4:]
|
||||
}
|
||||
markdown = strings.Replace(markdown, "\n>", "\n>", -1)
|
||||
unsafe := md.MarkdownOptions([]byte(markdown), HtmlMdRenderer, md.Options{Extensions: mdOptions})
|
||||
|
|
Référencer dans un nouveau ticket