Merge branch 'main' of https://git.disbaidu.com/maxwell/testfb
This commit is contained in:
commit
244c701519
@ -1,29 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
ErrInvalidPassword string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
ErrInvalidPassword: "Invalid password",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
ErrInvalidPassword string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
ErrInvalidPassword: "Invalid password",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
const (
|
|
||||||
ErrInvalidPassword = "invalid password",
|
|
||||||
)
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ErrInvalidPassword = "invalid password"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
DBConnString string
|
|
||||||
RedisAddr string
|
|
||||||
JWTSecret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
|
||||||
RedisAddr: "localhost:6379",
|
|
||||||
JWTSecret: "your-secret-key",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func InitRedis(addr string) *redis.Storage {
|
|
||||||
return redis.New(redis.Config{
|
|
||||||
Host: addr,
|
|
||||||
Port: 6379,
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Database: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"testfb/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Login(db *gorm.DB, redisClient *redis.Storage) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
var input struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.BodyParser(&input); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
|
||||||
}
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.Where("username = ?", input.Username).First(&user).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := user.ComparePassword(input.Password); err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
|
||||||
}
|
|
||||||
|
|
||||||
token := jwt.New(jwt.SigningMethodHS256)
|
|
||||||
claims := token.Claims.(jwt.MapClaims)
|
|
||||||
claims["user_id"] = user.ID
|
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
|
||||||
|
|
||||||
t, err := token.SignedString([]byte("your-secret-key"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert user.ID to string before storing in Redis
|
|
||||||
userIDStr := strconv.FormatUint(uint64(user.ID), 10)
|
|
||||||
err = redisClient.Set(t, []byte(userIDStr), 24*time.Hour)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(fiber.Map{"token": t})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCurrentUser(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
userID := c.Locals("user_id").(uint)
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, userID).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateCurrentUser(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
userID := c.Locals("user_id").(uint)
|
|
||||||
|
|
||||||
var input models.User
|
|
||||||
if err := c.BodyParser(&input); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
|
||||||
}
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, userID).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
user.Email = input.Email
|
|
||||||
user.Phone = input.Phone
|
|
||||||
|
|
||||||
if err := db.Save(&user).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not update user"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserByID(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
id := c.Params("id")
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, id).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
|
|
||||||
"testfb/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Login(db *gorm.DB, redisClient *redis.Storage) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
var input struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.BodyParser(&input); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
|
||||||
}
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.Where("username = ?", input.Username).First(&user).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
|
||||||
}
|
|
||||||
|
|
||||||
// if err := user.ComparePassword(input.Password); err != nil {
|
|
||||||
if err := user.ComparePassword(input.Password); err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
|
||||||
}
|
|
||||||
|
|
||||||
token := jwt.New(jwt.SigningMethodHS256)
|
|
||||||
claims := token.Claims.(jwt.MapClaims)
|
|
||||||
claims["user_id"] = user.ID
|
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
|
||||||
|
|
||||||
t, err := token.SignedString([]byte("your-secret-key"))
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert user.ID to string before storing in Redis
|
|
||||||
userIDStr := strconv.FormatUint(uint64(user.ID), 10)
|
|
||||||
err = redisClient.Set(t, []byte(userIDStr), 24*time.Hour)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(fiber.Map{"token": t})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetCurrentUser(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
userID := c.Locals("user_id").(uint)
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, userID).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateCurrentUser(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
userID := c.Locals("user_id").(uint)
|
|
||||||
|
|
||||||
var input models.User
|
|
||||||
if err := c.BodyParser(&input); err != nil {
|
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
|
||||||
}
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, userID).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
user.Email = input.Email
|
|
||||||
user.Phone = input.Phone
|
|
||||||
|
|
||||||
if err := db.Save(&user).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not update user"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserByID(db *gorm.DB) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
id := c.Params("id")
|
|
||||||
|
|
||||||
var user models.User
|
|
||||||
if err := db.First(&user, id).Error; err != nil {
|
|
||||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AuthMiddleware(redisClient *redis.Storage) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
token := c.Get("Authorization")
|
|
||||||
if token == "" {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
userIDBytes, err := redisClient.Get(token)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
userIDStr := string(userIDBytes)
|
|
||||||
userID, err := strconv.ParseUint(userIDStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Invalid user ID format"})
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Locals("user_id", uint(userID))
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
|
||||||
"github.com/gofiber/storage/redis/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AuthMiddleware(redisClient *redis.Storage) fiber.Handler {
|
|
||||||
return func(c *fiber.Ctx) error {
|
|
||||||
token := c.Get("Authorization")
|
|
||||||
if token == "" {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
userIDBytes, err := redisClient.Get(token)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
|
||||||
}
|
|
||||||
|
|
||||||
userIDStr := string(userIDBytes)
|
|
||||||
userID, err := strconv.ParseUint(userIDStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Invalid user ID format"})
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Locals("user_id", uint(userID))
|
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "testfb/config"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "testfb/config"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
return ErrInvalidPassword
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
err := "Invalid password"
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password != password {
|
|
||||||
err := 123
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password == password {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password == password {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID uint `gorm:"primarykey" json:"id"`
|
|
||||||
Username string `gorm:"unique" json:"username"`
|
|
||||||
Password string `json:"-"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
|
||||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Password = string(hashedPassword)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) ComparePassword(password string) error {
|
|
||||||
//直接比较密码,不用bcrypt
|
|
||||||
if u.Password == password {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# TestFB
|
# TestFB
|
||||||
> 使用Go语言,实现用户登录、获取用户信息、修改用户信息。
|
> 使用Go语言,实现用户登录、获取用户信息、修改用户信息。
|
||||||
|
test123
|
||||||
## 工程要求:结构化工程,更加规范的代码编写。
|
## 工程要求:结构化工程,更加规范的代码编写。
|
||||||
## 工程使用的模块或技术:
|
## 工程使用的模块或技术:
|
||||||
1. Go语言
|
1. Go语言
|
||||||
|
|||||||
6
app.log
Normal file
6
app.log
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[16:24:09] 401 - 193.040931ms POST /login
|
||||||
|
[16:24:20] 401 - 198.309132ms POST /login
|
||||||
|
[16:24:25] 401 - 194.157634ms POST /login
|
||||||
|
[16:24:40] 401 - 3.850798ms POST /login
|
||||||
|
[16:24:45] 401 - 182.36815ms POST /login
|
||||||
|
[16:25:04] 401 - 194.986562ms POST /login
|
||||||
@ -13,7 +13,7 @@ type Config struct {
|
|||||||
func New() *Config {
|
func New() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
DBConnString: "root:password@tcp(localhost:3306)/testfb?charset=utf8mb4&parseTime=True&loc=Local",
|
||||||
RedisAddr: "localhost:6379",
|
RedisAddr: "localhost",
|
||||||
JWTSecret: "your-secret-key",
|
JWTSecret: "your-secret-key",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user