now users can only view and delete their own posts

This commit is contained in:
drevil 2023-07-02 02:30:02 -04:00
parent b108615af0
commit 92cf109746
2 changed files with 224 additions and 15 deletions

View File

@ -136,6 +136,8 @@ func (c *Comic) readRow(db * sql.Rows) error {
}
func getComic(id int) (*Comic, error) {
id -= 1
c := new(Comic)
nferr := NoSuchComicErr.With(fmt.Sprintf("id \"%d\"", id))
@ -236,7 +238,7 @@ func comicView(w http.ResponseWriter, r * http.Request) {
}
if len(comics) > 0 {
c, err = getComic(i-1)
c, err = getComic(i)
if err != nil {
errlog.Println(err)
return404(w,r)
@ -400,10 +402,19 @@ func return500(w http.ResponseWriter, r * http.Request) {
returnError(w, r, http.StatusInternalServerError)
}
func newComic(title string, image string, description string, tags string) error {
_, err := db.Exec("INSERT INTO comic(title, image, description, tags) VALUES(?, ?, ?, ?);",
func newComic(title string, image string, description string, tags string) (int, error) {
res, err := db.Exec("INSERT INTO comic(title, image, description, tags) VALUES(?, ?, ?, ?);",
title, image, description, tags)
return err
if err != nil {
return -1, nil
}
id := int64(0)
if id, err = res.LastInsertId(); err != nil {
return 0, err
}
return int(id), err
}
func deleteComic(id int) error {
@ -437,7 +448,7 @@ func main() {
if len(options.Title) < 1 {
panic("missing -l")
}
err = newComic(options.Title, options.ImagePath, "", "")
_, err = newComic(options.Title, options.ImagePath, "", "")
if err != nil {
log.Fatal(err)
}

View File

@ -20,9 +20,10 @@ import (
"golang.org/x/crypto/bcrypt"
)
var seededRand *rand.Rand = nil
var secretKey string = ""
var secretKeyHash string = ""
var seededRand *rand.Rand = nil
var secretKey string = ""
var secretKeyHash string = ""
var tokenSecondsDefault = 60 * 60 * 24 * 14
const userSquema string = `
CREATE TABLE IF NOT EXISTS user (
@ -38,6 +39,13 @@ CREATE TABLE IF NOT EXISTS token (
username CHAR(20) NOT NULL
);`
const isAuthorOfSquema string = `
CREATE TABLE IF NOT EXISTS isauthorof (
id INTEGER PRIMARY KEY AUTOINCREMENT,
comicid INT NOT NULL,
userid CHAR(20) NOT NULL
);`
type User struct {
ID string
Name string
@ -63,12 +71,107 @@ type TokenClaims struct {
Username string
}
type IsAuthorOf struct {
ID int
ComicID int
UserID string
}
type ViewHandler func(w http.ResponseWriter, r *http.Request)
func (u *User) byID(id string) error {
rows, err := db.Query("SELECT * FROM user WHERE id = ?;", id)
if err != nil {
return err
}
defer rows.Close()
if !rows.Next() {
return errors.New("no such entry found")
}
return u.readRow(rows)
}
func (a *IsAuthorOf) byComic(id int) error {
rows, err := db.Query("SELECT * FROM isauthorof WHERE comicid = ?;", id)
if err != nil {
return err
}
defer rows.Close()
if !rows.Next() {
return errors.New("no such entry found")
}
return a.readRow(rows)
}
func (c *Comic) getAuthor() (*User, error) {
authorOf := &IsAuthorOf{}
user := &User{}
err := authorOf.byComic(c.ID)
if err != nil {
return nil, err
}
err = user.byID(authorOf.UserID)
if err != nil {
return nil, err
}
return user, nil
}
func (u *User) readRow(db * sql.Rows) error {
return db.Scan(&u.ID, &u.Name, &u.Password)
}
func getComicByID(id int) (*Comic, error) {
comic := &Comic{}
rows, err := db.Query("SELECT * FROM comic WHERE id = ?;", id)
if err != nil {
return nil, err
}
defer rows.Close()
if !rows.Next() {
return nil, errors.New("no such comic found")
}
err = comic.readRow(rows)
if err != nil {
return nil, err
}
return comic, nil
}
func (u *User) getComics() ([]Comic, error) {
authors, err := getAllIsAuthorOfs()
if err != nil {
return nil, err
}
comics := []Comic{}
for _, a := range authors {
if a.UserID != u.ID {
continue
}
c, err := getComicByID(a.ComicID)
if err != nil {
continue
}
comics = append(comics, *c)
}
return comics, nil
}
func (t *TokenClaims) readRow(db * sql.Rows) error {
var e int64
err := db.Scan(&t.ID, &e, &t.Username)
@ -76,6 +179,10 @@ func (t *TokenClaims) readRow(db * sql.Rows) error {
return err
}
func (a *IsAuthorOf) readRow(db *sql.Rows) error {
return db.Scan(&a.ID, &a.ComicID, &a.UserID)
}
func generateToken(username string, seconds time.Duration) (string, *TokenClaims, error) {
claims := TokenClaims{
ID: randomString(20),
@ -221,6 +328,53 @@ func getAllUsers() ([]User, error) {
return users, nil
}
func getAllIsAuthorOfs() ([]IsAuthorOf, error) {
rows, err := db.Query("SELECT * FROM isauthorof ORDER BY id ASC")
if err != nil {
return nil, err
}
defer rows.Close()
authors := []IsAuthorOf{}
for rows.Next() {
i := IsAuthorOf{}
err := i.readRow(rows)
if err != nil {
return nil, err
}
authors = append(authors, i)
}
return authors, nil
}
func addIsAuthorOf(userID string, comicID int) error {
authors, err := getAllIsAuthorOfs()
if err != nil {
return err
}
for _, a := range authors {
if a.ComicID == comicID && a.UserID == userID {
return nil
}
}
_, err = db.Exec("INSERT INTO isauthorof(comicid, userid) VALUES(?, ?);",
comicID, userID)
return err
}
func removeComicFromIsAuthorOf(id int) error {
_, err := db.Exec("DELETE FROM isauthorof WHERE comicid = ?;", id)
return err
}
func removeUserFromIsAuthorOf(id string) error {
_, err := db.Exec("DELETE FROM isauthorof WHERE userid = ?;", id)
return err
}
func randomString(length int) string {
charset := "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789"
b := make([]byte, length)
@ -296,7 +450,6 @@ func athenticateUserByPassword(username string, password string) (*User, error)
return nil, errors.New("No such user \"" + username + "\" found")
}
log.Println(user.ID)
password = saltPassword(password, user.ID)
if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
return nil, err
@ -335,12 +488,12 @@ func managerIndexView(w http.ResponseWriter, r * http.Request) {
User: *user,
}
comics, err := allComics()
comics, err := user.getComics()
if err != nil {
return
}
for i, comic := range comics {
for _, comic := range comics {
context.Comics = append(context.Comics, struct {
No int
Title string
@ -348,7 +501,7 @@ func managerIndexView(w http.ResponseWriter, r * http.Request) {
Image string
}{
Title: comic.Title,
No: i+1,
No: comic.ID,
Date: comic.DateTime,
Image: comic.Image,
})
@ -364,18 +517,39 @@ func managerRemoveView(w http.ResponseWriter, r * http.Request) {
path := strings.TrimRight(tmp, "/confirmed")
isConfirmed := strings.TrimPrefix(strings.TrimPrefix(tmp, path), "/") == "confirmed"
user, _, err := getSessionUser(r)
if err != nil {
log.Println("failed to get session user: " + err.Error())
return401(w, r)
err = nil
return
}
i, err := strconv.Atoi(path)
if err != nil {
return404(w, r)
return
}
comic, err := getComic(i-1)
comic, err := getComicByID(i)
if err != nil {
return404(w, r)
return
}
authorOf := &IsAuthorOf{}
err = authorOf.byComic(i)
if err != nil {
errlog.Println(err)
return500(w, r)
return
}
if authorOf.UserID != user.ID {
return401(w, r)
return
}
if !isConfirmed {
err = executeTemplate(w, "confirm", ConfirmContext{
Action: fmt.Sprintf("Remove %s", comic.Title),
@ -396,6 +570,11 @@ func managerRemoveView(w http.ResponseWriter, r * http.Request) {
return500(w, r)
return
}
err = removeComicFromIsAuthorOf(comic.ID)
if err != nil {
return500(w, r)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
@ -419,6 +598,14 @@ func managerPublishView(w http.ResponseWriter, r * http.Request) {
}
} ()
user, _, err := getSessionUser(r)
if err != nil {
log.Println("failed to get session user: " + err.Error())
return401(w, r)
err = nil
return
}
r.ParseMultipartForm(options.UploadSize * (1 << 20))
file, handler, err := r.FormFile("image")
if err != nil {
@ -440,7 +627,13 @@ func managerPublishView(w http.ResponseWriter, r * http.Request) {
defer f.Close()
io.Copy(f, file)
err = newComic(title, filename, "", "")
comicID, err := newComic(title, filename, "", "")
if err != nil {
return
}
log.Println(user.ID)
err = addIsAuthorOf(user.ID, comicID)
if err != nil {
return
}
@ -478,7 +671,7 @@ func managerLoginView(w http.ResponseWriter, r * http.Request) {
return
}
token, claims, err := generateToken(user.Name, 60)
token, claims, err := generateToken(user.Name, time.Duration(tokenSecondsDefault))
if err != nil {
log.Println(fmt.Sprintf("failed to generate token for \"%s\": %s", user.Name, err.Error()))
return500(w, r)
@ -536,6 +729,11 @@ func startManager(address string, port int, dbPath string, mediaPath string) err
log.Fatal(err)
}
_, err = db.Exec(isAuthorOfSquema)
if err != nil {
log.Fatal(err)
}
_, err = os.Stat(options.SecretPath)
if os.IsNotExist(err) {
secretKey = randomString(100)