feature: Adds user lookup support.
This commit is contained in:
parent
cee4e62f53
commit
611d7f24f8
4 changed files with 142 additions and 5 deletions
|
@ -29,8 +29,6 @@ type UserCreationRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUser(c *gin.Context) {
|
func CreateUser(c *gin.Context) {
|
||||||
var req UserCreationRequest
|
|
||||||
|
|
||||||
if !signupEnabled && !unsafeSignup {
|
if !signupEnabled && !unsafeSignup {
|
||||||
c.JSON(http.StatusForbidden, gin.H{
|
c.JSON(http.StatusForbidden, gin.H{
|
||||||
"error": "Signing up is not enabled at this time.",
|
"error": "Signing up is not enabled at this time.",
|
||||||
|
@ -39,6 +37,8 @@ func CreateUser(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var req UserCreationRequest
|
||||||
|
|
||||||
if err := c.BindJSON(&req); err != nil {
|
if err := c.BindJSON(&req); err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": fmt.Sprintf("Failed to parse body: %s", err.Error()),
|
"error": fmt.Sprintf("Failed to parse body: %s", err.Error()),
|
||||||
|
|
136
backend/api/controllers/v1/users/lookup.go
Normal file
136
backend/api/controllers/v1/users/lookup.go
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package users
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.terah.dev/imterah/hermes/api/dbcore"
|
||||||
|
"git.terah.dev/imterah/hermes/api/jwtcore"
|
||||||
|
"git.terah.dev/imterah/hermes/api/permissions"
|
||||||
|
"github.com/charmbracelet/log"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserLookupRequest struct {
|
||||||
|
Token string `validate:"required"`
|
||||||
|
UID *uint `json:"id"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Username *string `json:"username"`
|
||||||
|
IsBot *bool `json:"isServiceAccount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SanitizedUsers struct {
|
||||||
|
UID uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
IsBot bool `json:"isServiceAccount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LookupResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Data []*SanitizedUsers `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func LookupUser(c *gin.Context) {
|
||||||
|
var req UserLookupRequest
|
||||||
|
|
||||||
|
if err := c.BindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": fmt.Sprintf("Failed to parse body: %s", err.Error()),
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validator.New().Struct(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": fmt.Sprintf("Failed to validate body: %s", err.Error()),
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := jwtcore.GetUserFromJWT(req.Token)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() == "token is expired" || err.Error() == "user does not exist" {
|
||||||
|
c.JSON(http.StatusForbidden, gin.H{
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
log.Warnf("Failed to get user from the provided JWT token: %s", err.Error())
|
||||||
|
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": "Failed to parse token",
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
users := []dbcore.User{}
|
||||||
|
queryString := []string{}
|
||||||
|
queryParameters := []interface{}{}
|
||||||
|
|
||||||
|
if !permissions.UserHasPermission(user, "users.lookup") {
|
||||||
|
queryString = append(queryString, "id = ?")
|
||||||
|
queryParameters = append(queryParameters, user.ID)
|
||||||
|
} else if permissions.UserHasPermission(user, "users.lookup") && req.UID != nil {
|
||||||
|
queryString = append(queryString, "id = ?")
|
||||||
|
queryParameters = append(queryParameters, req.UID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Name != nil {
|
||||||
|
queryString = append(queryString, "name = ?")
|
||||||
|
queryParameters = append(queryParameters, req.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Email != nil {
|
||||||
|
queryString = append(queryString, "email = ?")
|
||||||
|
queryParameters = append(queryParameters, req.Email)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.IsBot != nil {
|
||||||
|
queryString = append(queryString, "isbot = ?")
|
||||||
|
queryParameters = append(queryParameters, req.IsBot)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbcore.DB.Where(strings.Join(queryString, " AND "), queryParameters...).Find(&users).Error; err != nil {
|
||||||
|
log.Warnf("Failed to get users: %s", err.Error())
|
||||||
|
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": "Failed to get users",
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitizedUsers := make([]*SanitizedUsers, len(users))
|
||||||
|
|
||||||
|
for userIndex, user := range users {
|
||||||
|
isBot := false
|
||||||
|
|
||||||
|
if user.IsBot != nil {
|
||||||
|
isBot = *user.IsBot
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitizedUsers[userIndex] = &SanitizedUsers{
|
||||||
|
UID: user.ID,
|
||||||
|
Name: user.Name,
|
||||||
|
Email: user.Email,
|
||||||
|
Username: user.Username,
|
||||||
|
IsBot: isBot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, &LookupResponse{
|
||||||
|
Success: true,
|
||||||
|
Data: sanitizedUsers,
|
||||||
|
})
|
||||||
|
}
|
|
@ -95,6 +95,7 @@ func main() {
|
||||||
engine.POST("/api/v1/users/login", users.LoginUser)
|
engine.POST("/api/v1/users/login", users.LoginUser)
|
||||||
engine.POST("/api/v1/users/refresh", users.RefreshUserToken)
|
engine.POST("/api/v1/users/refresh", users.RefreshUserToken)
|
||||||
engine.POST("/api/v1/users/remove", users.RemoveUser)
|
engine.POST("/api/v1/users/remove", users.RemoveUser)
|
||||||
|
engine.POST("/api/v1/users/lookup", users.LookupUser)
|
||||||
|
|
||||||
log.Infof("Listening on: %s", listeningAddress)
|
log.Infof("Listening on: %s", listeningAddress)
|
||||||
err = engine.Run(listeningAddress)
|
err = engine.Run(listeningAddress)
|
||||||
|
|
|
@ -5,14 +5,14 @@ meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
url: http://127.0.0.1:3000/api/v1/users/lookup
|
url: http://127.0.0.1:8000/api/v1/users/lookup
|
||||||
body: json
|
body: json
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"token": "5e2cb92a338a832d385790861312eb85d69f46f82317bfa984ac5e3517368ab5a827897b0f9775a9181b02fa3b9cffed7e59e5b3111d5bdc37f729156caf5f",
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiMSJdLCJleHAiOjE3MzQ4OTQwNTEsIm5iZiI6MTczNDg5Mzg3MSwiaWF0IjoxNzM0ODkzODcxfQ.l4GbSKejqeRxSze9Kjj3A-8mxKqUuOz58iHzPOraNmo",
|
||||||
"name": "Greyson Hofer"
|
"name": "Test User"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue