Skip to content

Commit

Permalink
feat: add net api
Browse files Browse the repository at this point in the history
  • Loading branch information
lanthora committed Jul 20, 2024
1 parent 272267d commit 6b99a28
Show file tree
Hide file tree
Showing 19 changed files with 1,126 additions and 90 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cacao
sqlite.db
cookie
149 changes: 149 additions & 0 deletions api/net.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package api

import (
"github.com/gin-gonic/gin"
"github.com/lanthora/cacao/candy"
"github.com/lanthora/cacao/model"
"github.com/lanthora/cacao/status"
"github.com/lanthora/cacao/storage"
"gorm.io/gorm"
)

func NetShow(c *gin.Context) {
user := c.MustGet("user").(*model.User)
nets := model.GetNetsByUserID(user.ID)

type netinfo struct {
ID uint `json:"netid"`
Name string `json:"netname"`
Password string `json:"password"`
DHCP string `json:"dhcp"`
Broadcast bool `json:"broadcast"`
}

response := make([]netinfo, 0)
for _, n := range nets {
response = append(response, netinfo{
ID: n.ID,
Name: n.Name,
Password: n.Password,
DHCP: n.DHCP,
Broadcast: n.Broadcast,
})
}

status.UpdateSuccess(c, gin.H{
"nets": response,
})
}

func NetInsert(c *gin.Context) {
var request struct {
Name string `json:"netname"`
Password string `json:"password"`
DHCP string `json:"dhcp"`
Broadcast bool `json:"broadcast"`
}

if err := c.BindJSON(&request); err != nil {
status.UpdateCode(c, status.InvalidRequest)
return
}

user := c.MustGet("user").(*model.User)
modelNet := &model.Net{
UserID: user.ID,
Name: request.Name,
}

db := storage.Get()
result := db.Where(modelNet).Take(modelNet)
if result.Error != gorm.ErrRecordNotFound {
status.UpdateCode(c, status.NetworkAlreadyExists)
return
}

modelNet.Password = request.Password
modelNet.DHCP = request.DHCP
modelNet.Broadcast = request.Broadcast
modelNet.Create()
candy.InsertNet(modelNet)

status.UpdateSuccess(c, gin.H{
"netid": modelNet.ID,
"netname": modelNet.Name,
"password": modelNet.Password,
"dhcp": modelNet.DHCP,
"broadcast": modelNet.Broadcast,
})
}

func NetEdit(c *gin.Context) {
var request struct {
ID uint `json:"netid"`
Name string `json:"netname"`
Password string `json:"password"`
DHCP string `json:"dhcp"`
Broadcast bool `json:"broadcast"`
}

if err := c.BindJSON(&request); err != nil {
status.UpdateCode(c, status.InvalidRequest)
return
}

user := c.MustGet("user").(*model.User)
modelNet := &model.Net{}
modelNet.ID = request.ID
db := storage.Get()
result := db.Where(modelNet).Take(modelNet)

if result.Error != nil || modelNet.UserID != user.ID {
status.UpdateCode(c, status.NetworkNotExists)
return
}

modelNet.Name = request.Name
modelNet.Password = request.Password
modelNet.DHCP = request.DHCP
modelNet.Broadcast = request.Broadcast
modelNet.Update()
candy.UpdateNet(modelNet)

status.UpdateSuccess(c, gin.H{
"netid": modelNet.ID,
"netname": modelNet.Name,
"password": modelNet.Password,
"dhcp": modelNet.DHCP,
"broadcast": modelNet.Broadcast,
})
}

func NetDelete(c *gin.Context) {
var request struct {
ID uint `json:"netid"`
}

if err := c.BindJSON(&request); err != nil {
status.UpdateCode(c, status.InvalidRequest)
return
}

user := c.MustGet("user").(*model.User)
modelNet := &model.Net{}
modelNet.ID = request.ID
db := storage.Get()
result := db.Where(modelNet).Take(modelNet)

if result.Error != nil || modelNet.UserID != user.ID {
status.UpdateCode(c, status.NetworkNotExists)
return
}

modelNet.Delete()
candy.DeleteNet(modelNet.ID)

status.UpdateSuccess(c, gin.H{
"id": modelNet.ID,
})
}
81 changes: 31 additions & 50 deletions user/user.go → api/user.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,18 @@
package user
package api

import (
"crypto/sha256"
"fmt"
"regexp"
"strconv"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/lanthora/cacao/logger"
"github.com/lanthora/cacao/candy"
"github.com/lanthora/cacao/model"
"github.com/lanthora/cacao/status"
"github.com/lanthora/cacao/storage"
"gorm.io/gorm"
)

type User struct {
gorm.Model
Name string `gorm:"uniqueIndex"`
Password string
Token string
Role string
IP string
}

func init() {
db := storage.Get()
err := db.AutoMigrate(User{})
if err != nil {
logger.Fatal("auto migrate users failed: %v", err)
}
}

func isAlphanumeric(s string) bool {
match, _ := regexp.MatchString("^[a-zA-Z0-9]+$", s)
return match
}

func sha256sum(data []byte) string {
hash := sha256.Sum256(data)
return fmt.Sprintf("%x", hash[:])
}

func LoginMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.String()
Expand All @@ -67,7 +37,7 @@ func LoginMiddleware() gin.HandlerFunc {
c.Abort()
return
}
user := &User{}
user := &model.User{}
user.ID = uint(id)

db := storage.Get()
Expand All @@ -82,7 +52,7 @@ func LoginMiddleware() gin.HandlerFunc {
}
}

func Register(c *gin.Context) {
func UserRegister(c *gin.Context) {
var request struct {
Username string `json:"username"`
Password string `json:"password"`
Expand All @@ -91,7 +61,7 @@ func Register(c *gin.Context) {
status.UpdateCode(c, status.InvalidRequest)
return
}
if len(request.Username) < 3 || !isAlphanumeric(request.Username) {
if len(request.Username) < 3 || !candy.IsAlphanumeric(request.Username) {
status.UpdateCode(c, status.InvalidUsername)
return
}
Expand All @@ -103,7 +73,7 @@ func Register(c *gin.Context) {
db := storage.Get()
if func() bool {
count := int64(0)
db.Model(&User{}).Where(&User{IP: c.ClientIP(), Role: "normal"}).Where("created_at > ?", time.Now().Add(-24*time.Hour)).Count(&count)
db.Model(&model.User{}).Where(&model.User{IP: c.ClientIP(), Role: "normal"}).Where("created_at > ?", time.Now().Add(-24*time.Hour)).Count(&count)
return count > 0
}() {
status.UpdateCode(c, status.RegisterTooFrequently)
Expand All @@ -112,7 +82,7 @@ func Register(c *gin.Context) {

if func() bool {
count := int64(0)
db.Model(&User{}).Where(&User{Name: request.Username}).Count(&count)
db.Model(&model.User{}).Where(&model.User{Name: request.Username}).Count(&count)
return count > 0
}() {
status.UpdateCode(c, status.UsernameAlreadyTaken)
Expand All @@ -121,16 +91,16 @@ func Register(c *gin.Context) {

role := func() string {
count := int64(0)
db.Model(&User{}).Count(&count)
db.Model(&model.User{}).Count(&count)
if count == 0 {
return "admin"
}
return "normal"
}()

user := User{
user := model.User{
Name: request.Username,
Password: sha256sum([]byte(request.Password)),
Password: candy.Sha256sum([]byte(request.Password)),
Token: uuid.NewString(),
Role: role,
IP: c.ClientIP(),
Expand All @@ -148,9 +118,21 @@ func Register(c *gin.Context) {
"name": user.Name,
"role": user.Role,
})

if role == "normal" {
modelNet := &model.Net{
UserID: user.ID,
Name: "@",
Password: request.Password,
DHCP: "192.168.202.0/24",
Broadcast: true,
}
modelNet.Create()
candy.InsertNet(modelNet)
}
}

func Login(c *gin.Context) {
func UserLogin(c *gin.Context) {
var request struct {
Username string `json:"username"`
Password string `json:"password"`
Expand All @@ -160,19 +142,20 @@ func Login(c *gin.Context) {
return
}

user := User{
user := model.User{
Name: request.Username,
Password: sha256sum([]byte(request.Password)),
Password: candy.Sha256sum([]byte(request.Password)),
}

db := storage.Get()

if result := db.Where(user).Take(&user); result.Error != nil {
status.UpdateCode(c, status.UsernameOrPasswordIncorrect)
return
}

user.Token = uuid.NewString()
db.Save(user)
user.Save()

c.SetCookie("id", strconv.FormatUint(uint64(user.ID), 10), 86400, "/", "", false, true)
c.SetCookie("token", user.Token, 86400, "/", "", false, true)
Expand All @@ -183,12 +166,10 @@ func Login(c *gin.Context) {
})
}

func Logout(c *gin.Context) {
user := c.MustGet("user").(*User)
func UserLogout(c *gin.Context) {
user := c.MustGet("user").(*model.User)
user.Token = uuid.NewString()

db := storage.Get()
db.Save(user)
user.Save()

c.SetCookie("id", "", -1, "/", "", false, true)
c.SetCookie("token", "", -1, "/", "", false, true)
Expand Down
10 changes: 10 additions & 0 deletions candy/device.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package candy

import (
"github.com/lanthora/cacao/model"
)

type Device struct {
model *model.Device
ip uint32
}
Loading

0 comments on commit 6b99a28

Please sign in to comment.