This is an idea for a Twitter clone for programmers, similar to how Dribbble is twitter for designers. It'll most likely not feature any images other than people's avatars, and no videos, or audio. Just text. 'Cause we're coders.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

125 lines
3.1 KiB

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) }
// BUG: THIS IS A BIG NO NO, just for getting going
sess.Set("authenticated", true)
sess.Set("admin", IsAdmin(&user))
err = sess.Save()
if err != nil { return IfErrNil(err, c) }
return c.Redirect("/")
} else {
return c.Redirect("/login/")
}
}