package logins import ( "database/sql" "encoding/base64" "encoding/hex" "errors" "time" "github.com/biscuit-auth/biscuit-go/v2" "github.com/biscuit-auth/biscuit-go/v2/parser" "gitlab.g3e.fr/h6n/users/lib" "golang.org/x/crypto/bcrypt" ) func CheckPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } func CreateLogin(db *sql.DB, request RequestLogin) (ResponseLogin, error) { type ( User struct { Username string EncryptedPassword string } ) var user User var response ResponseLogin if err := db.QueryRow("SELECT username, password FROM users WHERE email = $1", request.Username).Scan(&user.Username, &user.EncryptedPassword); err != nil { return response, err } if !CheckPasswordHash(request.Password, user.EncryptedPassword) { return response, errors.ErrUnsupported } now := time.Now() ValidateTime := 14 expire := now.AddDate(0, 0, ValidateTime) user_id := string(user.Username) auth := `user("` + user_id + `"); check if time($time), $time <= ` + expire.Format("2006-01-02T15:04:05Z") + `; ` authority, err := parser.FromStringBlockWithParams(auth, map[string]biscuit.Term{"read": biscuit.String("read"), "write": biscuit.String("write")}) if err != nil { return response, err } builder := biscuit.NewBuilder(lib.PrivateKey) if err = builder.AddBlock(authority); err != nil { return response, err } b, err := builder.Build() if err != nil { return response, err } token, err := b.Serialize() if err != nil { return response, err } response.Token = base64.URLEncoding.EncodeToString(token) response.PublicKey = hex.EncodeToString(lib.PublicKey) return response, nil }