diff options
-rwxr-xr-x | .githooks/pre-commit | 12 | ||||
-rw-r--r-- | client.go | 230 | ||||
-rw-r--r-- | db/boards.go | 64 | ||||
-rw-r--r-- | db/redis.go (renamed from session.go) | 60 | ||||
-rw-r--r-- | db/report.go | 138 | ||||
-rw-r--r-- | main.go | 32 | ||||
-rw-r--r-- | routes/index.go | 16 | ||||
-rw-r--r-- | routes/structs.go | 45 | ||||
-rw-r--r-- | routes/util.go | 3 | ||||
-rw-r--r-- | util/util.go | 14 |
10 files changed, 322 insertions, 292 deletions
diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 7fda0a3..9e91920 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,14 +1,22 @@ #!/bin/sh -# This hook formats every Go file with `go fmt` before committing them. -# It helps to enforce the Go style guide for those who forget to format their code properly. +# This hook formats every Go file before committing them. +# It helps to enforce a consistent style guide for those who forget to format their code properly. STAGED="$(git diff --cached --name-only -- '*.go')" + if [ -n "$STAGED" ]; then for file in $STAGED; do + if [ ! -e "$file" ]; then + # file doesn't exist, skip + continue + fi + + # format the file go fmt "$file" # run goimports if it's there + # it organizes imports if command -v goimports >/dev/null 2>&1; then goimports -w "$file" fi @@ -7,7 +7,6 @@ import ( "log" "net/http" "regexp" - "sort" "strconv" "strings" "time" @@ -18,79 +17,6 @@ import ( var Key *string = new(string) -var FollowingBoards []ObjectBase - -var Boards []Board - -type Board struct { - Name string - Actor Actor - Summary string - PrefName string - InReplyTo string - Location string - To string - RedirectTo string - Captcha string - CaptchaCode string - ModCred string - Domain string - TP string - Restricted bool - Post ObjectBase -} - -type PageData struct { - Title string - PreferredUsername string - Board Board - Pages []int - CurrentPage int - TotalPage int - Boards []Board - Posts []ObjectBase - Key string - PostId string - Instance Actor - InstanceIndex []ObjectBase - ReturnTo string - NewsItems []NewsItem - BoardRemainer []int - - Themes *[]string - ThemeCookie string -} - -type AdminPage struct { - Title string - Board Board - Key string - Actor string - Boards []Board - Following []string - Followers []string - Reported []Report - Domain string - IsLocal bool - PostBlacklist []PostBlacklist - AutoSubscribe bool - - Themes *[]string - ThemeCookie string -} - -type Report struct { - ID string - Count int - Reason string -} - -type Removed struct { - ID string - Type string - Board string -} - func mod(i, j int) bool { return i%j == 0 } @@ -438,27 +364,6 @@ func PostGet(c *fiber.Ctx) error { }, "layouts/main") } -func GetBoardCollection(db *sql.DB) []Board { - var collection []Board - for _, e := range FollowingBoards { - var board Board - boardActor := GetActorFromDB(db, e.Id) - if boardActor.Id == "" { - boardActor = FingerActor(e.Id) - } - board.Name = boardActor.Name - board.PrefName = boardActor.PreferredUsername - board.Location = "/" + boardActor.Name - board.Actor = boardActor - board.Restricted = boardActor.Restricted - collection = append(collection, board) - } - - sort.Sort(BoardSortAsc(collection)) - - return collection -} - func WantToServePage(db *sql.DB, actorName string, page int) (Collection, bool) { var collection Collection @@ -531,135 +436,6 @@ func GetCaptchaCode(captcha string) string { return code } -func CreateLocalDeleteDB(db *sql.DB, id string, _type string) { - query := `select id from removed where id=$1` - - rows, err := db.Query(query, id) - - CheckError(err, "could not query removed") - - defer rows.Close() - - if rows.Next() { - var i string - - rows.Scan(&i) - - if i != "" { - query := `update removed set type=$1 where id=$2` - - _, err := db.Exec(query, _type, id) - - CheckError(err, "Could not update removed post") - - } - } else { - query := `insert into removed (id, type) values ($1, $2)` - - _, err := db.Exec(query, id, _type) - - CheckError(err, "Could not insert removed post") - } -} - -func GetLocalDeleteDB(db *sql.DB) []Removed { - var deleted []Removed - - query := `select id, type from removed` - - rows, err := db.Query(query) - - CheckError(err, "could not query removed") - - defer rows.Close() - - for rows.Next() { - var r Removed - - rows.Scan(&r.ID, &r.Type) - - deleted = append(deleted, r) - } - - return deleted -} - -func CreateLocalReportDB(db *sql.DB, id string, board string, reason string) { - query := `select id, count from reported where id=$1 and board=$2` - - rows, err := db.Query(query, id, board) - - CheckError(err, "could not query reported") - - defer rows.Close() - - if rows.Next() { - var i string - var count int - - rows.Scan(&i, &count) - - if i != "" { - count = count + 1 - query := `update reported set count=$1 where id=$2` - - _, err := db.Exec(query, count, id) - - CheckError(err, "Could not update reported post") - } - } else { - query := `insert into reported (id, count, board, reason) values ($1, $2, $3, $4)` - - _, err := db.Exec(query, id, 1, board, reason) - - CheckError(err, "Could not insert reported post") - } - -} - -func GetLocalReportDB(db *sql.DB, board string) []Report { - var reported []Report - - query := `select id, count, reason from reported where board=$1` - - rows, err := db.Query(query, board) - - CheckError(err, "could not query reported") - - defer rows.Close() - - for rows.Next() { - var r Report - - rows.Scan(&r.ID, &r.Count, &r.Reason) - - reported = append(reported, r) - } - - return reported -} - -func CloseLocalReportDB(db *sql.DB, id string, board string) { - query := `delete from reported where id=$1 and board=$2` - - _, err := db.Exec(query, id, board) - - CheckError(err, "Could not delete local report from db") -} - -func GetActorFollowNameFromPath(path string) string { - var actor string - - re := regexp.MustCompile("f\\w+-") - - actor = re.FindString(path) - - actor = strings.Replace(actor, "f", "", 1) - actor = strings.Replace(actor, "-", "", 1) - - return actor -} - func GetActorsFollowFromName(actor Actor, name string) []string { var followingActors []string follow := GetActorCollection(actor.Following) @@ -689,12 +465,6 @@ func GetActorsFollowPostFromId(db *sql.DB, actors []string, id string) Collectio return collection } -type BoardSortAsc []Board - -func (a BoardSortAsc) Len() int { return len(a) } -func (a BoardSortAsc) Less(i, j int) bool { return a[i].Name < a[j].Name } -func (a BoardSortAsc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - func MediaProxy(url string) string { re := regexp.MustCompile("(.+)?" + Domain + "(.+)?") diff --git a/db/boards.go b/db/boards.go new file mode 100644 index 0000000..b54ab60 --- /dev/null +++ b/db/boards.go @@ -0,0 +1,64 @@ +package db + +import ( + "sort" + + "github.com/FChannel0/FChannel-Server/activitypub" + "github.com/FChannel0/FChannel-Server/webfinger" +) + +var Boards []Board +var FollowingBoards []activitypub.ObjectBase + +type Board struct { + Name string + Actor activitypub.Actor + Summary string + PrefName string + InReplyTo string + Location string + To string + RedirectTo string + Captcha string + CaptchaCode string + ModCred string + Domain string + TP string + Restricted bool + Post activitypub.ObjectBase +} + +type BoardSortAsc []Board + +func (a BoardSortAsc) Len() int { return len(a) } +func (a BoardSortAsc) Less(i, j int) bool { return a[i].Name < a[j].Name } +func (a BoardSortAsc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +func GetBoardCollection() ([]Board, error) { + var collection []Board + for _, e := range FollowingBoards { + var board Board + boardActor, err := GetActorFromDB(e.Id) + if err != nil { + return collection, err + } + + if boardActor.Id == "" { + boardActor, err = webfinger.FingerActor(e.Id) + if err != nil { + return collection, err + } + } + + board.Name = boardActor.Name + board.PrefName = boardActor.PreferredUsername + board.Location = "/" + boardActor.Name + board.Actor = boardActor + board.Restricted = boardActor.Restricted + collection = append(collection, board) + } + + sort.Sort(BoardSortAsc(collection)) + + return collection, nil +} @@ -1,27 +1,28 @@ -package main +package db import ( "bufio" "fmt" "net/http" "os" - "strings" + "github.com/FChannel0/FChannel-Server/config" "github.com/gomodule/redigo/redis" ) -var cache redis.Conn +var Cache redis.Conn -func InitCache() { - conn, err := redis.DialURL(GetConfigValue("redis", "redis://localhost")) - if err != nil { - panic(err) - } - cache = conn +func InitCache() error { + conn, err := redis.DialURL(config.Redis) + Cache = conn + return err } -func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { +func CloseCache() error { + return Cache.Close() +} +func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { c, err := r.Cookie("session_token") if err != nil { @@ -36,7 +37,7 @@ func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { sessionToken := c.Value - response, err := cache.Do("GET", sessionToken) + response, err := Cache.Do("GET", sessionToken) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -50,11 +51,11 @@ func CheckSession(w http.ResponseWriter, r *http.Request) (interface{}, error) { return response, nil } -func GetClientKey() string { +func GetClientKey() (string, error) { file, err := os.Open("clientkey") - - CheckError(err, "could not open client key in file") - + if err != nil { + return "", err + } defer file.Close() scanner := bufio.NewScanner(file) @@ -63,32 +64,5 @@ func GetClientKey() string { line = fmt.Sprintf("%s", scanner.Text()) } - return line -} - -func GetPasswordFromSession(r *http.Request) (string, string) { - - c, err := r.Cookie("session_token") - - if err != nil { - return "", "" - } - - sessionToken := c.Value - - response, err := cache.Do("GET", sessionToken) - - if CheckError(err, "could not get session from cache") != nil { - return "", "" - } - - token := fmt.Sprintf("%s", response) - - parts := strings.Split(token, "|") - - if len(parts) > 1 { - return parts[0], parts[1] - } - - return "", "" + return line, nil } diff --git a/db/report.go b/db/report.go index 4fcb806..a64c94f 100644 --- a/db/report.go +++ b/db/report.go @@ -1,5 +1,17 @@ package db +type Report struct { + ID string + Count int + Reason string +} + +type Removed struct { + ID string + Type string + Board string +} + func DeleteReportActivity(id string) error { query := `delete from reported where id=$1` @@ -54,3 +66,129 @@ func ReportActivity(id string, reason string) (bool, error) { return true, nil } + +func CreateLocalDeleteDB(id string, _type string) error { + query := `select id from removed where id=$1` + + rows, err := db.Query(query, id) + if err != nil { + return err + } + defer rows.Close() + + if rows.Next() { + var i string + + if err := rows.Scan(&i); err != nil { + return err + } + + if i != "" { + query := `update removed set type=$1 where id=$2` + + if _, err := db.Exec(query, _type, id); err != nil { + return err + } + } + } else { + query := `insert into removed (id, type) values ($1, $2)` + + if _, err := db.Exec(query, id, _type); err != nil { + return err + } + } + + return nil +} + +func GetLocalDeleteDB() ([]Removed, error) { + var deleted []Removed + + query := `select id, type from removed` + + rows, err := db.Query(query) + if err != nil { + return deleted, err + } + + defer rows.Close() + + for rows.Next() { + var r Removed + + if err := rows.Scan(&r.ID, &r.Type); err != nil { + return deleted, err + } + + deleted = append(deleted, r) + } + + return deleted, nil +} + +func CreateLocalReportDB(id string, board string, reason string) error { + query := `select id, count from reported where id=$1 and board=$2` + + rows, err := db.Query(query, id, board) + if err != nil { + return err + } + defer rows.Close() + + if rows.Next() { + var i string + var count int + + if err := rows.Scan(&i, &count); err != nil { + return err + } + + if i != "" { + count = count + 1 + query := `update reported set count=$1 where id=$2` + + if _, err := db.Exec(query, count, id); err != nil { + return err + } + } + } else { + query := `insert into reported (id, count, board, reason) values ($1, $2, $3, $4)` + + if _, err := db.Exec(query, id, 1, board, reason); err != nil { + return err + } + } + + return nil +} + +func GetLocalReportDB(board string) ([]Report, error) { + var reported []Report + + query := `select id, count, reason from reported where board=$1` + + rows, err := db.Query(query, board) + if err != nil { + return reported, err + } + defer rows.Close() + + for rows.Next() { + var r Report + + if err := rows.Scan(&r.ID, &r.Count, &r.Reason); err != nil { + return reported, err + } + + reported = append(reported, r) + } + + return reported, nil +} + +func CloseLocalReportDB(id string, board string) error { + query := `delete from reported where id=$1 and board=$2` + + _, err := db.Exec(query, id, board) + return err +} @@ -44,34 +44,46 @@ func init() { } func main() { + var err error CreatedNeededDirectories() - InitCache() - db.ConnectDB() defer db.Close() + db.InitCache() + defer db.CloseCache() + db.RunDatabaseSchema() go MakeCaptchas(DB, 100) - *Key = util.CreateKey(32) + config.Key = util.CreateKey(32) - FollowingBoards = GetActorFollowingDB(DB, Domain) + db.FollowingBoards, err = db.GetActorFollowingDB(config.Domain) + if err != nil { + panic(err) + } go StartupArchive(DB) go CheckInactive(DB) - Boards = GetBoardCollection(DB) + db.Boards, err = db.GetBoardCollection() + if err != nil { + panic(err) + } // root actor is used to follow remote feeds that are not local //name, prefname, summary, auth requirements, restricted - if GetConfigValue("instancename", "") != "" { - CreateNewBoardDB(DB, *CreateNewActor("", GetConfigValue("instancename", ""), GetConfigValue("instancesummary", ""), authReq, false)) - if PublicIndexing == "true" { - AddInstanceToIndex(Domain) + if config.InstanceName != "" { + if _, err = db.CreateNewBoardDB(*CreateNewActor("", config.InstanceName, config.InstanceSummary, authReq, false)); err != nil { + panic(err) + } + + if config.PublicIndexing == "true" { + // TODO: comment out later + //AddInstanceToIndex(config.Domain) } } @@ -83,7 +95,7 @@ func main() { for _, f := range themes { if e := path.Ext(f.Name()); e == ".css" { - Themes = append(Themes, strings.TrimSuffix(f.Name(), e)) + config.Themes = append(config.Themes, strings.TrimSuffix(f.Name(), e)) } } diff --git a/routes/index.go b/routes/index.go index df10d9f..a130796 100644 --- a/routes/index.go +++ b/routes/index.go @@ -3,11 +3,12 @@ package routes import ( "github.com/FChannel0/FChannel-Server/config" "github.com/FChannel0/FChannel-Server/db" + "github.com/FChannel0/FChannel-Server/webfinger" "github.com/gofiber/fiber/v2" ) func Index(c *fiber.Ctx) error { - actor, err := db.GetActor(config.Domain) + actor, err := db.GetActorFromDB(config.Domain) if err != nil { return err } @@ -15,11 +16,11 @@ func Index(c *fiber.Ctx) error { var data PageData data.Title = "Welcome to " + actor.PreferredUsername data.PreferredUsername = actor.PreferredUsername - data.Boards = Boards + data.Boards = db.Boards data.Board.Name = "" - data.Key = *Key + data.Key = config.Key data.Board.Domain = config.Domain - data.Board.ModCred, _ = GetPasswordFromCtx(c) + data.Board.ModCred, _ = getPassword(c) data.Board.Actor = actor data.Board.Post.Actor = actor.Id data.Board.Restricted = actor.Restricted @@ -30,7 +31,10 @@ func Index(c *fiber.Ctx) error { data.BoardRemainer = make([]int, 0) } - col := GetCollectionFromReq("https://fchan.xyz/followers") + col, err := webfinger.GetCollectionFromReq("https://fchan.xyz/followers") + if err != nil { + return err + } if len(col.Items) > 0 { data.InstanceIndex = col.Items @@ -41,7 +45,7 @@ func Index(c *fiber.Ctx) error { return err } - data.Themes = &Themes + data.Themes = &config.Themes data.ThemeCookie = getThemeCookie(c) diff --git a/routes/structs.go b/routes/structs.go new file mode 100644 index 0000000..c145a6d --- /dev/null +++ b/routes/structs.go @@ -0,0 +1,45 @@ +package routes + +import ( + "github.com/FChannel0/FChannel-Server/activitypub" + "github.com/FChannel0/FChannel-Server/db" +) + +type PageData struct { + Title string + PreferredUsername string + Board db.Board + Pages []int + CurrentPage int + TotalPage int + Boards []db.Board + Posts []activitypub.ObjectBase + Key string + PostId string + Instance activitypub.Actor + InstanceIndex []activitypub.ObjectBase + ReturnTo string + NewsItems []db.NewsItem + BoardRemainer []int + + Themes *[]string + ThemeCookie string +} + +type AdminPage struct { + Title string + Board db.Board + Key string + Actor string + Boards []db.Board + Following []string + Followers []string + Reported []db.Report + Domain string + IsLocal bool + PostBlacklist []db.PostBlacklist + AutoSubscribe bool + + Themes *[]string + ThemeCookie string +} diff --git a/routes/util.go b/routes/util.go index 37639c3..a38e969 100644 --- a/routes/util.go +++ b/routes/util.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/FChannel0/FChannel-Server/db" "github.com/gofiber/fiber/v2" ) @@ -22,7 +23,7 @@ func getPassword(r *fiber.Ctx) (string, string) { sessionToken := c - response, err := cache.Do("GET", sessionToken) + response, err := db.Cache.Do("GET", sessionToken) if err != nil { return "", "" } diff --git a/util/util.go b/util/util.go index 4ac8267..5ee548e 100644 --- a/util/util.go +++ b/util/util.go @@ -2,6 +2,7 @@ package util import ( "regexp" + "strings" ) func IsOnion(url string) bool { @@ -49,3 +50,16 @@ func GetActorInstance(path string) (string, string) { return "", "" } + +func GetActorFollowNameFromPath(path string) string { + var actor string + + re := regexp.MustCompile("f\\w+-") + + actor = re.FindString(path) + + actor = strings.Replace(actor, "f", "", 1) + actor = strings.Replace(actor, "-", "", 1) + + return actor +} |