package api import ( "errors" "golang.org/x/crypto/bcrypt" "log" "github.com/gofiber/fiber/v2" _ "github.com/mattn/go-sqlite3" sq "github.com/Masterminds/squirrel" "github.com/gofiber/fiber/v2/middleware/session" "MY/webapp/data" "MY/webapp/config" . "MY/webapp/common" ) func IsAdmin(user *data.User) bool { return user.Username == config.Settings.Admin } func CheckAuthed(c *fiber.Ctx, needs_admin bool) (*session.Session, error) { sess, err := STORE.Get(c) if err != nil { return sess, err } // BUG: this has to come from the databse, just temporary admin := sess.Get("admin") == true authed := sess.Get("authenticated") == true log.Printf("session admin=%v, session authed=%v, needs_admin = %v", admin, authed, needs_admin) if needs_admin { authed = admin && authed log.Printf("after needs_admin block: authed=%v", authed) } if authed { log.Println("user is authed, return nil and sess") return sess, nil } else { log.Println("user is NOT authed, return error") return sess, errors.New("Authentication, permission failure") } } func LogoutUser(c *fiber.Ctx) error { sess, err := STORE.Get(c) if err != nil { return err } sess.Set("authenticated", false) err = sess.Save() return err } func LoginUser(result *data.User, login *data.Login) (bool, error) { sql, args, err := sq.Select("username, password"). From("user").Where("username=?", login.Username).ToSql() if err != nil { return false, err } err = data.DB.Get(result, sql, args...) if err != nil { return false, err } pass_good := bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(login.Password)) if pass_good != nil { return false, pass_good } return login.Username == result.Username && pass_good == nil, nil } func SetUserPassword(user *data.User) error { hashed, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12) if err != nil { return err } user.Password = string(hashed) return nil } func GetApiLogout(c *fiber.Ctx) error { err := LogoutUser(c) if err != nil { return IfErrNil(err, c) } return c.Redirect("/") } func PostApiRegister(c *fiber.Ctx) error { user, err := ReceivePost[data.User](c) if err != nil { return IfErrNil(err, c) } err = SetUserPassword(user) if err != nil { return IfErrNil(err, c) } sql, args, err := sq.Insert("user"). Columns("username", "email", "password"). Values(user.Username, user.Email, user.Password).ToSql() err = data.Exec(err, sql, args...) if err != nil { return IfErrNil(err, c) } return c.Redirect("/login/") } func PostApiLogin(c *fiber.Ctx) error { var user data.User login, err := ReceivePost[data.Login](c) if(err != nil) { return IfErrNil(err, c) } pass_good, err := LoginUser(&user, login) if err != nil { return IfErrNil(err, c) } if pass_good { sess, err := STORE.Get(c) if err != nil { return IfErrNil(err, c) } sess.Set("authenticated", true) sess.Set("user_id", user.Id) sess.Set("admin", IsAdmin(&user)) err = sess.Save() if err != nil { return IfErrNil(err, c) } return c.Redirect("/") } else { return c.Redirect("/login/") } }