diff options
author | FChannel <> | 2021-07-22 19:03:28 -0700 |
---|---|---|
committer | FChannel <> | 2021-07-22 19:03:28 -0700 |
commit | 16b4165e5102fc9b4766e1bd1204ca9cf23199aa (patch) | |
tree | 0a491330799a37558a4d85648f29c45b5311ef59 | |
parent | 213683bf7245a05aa734ac2bb26fba60705ba5ee (diff) |
added banning media by saving hash in database
-rw-r--r-- | client.go | 2 | ||||
-rw-r--r-- | databaseschema.psql | 7 | ||||
-rw-r--r-- | main.go | 107 | ||||
-rw-r--r-- | outboxPost.go | 41 | ||||
-rw-r--r-- | static/posts.html | 9 |
5 files changed, 149 insertions, 17 deletions
@@ -641,7 +641,7 @@ func MediaProxy(url string) string { func ParseContent(db *sql.DB, board Actor, op string, content string, thread ObjectBase) template.HTML { var nContent = content - re := regexp.MustCompile(`(>>https?://[A-Za-z0-9_.\-~]+\/[A-Za-z0-9_.\-~]+\/\w+)`) + re := regexp.MustCompile(`(>>https?://[A-Za-z0-9_.:\-~]+\/[A-Za-z0-9_.\-~]+\/\w+)`) match := re.FindAllStringSubmatch(nContent, -1) //add url to each matched reply diff --git a/databaseschema.psql b/databaseschema.psql index 954aa2e..67681cd 100644 --- a/databaseschema.psql +++ b/databaseschema.psql @@ -232,4 +232,9 @@ id serial primary key, regex varchar(200) ); -ALTER TABLE actor ADD COLUMN IF NOT EXISTS autosubscribe boolean default false;
\ No newline at end of file +ALTER TABLE actor ADD COLUMN IF NOT EXISTS autosubscribe boolean default false; + +CREATE TABLE IF NOT EXISTS bannedmedia( +id serial primary key, +hash varchar(200) +);
\ No newline at end of file @@ -272,7 +272,7 @@ func main() { auth := CreateTripCode(verify.Code) auth = CreateTripCode(auth) - + if CreateTripCode(auth) == code { w.WriteHeader(http.StatusOK) } else { @@ -336,8 +336,8 @@ func main() { } if(r.FormValue("inReplyTo") == "" && file == nil) { - w.Write([]byte("Media is required for new posts")) - return + w.Write([]byte("Media is required for new posts")) + return } @@ -502,7 +502,7 @@ func main() { } } - //follow all of boards followers + //follow all of boards followers } else if followers.MatchString(follow){ followersActor := FingerActor(follow) col := GetActorCollection(followersActor.Followers) @@ -521,7 +521,7 @@ func main() { } } - //do a normal follow to a single board + //do a normal follow to a single board } else { followActivity := MakeFollowActivity(db, actorId, follow) @@ -603,7 +603,7 @@ func main() { } else if admin || actor.Id == Domain { t := template.Must(template.New("").Funcs(template.FuncMap{ "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/nadmin.html")) - + actor := GetActor(Domain) follow := GetActorCollection(actor.Following).Items follower := GetActorCollection(actor.Followers).Items @@ -771,7 +771,91 @@ func main() { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("404 no path")) } - }) + }) + + http.HandleFunc("/banmedia", func(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + board := r.URL.Query().Get("board") + + _, auth := GetPasswordFromSession(r) + + if id == "" || auth == "" { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("")) + return + } + + col := GetCollectionFromID(id) + + if len(col.OrderedItems) > 0 { + + actor := col.OrderedItems[0].Actor + + if !HasAuth(db, auth, actor) { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("")) + return + } + + if len(col.OrderedItems[0].Attachment) > 0 { + re := regexp.MustCompile(Domain) + file := re.ReplaceAllString(col.OrderedItems[0].Attachment[0].Href, "") + + f, err := os.Open("." + file) + CheckError(err, "could not open attachment for ban media") + + defer f.Close() + bytes, err := ioutil.ReadAll(f) + CheckError(err, "could not get attachment bytes for ban media") + + if !IsMediaBanned(db, f) { + query := `insert into bannedmedia (hash) values ($1)` + + _, err := db.Exec(query, HashBytes(bytes)) + + CheckError(err, "error inserting banend media into db") + + } + + var obj ObjectBase + obj.Id = id + obj.Actor = actor + + isOP := CheckIfObjectOP(db, obj.Id) + + var OP string + if len(col.OrderedItems[0].InReplyTo) > 0 { + OP = col.OrderedItems[0].InReplyTo[0].Id + } + + if !isOP { + TombstoneObject(db, id) + } else { + TombstoneObjectAndReplies(db, id) + } + + if IsIDLocal(db, id){ + go DeleteObjectRequest(db, id) + } + + + if !isOP { + if (!IsIDLocal(db, id)){ + http.Redirect(w, r, "/" + board + "/" + remoteShort(OP), http.StatusSeeOther) + return + } else { + http.Redirect(w, r, OP, http.StatusSeeOther) + return + } + } else { + http.Redirect(w, r, "/" + board, http.StatusSeeOther) + return + } + } + } + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("")) + }) http.HandleFunc("/delete", func(w http.ResponseWriter, r *http.Request){ id := r.URL.Query().Get("id") @@ -1377,7 +1461,6 @@ func CreateTripCode(input string) string { return code[0] } - func GetActorFromPath(db *sql.DB, location string, prefix string) Actor { pattern := fmt.Sprintf("%s([^/\n]+)(/.+)?", prefix) re := regexp.MustCompile(pattern) @@ -1891,7 +1974,7 @@ func MakeCaptchas(db *sql.DB, total int) { } func GetFileContentType(out multipart.File) (string, error) { - + buffer := make([]byte, 512) _, err := out.Read(buffer) @@ -2697,6 +2780,12 @@ func HashMedia(media string) string { return hex.EncodeToString(h.Sum(nil)) } +func HashBytes(media []byte) string { + h:= sha256.New() + h.Write(media) + return hex.EncodeToString(h.Sum(nil)) +} + func RouteImages(w http.ResponseWriter, media string) { req, err := http.NewRequest("GET", MediaHashs[media], nil) diff --git a/outboxPost.go b/outboxPost.go index 356647e..a827e21 100644 --- a/outboxPost.go +++ b/outboxPost.go @@ -7,6 +7,7 @@ import _ "github.com/lib/pq" import "encoding/json" import "reflect" import "io/ioutil" +import "mime/multipart" import "os" import "regexp" import "strings" @@ -24,6 +25,8 @@ func ParseOutboxRequest(w http.ResponseWriter, r *http.Request, db *sql.DB) { r.ParseMultipartForm(5 << 20) if(BoardHasAuthType(db, actor.Name, "captcha") && CheckCaptcha(db, r.FormValue("captcha"))) { f, header, _ := r.FormFile("file") + defer f.Close() + if(header != nil) { if(header.Size > (7 << 20)){ w.WriteHeader(http.StatusRequestEntityTooLarge) @@ -31,6 +34,12 @@ func ParseOutboxRequest(w http.ResponseWriter, r *http.Request, db *sql.DB) { return } + if(IsMediaBanned(db, f)) { + fmt.Println("media banned") + http.Redirect(w, r, Domain, http.StatusSeeOther) + return + } + contentType, _ := GetFileContentType(f) if(!SupportedMIMEType(contentType)) { @@ -39,7 +48,7 @@ func ParseOutboxRequest(w http.ResponseWriter, r *http.Request, db *sql.DB) { return } } - + var nObj = CreateObject("Note") nObj = ObjectFromForm(r, db, nObj) @@ -339,7 +348,6 @@ func ObjectFromForm(r *http.Request, db *sql.DB, obj ObjectBase) ObjectBase { err := cmd.Run() CheckError(err, "error with removing exif data from image") - } obj.Preview = CreatePreviewObject(obj.Attachment[0]) @@ -617,3 +625,32 @@ func MakeActivityFollowingReq(w http.ResponseWriter, r *http.Request, activity A return false } + +func IsMediaBanned(db *sql.DB, f multipart.File) bool { + f.Seek(0, 0) + + fileBytes, _ := ioutil.ReadAll(f) + + hash := HashBytes(fileBytes) + + f.Seek(0, 0) + + query := `select hash from bannedmedia where hash=$1` + + rows, err := db.Query(query, hash) + + CheckError(err, "could not get hash from banned media in db") + + var h string + + defer rows.Close() + + rows.Next() + rows.Scan(&h) + + if h == hash { + return true + } + + return false +} diff --git a/static/posts.html b/static/posts.html index b638a10..d7f46b9 100644 --- a/static/posts.html +++ b/static/posts.html @@ -12,7 +12,8 @@ <a href="/delete?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Post]</a> {{ end }} {{ if .Attachment }} - {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + <a href="/banmedia?id={{ .Id }}&board={{ $board.Actor.Name }}">[Ban Media]</a> <a href="/deleteattach?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Attachment]</a> <a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">[Mark Sensitive]</a> {{ end }} @@ -41,7 +42,6 @@ sensitive.style = "display: block" media.style = "display: none;" } - </script> {{ end }} <span style="color: #0f0c5d;"><b>{{ .Name }}</b></span><span style="color: #117743;"><b>{{ if .AttributedTo }} {{.AttributedTo }} {{ else }} Anonymous {{ end }}</b></span><span class="tripcode"> {{ .TripCode }} </span><span>{{ .Published }} <a id="{{ .Id }}-anchor" href="/{{ $board.Name }}/{{ short $board.Actor.Outbox $opId }}#{{ short $board.Actor.Outbox .Id }}">No.</a> <a id="{{ .Id }}-link" title="{{ .Id }}" href="javascript:quote('{{ $board.Actor.Id }}', '{{ $opId }}', '{{ .Id }}')">{{ short $board.Actor.Outbox .Id }}</a> {{ if ne .Type "Tombstone" }}<a href="javascript:report('{{ $board.Actor.Id }}', '{{ .Id }}')">[Report]</a>{{ end }}</span> @@ -62,9 +62,10 @@ <a href="/delete?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Post]</a> {{ end }} {{ if .Attachment }} - {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + {{ if eq $board.ModCred $board.Domain $board.Actor.Id }} + <a href="/banmedia?id={{ .Id }}&board={{ $board.Actor.Name }}">[Ban Media]</a> <a href="/deleteattach?id={{ .Id }}&board={{ $board.Actor.Name }}">[Delete Attachment]</a> - <a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">[Mark Sensitive]</a> + <a href="/marksensitive?id={{ .Id }}&board={{ $board.Actor.Name }}">[Mark Sensitive]</a> {{ end }} <span style="display: block;">File <a id="{{ .Id }}-img" href="{{ proxy (index .Attachment 0).Href}}">{{ (index .Attachment 0).Name }}</a> <span id="{{ .Id }}-size">({{ (index .Attachment 0).Size }})</span></span> <div id="hide-{{ .Id }}" style="display: none;">[Hide]</div> |