Browse Source

Pengen upload lagi

yoga-dev
Seyora24 1 year ago
parent
commit
95ed97d1ba
  1. 182
      controllers/postController.go
  2. 4
      go.mod
  3. 9
      go.sum
  4. 2
      main.go

182
controllers/postController.go

@ -1,8 +1,11 @@
package controllers
import (
"fmt"
"net/http"
"os"
"strconv"
"strings"
"time"
"tugas1/initializers"
"tugas1/models"
@ -10,6 +13,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
func PostsCreate(c *gin.Context) {
@ -116,124 +120,190 @@ func PostsDelete(c *gin.Context) {
// Respond
c.Status(200)
}
func SignUp(c *gin.Context) {
// Get the email/pass of req body
var body struct {
Name string
Email string
Password string
Gender string
Address string
Tempat string
TLahir string
Email string
Password string
Nik string
Name string
Photo string
Birthdate time.Time
JobTitle string
CreatedBy string
UpdatedBy string
DeletedBy string
}
if c.Bind(&body) != nil {
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to read body",
})
return
}
// Hash the password
hash, err := bcrypt.GenerateFromPassword([]byte(body.Password), 10)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to hash password",
"error": "Failed to generate password hash",
})
return
}
// Create the user
user := models.Post{Name: body.Name, Email: body.Email, Password: string(hash), Gender: body.Gender,
Address: body.Address, Tempat: body.Tempat, TLahir: body.TLahir}
user := models.Post{
Email: body.Email,
Password: string(hash),
Nik: body.Nik,
Name: body.Name,
Photo: body.Photo,
Birthdate: body.Birthdate,
JobTitle: body.JobTitle,
LastLoginAt: time.Now(),
CreatedBy: body.Nik,
UpdatedBy: body.Nik,
DeletedBy: body.Nik,
Token: "",
}
result := initializers.DB.Create(&user)
if result.Error != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to create user",
})
return
}
// Respond
updateLoginRecord(c, user.ID, time.Now())
c.JSON(http.StatusOK, gin.H{})
}
func Login(c *gin.Context) {
// Get the email and password for req body
func LogIn(c *gin.Context) {
var body struct {
Name string
Email string
Password string
Gender string
Address string
Tempat string
TLahir string
}
if c.Bind(&body) != nil {
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to read body",
})
return
}
// Look up requested user
var user models.Post
initializers.DB.First(&user, "email = ?", body.Email)
if user.ID == 0 {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid email",
"error": "Invalid email or password",
})
return
}
// Compare sent in password with saved user password hash
err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(body.Password))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid password",
"error": "Invalid email or password",
})
return
}
// Generate a jwt token
user.LastLoginAt = time.Now()
initializers.DB.Save(&user)
updateLoginRecord(c, user.ID, time.Now())
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": user.ID,
"exp": time.Now().Add(time.Hour * 24 * 30).Unix(),
})
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString([]byte(os.Getenv("SECRET")))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to create token",
})
return
}
// Send it back
c.SetSameSite(http.SameSiteLaxMode)
c.SetCookie("Authorization", tokenString, 3600*24*30, "", "", false, true)
c.JSON(http.StatusOK, gin.H{})
c.JSON(http.StatusOK, gin.H{
"token": tokenString,
})
}
func LogOut(c *gin.Context) {
c.SetCookie("Authorization", "", -1, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"message": "Logout successful",
})
}
func Validate(c *gin.Context) {
user, _ := c.Get("user")
c.JSON(http.StatusOK, gin.H{
"message": user,
})
}
func updateLoginRecord(c *gin.Context, userID uint, date time.Time) {
// Cari data rekap login berdasarkan tanggal
var loginRecord models.LoginRecord
result := initializers.DB.Where("login_date = ?", date.Format("2006-01-02")).First(&loginRecord)
if result.Error != nil && result.Error != gorm.ErrRecordNotFound {
return
}
if result.Error == gorm.ErrRecordNotFound {
// Jika belum ada data rekap untuk hari ini, buat data baru
loginRecord = models.LoginRecord{
LoginDate: date,
UserIDs: fmt.Sprintf("%d", userID),
}
initializers.DB.Create(&loginRecord)
} else {
// Jika sudah ada data rekap, cek apakah user sudah login pada hari ini
if !containsInt(loginRecord.UserIDs, userID) {
// Jika user belum login hari ini, tambahkan ID pengguna ke dalam array user_ids
loginRecord.UserIDs = fmt.Sprintf("%s,%d", loginRecord.UserIDs, userID)
initializers.DB.Save(&loginRecord)
}
}
// Ambil data pengguna yang login pada hari ini
var users []models.Post
initializers.DB.Find(&users, "id IN (?)", parseUserIDs(loginRecord.UserIDs))
// Update login record dengan pengguna yang login pada hari ini
loginRecord.Users = users
// Update jumlah pengguna (TotalUsers) saat pengguna baru melakukan login
initializers.DB.Save(&loginRecord)
}
// Helper function to check if an int is present in a slice
func containsInt(slice string, val uint) bool {
ids := parseUserIDs(slice)
for _, item := range ids {
if item == val {
return true
}
}
return false
}
// Helper function to parse user IDs from a string
func parseUserIDs(idsStr string) []uint {
ids := strings.Split(idsStr, ",")
var userIDs []uint
for _, idStr := range ids {
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
continue
}
userIDs = append(userIDs, uint(id))
}
return userIDs
}
func GetLoginRecords(c *gin.Context) {
var loginRecords []models.LoginRecord
result := initializers.DB.Find(&loginRecords)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to fetch login records",
})
return
}
// Retrieve user details for each login record
for i := range loginRecords {
var users []models.Post
initializers.DB.Find(&users, "id IN (?)", parseUserIDs(loginRecords[i].UserIDs))
loginRecords[i].Users = users
}
// Create JSON response
var response struct {
Records []models.LoginRecord `json:"records"`
}
response.Records = loginRecords
c.JSON(http.StatusOK, response)
}

4
go.mod

@ -31,8 +31,12 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/radovskyb/watcher v1.0.7 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/net v0.11.0 // indirect

9
go.sum

@ -67,6 +67,8 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -81,6 +83,12 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@ -94,6 +102,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=

2
main.go

@ -23,7 +23,7 @@ func main() {
r.GET("/posts/:id", controllers.PostsShow)
r.DELETE("/posts/:id", controllers.PostsDelete)
r.POST("/signup", controllers.SignUp)
r.POST("/login", controllers.Login)
r.POST("/login", controllers.LogIn)
r.GET("/validate", middleware.RequireAuth, controllers.Validate)
r.Run()
}

Loading…
Cancel
Save