From 2566e314e8351ffbceae9a2688d90a5c811d49e5 Mon Sep 17 00:00:00 2001 From: FChannel <=> Date: Fri, 22 Jan 2021 21:12:26 -0800 Subject: client to server conversion --- main.go | 735 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 644 insertions(+), 91 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index be84a4b..60f5701 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import "net/url" import "database/sql" import _ "github.com/lib/pq" import "math/rand" +import "html/template" import "time" import "regexp" import "os/exec" @@ -17,6 +18,8 @@ import "io/ioutil" import "mime/multipart" import "os" import "bufio" +import "io" +import "github.com/gofrs/uuid" var Port = ":" + GetConfigValue("instanceport") var TP = GetConfigValue("instancetp") @@ -31,22 +34,29 @@ var SiteEmailPassword = GetConfigValue("emailpass") var SiteEmailServer = GetConfigValue("emailserver") //mail.fchan.xyz var SiteEmailPort = GetConfigValue("emailport") //587 -type BoardAccess struct { - boards []string -} +var ldjson = "application/ld+json" +var activitystreams = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" func main() { if _, err := os.Stat("./public"); os.IsNotExist(err) { os.Mkdir("./public", 0755) - } + } + + InitCache() db := ConnectDB(); defer db.Close() go MakeCaptchas(db, 100) + + *Key = CreateClientKey() + + following := GetActorFollowingDB(db, Domain) + Boards = &following + // root actor is used to follow remote feeds that are not local //name, prefname, summary, auth requirements, restricted if GetConfigValue("instancename") != "" { @@ -55,7 +65,10 @@ func main() { // Allow access to public media folder fileServer := http.FileServer(http.Dir("./public")) - http.Handle("/public/", http.StripPrefix("/public", neuter(fileServer))) + http.Handle("/public/", http.StripPrefix("/public", neuter(fileServer))) + + javascriptFiles := http.FileServer(http.Dir("./static")) + http.Handle("/static/", http.StripPrefix("/static", neuter(javascriptFiles))) // main routing http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ @@ -79,12 +92,15 @@ func main() { var actorMain bool var actorInbox bool + var actorCatalog bool var actorOutbox bool + var actorPost bool var actorFollowing bool var actorFollowers bool var actorReported bool var actorVerification bool + var accept = r.Header.Get("Accept") if(actor.Id != ""){ if actor.Name == "main" { @@ -96,16 +112,26 @@ func main() { } else { actorMain = (path == "/" + actor.Name) actorInbox = (path == "/" + actor.Name + "/inbox") + actorCatalog = (path == "/" + actor.Name + "/catalog") actorOutbox = (path == "/" + actor.Name + "/outbox") actorFollowing = (path == "/" + actor.Name + "/following") actorFollowers = (path == "/" + actor.Name + "/followers") actorReported = (path == "/" + actor.Name + "/reported") - actorVerification = (path == "/" + actor.Name + "/verification") + actorVerification = (path == "/" + actor.Name + "/verification") + + re := regexp.MustCompile("/" + actor.Name + "/\\w+") + actorPost = re.MatchString(path) } } if mainActor { - GetActorInfo(w, db, Domain) + if accept == activitystreams || accept == ldjson { + GetActorInfo(w, db, Domain) + return + } + + IndexGet(w, r, db) + return } @@ -123,6 +149,7 @@ func main() { if method == "GET" { GetActorOutbox(w, r, db) } else if method == "POST" { + fmt.Println("parsing outbox req") ParseOutboxRequest(w, r, db) } else { w.WriteHeader(http.StatusForbidden) @@ -142,10 +169,29 @@ func main() { } if actorMain { - GetActorInfo(w, db, actor.Id) + if accept == activitystreams || accept == ldjson { + GetActorInfo(w, db, actor.Id) + return + } + + collection, valid := WantToServe(db, actor.Id) + if valid { + OutboxGet(w, r, db, collection) + } + + return + } + + if actorFollowing { + GetActorFollowing(w, db, actor.Id) return } + if actorFollowers { + GetActorFollowers(w, db, actor.Id) + return + } + if actorInbox { if method == "POST" { ParseInboxRequest(w, r, db) @@ -156,6 +202,14 @@ func main() { return } + if actorCatalog { + collection, valid := WantToServe(db, actor.Id) + if valid { + CatalogGet(w, r, db, collection) + } + return + } + if actorOutbox { if method == "GET" { GetActorOutbox(w, r, db) @@ -168,22 +222,12 @@ func main() { return } - if actorFollowing { - GetActorFollowing(w, db, actor.Id) - return - } - - if actorFollowers { - GetActorFollowers(w, db, actor.Id) - return - } - if actorReported { GetActorReported(w, r, db, actor.Id) return } - if actorVerification { + if actorVerification { if method == "POST" { p, _ := url.ParseQuery(r.URL.RawQuery) if len(p["email"]) > 0 { @@ -214,109 +258,518 @@ func main() { } return } + + //catch all + if actorPost { + if accept == activitystreams || accept == ldjson { + GetActorPost(w, db, path) + return + } + + PostGet(w, r, db) + return + } + + w.WriteHeader(http.StatusForbidden) + w.Write([]byte("404 no path")) + + }) + + http.HandleFunc("/post", func(w http.ResponseWriter, r *http.Request){ + + r.ParseMultipartForm(10 << 20) + + file, header, _ := r.FormFile("file") + + if(file != nil && header.Size > (7 << 20)){ + w.Write([]byte("7MB max file size")) + return + } + + if(r.FormValue("inReplyTo") == "" || file == nil) { + if(r.FormValue("comment") == "" && r.FormValue("subject") == ""){ + w.Write([]byte("Comment or Subject required")) + return + } + } + + if(r.FormValue("captcha") == "") { + w.Write([]byte("Captcha required")) + return + } + + b := bytes.Buffer{} + we := multipart.NewWriter(&b) + + if(file != nil){ + var fw io.Writer + + fw, err := we.CreateFormFile("file", header.Filename) + + CheckError(err, "error with form file create") + + _, err = io.Copy(fw, file) + + CheckError(err, "error with form file copy") + } + + reply := ParseCommentForReply(r.FormValue("comment")) + + for key, r0 := range r.Form { + if(key == "captcha") { + err := we.WriteField(key, r.FormValue("captchaCode") + ":" + r.FormValue("captcha")) + CheckError(err, "error with writing field") + }else{ + err := we.WriteField(key, r0[0]) + CheckError(err, "error with writing field") + } + } + + if(r.FormValue("inReplyTo") == "" && reply != ""){ + err := we.WriteField("inReplyTo", reply) + CheckError(err, "error with writing inReplyTo field") + } + + we.Close() + + req, err := http.NewRequest("POST", r.FormValue("sendTo"), &b) + + CheckError(err, "error with post form req") + + req.Header.Set("Content-Type", we.FormDataContentType()) + req.Header.Set("Authorization", "basic: " + *Key) + + resp, err := http.DefaultClient.Do(req) + + CheckError(err, "error with post form resp") + + defer resp.Body.Close() + + if(resp.StatusCode == 200){ + + body, _ := ioutil.ReadAll(resp.Body) + + var obj ObjectBase + obj = ParseOptions(r, obj) + for _, e := range obj.Option { + if(e == "noko" || e == "nokosage"){ + http.Redirect(w, r, TP + "" + Domain + "/" + r.FormValue("boardName") + "/" + string(body) , http.StatusMovedPermanently) + break + } + } + + http.Redirect(w, r, Domain + "/" + r.FormValue("boardName"), http.StatusMovedPermanently) + return + } + + if(resp.StatusCode == 403){ + w.Write([]byte("Wrong Captcha")) + return + } - collection := GetCollectionFromPath(db, Domain + "" + path) - if len(collection.OrderedItems) > 0 { - enc, _ := json.MarshalIndent(collection, "", "\t") - w.Header().Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") - w.Write(enc) + http.Redirect(w, r, Domain + "/" + r.FormValue("boardName"), http.StatusMovedPermanently) + }) + + http.HandleFunc("/" + *Key + "/", func(w http.ResponseWriter, r *http.Request) { + + id, _ := GetPasswordFromSession(r) + + actor := GetActorFromPath(db, r.URL.Path, "/" + *Key + "/") + + if actor.Id == "" { + actor = GetActorFromDB(db, Domain) + } + + if id == "" || (id != actor.Id && id != Domain) { + t := template.Must(template.ParseFiles("./static/verify.html")) + t.Execute(w, "") + return + } + + re := regexp.MustCompile("/" + *Key + "/" + actor.Name + "/follow") + follow := re.MatchString(r.URL.Path) + + re = regexp.MustCompile("/" + *Key + "/" + actor.Name) + manage := re.MatchString(r.URL.Path) + + re = regexp.MustCompile("/" + *Key ) + admin := re.MatchString(r.URL.Path) + + re = regexp.MustCompile("/" + *Key + "/follow" ) + adminFollow := re.MatchString(r.URL.Path) + + if follow || adminFollow { + r.ParseForm() + + var followActivity Activity + + followActivity.AtContext.Context = "https://www.w3.org/ns/activitystreams" + followActivity.Type = "Follow" + var nactor Actor + var obj ObjectBase + followActivity.Actor = &nactor + followActivity.Object = &obj + followActivity.Actor.Id = r.FormValue("actor") + var mactor Actor + followActivity.Object.Actor = &mactor + followActivity.Object.Actor.Id = r.FormValue("follow") + followActivity.To = append(followActivity.To, r.FormValue("follow")) + + enc, _ := json.Marshal(followActivity) + + req, err := http.NewRequest("POST", actor.Outbox, bytes.NewBuffer(enc)) + + CheckError(err, "error with follow req") + + _, pass := GetPasswordFromSession(r) + + req.Header.Set("Authorization", "Basic " + pass) + + req.Header.Set("Content-Type", activitystreams) + + _, err = http.DefaultClient.Do(req) + + CheckError(err, "error with add board follow resp") + + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + + } else if manage && actor.Name != "" { + t := template.Must(template.ParseFiles("./static/main.html", "./static/manage.html")) + + follow := GetActorCollection(actor.Following) + follower := GetActorCollection(actor.Followers) + reported := GetActorCollectionReq(r, actor.Id + "/reported") + + var following []string + var followers []string + var reports []Report + + for _, e := range follow.Items { + following = append(following, e.Id) + } + + for _, e := range follower.Items { + followers = append(followers, e.Id) + } + + for _, e := range reported.Items { + var r Report + r.Count = int(e.Size) + r.ID = e.Id + reports = append(reports, r) + } + + localReports := GetLocalReportDB(db, actor.Name) + + for _, e := range localReports { + var r Report + r.Count = e.Count + r.ID = e.ID + reports = append(reports, r) + } + + var adminData AdminPage + adminData.Following = following + adminData.Followers = followers + adminData.Reported = reports + adminData.Domain = Domain + + var boardCollection []Board + + boardCollection = GetBoardCollection(db) + + adminData.Title = "Manage /" + actor.Name + "/" + adminData.Boards = boardCollection + adminData.Board.Name = actor.Name + adminData.Actor = actor.Id + adminData.Key = *Key + adminData.Board.TP = TP + t.ExecuteTemplate(w, "layout", adminData) + + } else if admin || actor.Id == Domain { + + t := template.Must(template.ParseFiles("./static/main.html", "./static/nadmin.html")) + + actor := GetActor(Domain) + follow := GetActorCollection(actor.Following).Items + follower := GetActorCollection(actor.Followers).Items + + var following []string + var followers []string + + for _, e := range follow { + following = append(following, e.Id) + } + + for _, e := range follower { + followers = append(followers, e.Id) + } + + var adminData AdminPage + adminData.Following = following + adminData.Followers = followers + adminData.Actor = actor.Id + adminData.Key = *Key + adminData.Domain = Domain + adminData.Board.ModCred,_ = GetPasswordFromSession(r) + + var boardCollection []Board + + boardCollection = GetBoardCollection(db) + adminData.Boards = boardCollection + + t.ExecuteTemplate(w, "layout", adminData) + } + }) + + http.HandleFunc("/" + *Key + "/addboard", func(w http.ResponseWriter, r *http.Request) { + + var newActorActivity Activity + var board Actor + r.ParseForm() + + actor := GetActorFromDB(db, Domain) + + var restrict bool + if r.FormValue("restricted") == "True" { + restrict = true } else { - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("404 no path")) + restrict = false } + + board.Name = r.FormValue("name") + board.PreferredUsername = r.FormValue("prefname") + board.Summary = r.FormValue("summary") + board.Restricted = restrict + + newActorActivity.AtContext.Context = "https://www.w3.org/ns/activitystreams" + newActorActivity.Type = "New" + var nactor Actor + var nobj ObjectBase + newActorActivity.Actor = &nactor + newActorActivity.Object = &nobj + newActorActivity.Actor.Id = actor.Id + newActorActivity.Object.Actor = &board + + + enc, _ := json.Marshal(newActorActivity) + + req, err := http.NewRequest("POST", actor.Outbox, bytes.NewBuffer(enc)) + + CheckError(err, "error with add board follow req") + + _, pass := GetPasswordFromSession(r) + req.Header.Set("Authorization", "Basic " + pass) + req.Header.Set("Content-Type", activitystreams) + + resp, err := http.DefaultClient.Do(req) + + CheckError(err, "error with add board follow resp") + + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + + var respActor Actor + + err = json.Unmarshal(body, &respActor) + + CheckError(err, "error getting actor from body in new board") + //update board list with new instances following + if resp.StatusCode == 200 { + var board []ObjectBase + var item ObjectBase + var removed bool = false + + item.Id = respActor.Id + for _, e := range *Boards { + if e.Id != item.Id { + board = append(board, e) + } else { + removed = true + } + } + + if !removed { + board = append(board, item) + } + + *Boards = board + } + + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) }) + http.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request){ + if(r.Method == "POST") { + r.ParseForm() + identifier := r.FormValue("id") + code := r.FormValue("code") + + var verify Verify + verify.Identifier = identifier + verify.Code = code + + j, _ := json.Marshal(&verify) + + req, err := http.NewRequest("POST", Domain + "/auth", bytes.NewBuffer(j)) + + CheckError(err, "error making verify req") + + req.Header.Set("Content-Type", activitystreams) + + resp, err := http.DefaultClient.Do(req) + + CheckError(err, "error getting verify resp") + + defer resp.Body.Close() + + rBody, _ := ioutil.ReadAll(resp.Body) + + body := string(rBody) + + if(resp.StatusCode != 200) { + t := template.Must(template.ParseFiles("./static/verify.html")) + t.Execute(w, "wrong password " + verify.Code) + } else { + + sessionToken, _ := uuid.NewV4() + + _, err := cache.Do("SETEX", sessionToken, "86400", body + "|" + verify.Code) + if err != nil { + t := template.Must(template.ParseFiles("./static/verify.html")) + t.Execute(w, "") + return + } + + http.SetCookie(w, &http.Cookie{ + Name: "session_token", + Value: sessionToken.String(), + Expires: time.Now().Add(60 * 60 * 24 * 7 * time.Second), + }) + + http.Redirect(w, r, "/", http.StatusSeeOther) + } + } else { + t := template.Must(template.ParseFiles("./static/verify.html")) + t.Execute(w, "") + } + }) + http.HandleFunc("/getcaptcha", func(w http.ResponseWriter, r *http.Request){ w.Write([]byte(GetRandomCaptcha(db))) }) http.HandleFunc("/delete", func(w http.ResponseWriter, r *http.Request){ - values := r.URL.Query().Get("id") - - header := r.Header.Get("Authorization") - - auth := strings.Split(header, " ") + id := r.URL.Query().Get("id") + board := r.URL.Query().Get("board") + actor := GetActorFromPath(db, id, "/") + _, auth := GetPasswordFromSession(r) - if len(values) < 1 || !IsIDLocal(db, values) || len(auth) < 2 { + if id == "" || auth == "" { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("")) return } - actor := GetActorFromPath(db, values, "/") - - if !HasAuth(db, auth[1], actor.Id) { + if !HasAuth(db, auth, actor.Id) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("")) return - } + } + + if !IsIDLocal(db, id) { + CreateLocalDeleteDB(db, id, "post") + CloseLocalReportDB(db, id, board) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return + } + var obj ObjectBase - obj.Id = values + obj.Id = id + + count, _ := GetObjectRepliesDBCount(db, obj) - count, _ := GetObjectRepliesDBCount(db, obj) if count == 0 { DeleteObject(db, obj.Id) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return } else { DeleteObjectAndReplies(db, obj.Id) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return } - w.Write([]byte("")) + + + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("")) }) http.HandleFunc("/deleteattach", func(w http.ResponseWriter, r *http.Request){ - values := r.URL.Query().Get("id") - - header := r.Header.Get("Authorization") + id := r.URL.Query().Get("id") - auth := strings.Split(header, " ") + _, auth := GetPasswordFromSession(r) - if len(values) < 1 || !IsIDLocal(db, values) || len(auth) < 2 { + if id == "" || auth == "" { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("")) return } - actor := GetActorFromPath(db, values, "/") + actor := GetActorFromPath(db, id, "/") - if !HasAuth(db, auth[1], actor.Id) { + if !HasAuth(db, auth, actor.Id) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("")) return + } + + if !IsIDLocal(db, id) { + CreateLocalDeleteDB(db, id, "attachment") + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return } - id := values DeleteAttachmentFromFile(db, id) - DeletePreviewFromFile(db, id) - w.Write([]byte("")) + DeletePreviewFromFile(db, id) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) }) http.HandleFunc("/report", func(w http.ResponseWriter, r *http.Request){ id := r.URL.Query().Get("id") close := r.URL.Query().Get("close") - header := r.Header.Get("Authorization") + board := r.URL.Query().Get("board") + actor := GetActorFromPath(db, id, "/") + _, auth := GetPasswordFromSession(r) - auth := strings.Split(header, " ") - if close == "1" { - if !IsIDLocal(db, id) || len(auth) < 2 { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("")) - return - } + fmt.Println(actor.Id) - actor := GetActorFromPath(db, id, "/") + if id == "" || auth == "" { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("")) + return + } - if !HasAuth(db, auth[1], actor.Id) { + if close == "1" { + if !HasAuth(db, auth, actor.Id) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("")) return } + if !IsIDLocal(db, id) { + CloseLocalReportDB(db, id, board) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return + } + reported := DeleteReportActivity(db, id) if reported { - w.Write([]byte("")) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) return } @@ -324,11 +777,17 @@ func main() { w.Write([]byte("")) return } + + if !IsIDLocal(db, id) { + fmt.Println("not local") + CreateLocalReportDB(db, id, board) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) + return + } reported := ReportActivity(db, id) - if reported { - w.Write([]byte("")) + http.Redirect(w, r, r.Header.Get("Referer"), http.StatusSeeOther) return } @@ -336,7 +795,7 @@ func main() { w.Write([]byte("")) }) - http.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request){ + http.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request){ var verify Verify defer r.Body.Close() @@ -358,7 +817,8 @@ func main() { }) fmt.Println("Server for " + Domain + " running on port " + Port) - + + fmt.Println("Mod key: " + *Key) PrintAdminAuth(db) http.ListenAndServe(Port, nil) @@ -543,6 +1003,15 @@ func GetActorInfo(w http.ResponseWriter, db *sql.DB, id string) { w.Write(enc) } +func GetActorPost(w http.ResponseWriter, db *sql.DB, path string) { + collection := GetCollectionFromPath(db, Domain + "" + path) + if len(collection.OrderedItems) > 0 { + enc, _ := json.MarshalIndent(collection, "", "\t") + w.Header().Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") + w.Write(enc) + } +} + func CreateObject(objType string) ObjectBase { var nObj ObjectBase @@ -694,17 +1163,16 @@ func ParseCommentForReplies(comment string) []ObjectBase { return validLinks } - func CheckValidActivity(id string) (Collection, bool) { req, err := http.NewRequest("GET", id, nil) - + if err != nil { fmt.Println("error with request") panic(err) } - req.Header.Set("Accept", "json/application/activity+json") + req.Header.Set("Accept", activitystreams) resp, err := http.DefaultClient.Do(req) @@ -736,14 +1204,20 @@ func GetActor(id string) Actor { var respActor Actor + if id == "" { + return respActor + } + req, err := http.NewRequest("GET", id, nil) CheckError(err, "error with getting actor req") + req.Header.Set("Accept", activitystreams) + resp, err := http.DefaultClient.Do(req) if err != nil { - fmt.Println("error with getting actor resp") + fmt.Println("error with getting actor resp " + id) return respActor } @@ -761,23 +1235,34 @@ func GetActor(id string) Actor { func GetActorCollection(collection string) Collection { var nCollection Collection + if collection == "" { + return nCollection + } + req, err := http.NewRequest("GET", collection, nil) CheckError(err, "error with getting actor collection req " + collection) + req.Header.Set("Accept", activitystreams) + resp, err := http.DefaultClient.Do(req) - CheckError(err, "error with getting actor collection resp " + collection) + if err != nil { + fmt.Println("error with getting actor collection resp " + collection) + return nCollection + } - if resp.StatusCode == 200 { - defer resp.Body.Close() + defer resp.Body.Close() + if resp.StatusCode == 200 { body, _ := ioutil.ReadAll(resp.Body) - err = json.Unmarshal(body, &nCollection) - - CheckError(err, "error getting actor collection from body " + collection) + if len(body) > 0 { + err = json.Unmarshal(body, &nCollection) + + CheckError(err, "error getting actor collection from body " + collection) + } } return nCollection @@ -789,18 +1274,18 @@ func IsValidActor(id string) (Actor, bool) { CheckError(err, "error with valid actor request") - req.Header.Set("Accept", "json/application/activity+json") + req.Header.Set("Accept", activitystreams) resp, err := http.DefaultClient.Do(req) CheckError(err, "error with valid actor response") + defer resp.Body.Close() + if resp.StatusCode == 403 { return respCollection, false; } - defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) err = json.Unmarshal(body, &respCollection) @@ -816,8 +1301,6 @@ func IsValidActor(id string) (Actor, bool) { return respCollection, false; } - - func IsActivityLocal(db *sql.DB, activity Activity) bool { for _, e := range activity.To { if GetActorFromDB(db, e).Id != "" { @@ -839,12 +1322,8 @@ func IsActivityLocal(db *sql.DB, activity Activity) bool { } func IsIDLocal(db *sql.DB, id string) bool { - - if GetActivityFromDB(db, id).OrderedItems != nil { - return true - } - - return false + activity := GetActivityFromDB(db, id) + return len(activity.OrderedItems) > 0 } func IsObjectLocal(db *sql.DB, id string) bool { @@ -995,7 +1474,7 @@ func GetActorReported(w http.ResponseWriter, r *http.Request, db *sql.DB, id str following.Items = GetActorReportedDB(db, id) enc, _ := json.MarshalIndent(following, "", "\t") - w.Header().Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") + w.Header().Set("Content-Type", activitystreams) w.Write(enc) } @@ -1008,11 +1487,13 @@ func MakeActivityRequest(activity Activity) { actor := GetActor(e) if actor.Inbox != "" { - req, err := http.NewRequest("POST", actor.Inbox, bytes.NewBuffer(j)) + req, err := http.NewRequest("POST", actor.Inbox, bytes.NewBuffer(j)) - CheckError(err, "error with sending activity req to") + req.Header.Set("Content-Type", activitystreams) - _, err = http.DefaultClient.Do(req) + CheckError(err, "error with sending activity req to") + + _, err = http.DefaultClient.Do(req) CheckError(err, "error with sending activity resp to") } @@ -1026,6 +1507,8 @@ func GetCollectionFromID(id string) Collection { CheckError(err, "could not get collection from id req") + req.Header.Set("Accept", activitystreams) + resp, err := http.DefaultClient.Do(req) if err != nil { @@ -1052,6 +1535,8 @@ func GetActorFromID(id string) Actor { CheckError(err, "error getting actor from id req") + req.Header.Set("Accept", activitystreams) + resp, err := http.DefaultClient.Do(req) CheckError(err, "error getting actor from id resp") @@ -1088,7 +1573,6 @@ func GetConfigValue(value string) string{ return "" } - func PrintAdminAuth(db *sql.DB){ query := fmt.Sprintf("select identifier, code from boardaccess where board='%s' and type='admin'", Domain) @@ -1114,7 +1598,6 @@ func IsInStringArray(array []string, value string) bool { return false } - func GetUniqueFilename(_type string) string { id := RandomID(8) file := "/public/" + id + "." + _type @@ -1242,3 +1725,73 @@ func UpdateObjectWithPreview(db *sql.DB, id string, preview string) { CheckError(err, "could not update activity stream with preview") } + +func ParseCommentForReply(comment string) string { + + re := regexp.MustCompile("(>>)(https://|http://)?(www\\.)?.+\\/\\w+") + match := re.FindAllStringSubmatch(comment, -1) + + var links []string + + for i:= 0; i < len(match); i++ { + str := strings.Replace(match[i][0], ">>", "", 1) + links = append(links, str) + } + + if(len(links) > 0){ + _, isValid := CheckValidActivity(links[0]) + + if(isValid) { + return links[0] + } + } + + return "" +} + +func GetActorByName(db *sql.DB, name string) Actor { + var actor Actor + for _, e := range *Boards { + boardActor := GetActorFromDB(db, e.Id) + if boardActor.Id == "" { + boardActor = GetRemoteActor(e.Id) + } + + if boardActor.Name == name { + actor = boardActor + } + } + + return actor +} + +func GetActorCollectionReq(r *http.Request, collection string) Collection { + var nCollection Collection + + req, err := http.NewRequest("GET", collection, nil) + + CheckError(err, "error with getting actor collection req " + collection) + + _, pass := GetPasswordFromSession(r) + + req.Header.Set("Accept", activitystreams) + + req.Header.Set("Authorization", "Basic " + pass) + + resp, err := http.DefaultClient.Do(req) + + CheckError(err, "error with getting actor collection resp " + collection) + + if resp.StatusCode == 200 { + + defer resp.Body.Close() + + body, _ := ioutil.ReadAll(resp.Body) + + err = json.Unmarshal(body, &nCollection) + + CheckError(err, "error getting actor collection from body " + collection) + } + + return nCollection +} -- cgit v1.2.3