update api.go, auth.go, middleware.go
This commit is contained in:
1 parent
be5630cbd9
commit
7493fd4885
3 files changed
+710
No files matched your search
@@ -0,0 +1,534 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"esaccount"
|
||||
"esaccount/pkg/util"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// confidential godoc
|
||||
// @Summary Get all confidential settings
|
||||
// @Tags confidential
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200
|
||||
// @Router /api/confidential/ [get]
|
||||
func (h *Handler) getConfidential(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, account.Confidentials)
|
||||
}
|
||||
|
||||
// confidential godoc
|
||||
// @Summary Set confidential settings
|
||||
// @Tags confidential
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param confidencial body string true "Confidencial settings"
|
||||
// @Success 200 {object} esaccount.AuthorizedUser
|
||||
// @Router /api/confidential/ [post]
|
||||
func (h *Handler) setConfidential(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var input esaccount.ConfidentialSettings
|
||||
if err := c.BindJSON(&input); err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range input {
|
||||
account.Confidentials[k] = v
|
||||
}
|
||||
account.Confidentials["picture_url"] = esaccount.All
|
||||
|
||||
h.repo.SaveAccount(account)
|
||||
|
||||
c.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
// public godoc
|
||||
// @Summary Get all public data of users
|
||||
// @Tags confidential
|
||||
// @Produce json
|
||||
// @Param Authorization header string false "JWT Bearer token (authorization)"
|
||||
// @Param id query int true "user id"
|
||||
// @Success 200
|
||||
// @Router /api/public/{id} [get]
|
||||
func (h *Handler) getPublic(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
account, err := h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
header := c.GetHeader(authorizationHeader)
|
||||
allowedFields := []string{}
|
||||
isFriend := false
|
||||
if header != "" {
|
||||
authorized, err := h.services.Authorization.Authorize(header)
|
||||
if err == nil {
|
||||
isFriend = (slices.Contains(account.Followers, authorized.Id) && slices.Contains(account.Follows, authorized.Id))
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range account.Confidentials {
|
||||
if (v == esaccount.All) || (isFriend && (v == esaccount.Friends)) {
|
||||
allowedFields = append(allowedFields, k)
|
||||
}
|
||||
}
|
||||
|
||||
res := map[string]any{}
|
||||
user, _ := h.services.AuthorizeById(id)
|
||||
|
||||
// auth user
|
||||
if slices.Contains(allowedFields, "username") {
|
||||
res["username"] = user.Username
|
||||
}
|
||||
if slices.Contains(allowedFields, "first_name") {
|
||||
res["first_name"] = user.FirstName
|
||||
}
|
||||
if slices.Contains(allowedFields, "last_name") {
|
||||
res["last_name"] = user.LastName
|
||||
}
|
||||
res["picture_url"] = user.LastName
|
||||
if slices.Contains(allowedFields, "email") {
|
||||
res["email"] = user.LastName
|
||||
}
|
||||
|
||||
// account
|
||||
if slices.Contains(allowedFields, "description") {
|
||||
res["description"] = account.Description
|
||||
}
|
||||
if slices.Contains(allowedFields, "date_of_birth") {
|
||||
res["date_of_birth"] = account.DateOfBirth
|
||||
}
|
||||
if slices.Contains(allowedFields, "follows") {
|
||||
res["follows"] = account.Follows
|
||||
}
|
||||
if slices.Contains(allowedFields, "followers") {
|
||||
res["followers"] = account.Follows
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
||||
|
||||
type accountResponce struct {
|
||||
Description string `json:"description"`
|
||||
DateOfBirth string `json:"date_of_birth"`
|
||||
Follows []int64 `json:"follows"`
|
||||
Followers []int64 `json:"followers"`
|
||||
}
|
||||
|
||||
// account godoc
|
||||
// @Summary Get account information
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200 {object} handler.accountResponce
|
||||
// @Router /api/account [get]
|
||||
func (h *Handler) getAccount(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, accountResponce{
|
||||
Description: account.Description,
|
||||
DateOfBirth: account.DateOfBirth,
|
||||
Follows: account.Follows,
|
||||
Followers: account.Followers,
|
||||
})
|
||||
}
|
||||
|
||||
// picture godoc
|
||||
// @Summary Get account information
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param file formData file true "Picture"
|
||||
// @Success 200
|
||||
// @Router /api/account/picture [post]
|
||||
func (h *Handler) picture(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
_, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
file, _, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
os.Remove(fmt.Sprintf("./public/usercontent/picture/%d.png", id))
|
||||
picFile, err := os.Create(fmt.Sprintf("./public/usercontent/picture/%d.png", id))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err := io.Copy(picFile, file); err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
header, _ := c.Get(userHeader)
|
||||
picUrl := fmt.Sprintf("https://account.easystartup.su/static/picture/%d.png", id)
|
||||
_, err = h.services.AuthorizeAndUpdatePicture(header.(string), picUrl)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, fmt.Sprintf("{ \"url\": %s \"\" }", picUrl))
|
||||
}
|
||||
|
||||
type accountInput struct {
|
||||
Description string `json:"description"`
|
||||
DateOfBirth string `json:"date_of_birth"`
|
||||
}
|
||||
|
||||
// account godoc
|
||||
// @Summary Set account information
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param account body handler.accountInput true "account info"
|
||||
// @Success 200 {object} handler.accountInput
|
||||
// @Router /api/account [post]
|
||||
func (h *Handler) editAccount(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var input accountInput
|
||||
if err := c.BindJSON(&input); err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
account.Description = input.Description
|
||||
account.DateOfBirth = input.DateOfBirth
|
||||
h.repo.SaveAccount(account)
|
||||
|
||||
c.JSON(http.StatusOK, input)
|
||||
}
|
||||
|
||||
// account godoc
|
||||
// @Summary Get account information by id
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param id path int true "account id"
|
||||
// @Success 200 {object} handler.accountResponce
|
||||
// @Router /api/account/{id} [get]
|
||||
func (h *Handler) getAccountById(c *gin.Context) {
|
||||
current, _ := c.Get(userCtx)
|
||||
currentUser, err := h.services.AuthorizeById(current.(int64))
|
||||
if (err != nil) || (currentUser.Access != "admin") {
|
||||
util.NewErrorResponse(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
account, err := h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
authorized, err := h.services.AuthorizeById(id)
|
||||
if (err == nil) && (authorized.Id == id) {
|
||||
account, err = h.repo.CreateAccount(id)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, accountResponce{
|
||||
Description: account.Description,
|
||||
DateOfBirth: account.DateOfBirth,
|
||||
Follows: account.Follows,
|
||||
Followers: account.Followers,
|
||||
})
|
||||
}
|
||||
|
||||
// account godoc
|
||||
// @Summary Set account information by id
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param account body handler.accountResponce true "account info"
|
||||
// @Param id path int true "account id"
|
||||
// @Success 200 {object} handler.accountResponce
|
||||
// @Router /api/account/{id} [post]
|
||||
func (h *Handler) editAccountById(c *gin.Context) {
|
||||
current, _ := c.Get(userCtx)
|
||||
currentUser, err := h.services.AuthorizeById(current.(int64))
|
||||
if (err != nil) || (currentUser.Access != "admin") {
|
||||
util.NewErrorResponse(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
account, err := h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
authorized, err := h.services.AuthorizeById(id)
|
||||
if (err == nil) && (authorized.Id == id) {
|
||||
account, err = h.repo.CreateAccount(id)
|
||||
}
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var input accountResponce
|
||||
if err := c.BindJSON(&input); err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
account.Description = input.Description
|
||||
account.DateOfBirth = input.DateOfBirth
|
||||
account.Followers = input.Followers
|
||||
account.Follows = input.Follows
|
||||
h.repo.SaveAccount(account)
|
||||
|
||||
c.JSON(http.StatusOK, input)
|
||||
}
|
||||
|
||||
// account godoc
|
||||
// @Summary Delete account by id
|
||||
// @Tags account
|
||||
// @Produce json
|
||||
// @Param id path int true "id of user"
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200
|
||||
// @Router /api/account/{id} [delete]
|
||||
func (h *Handler) delete(c *gin.Context) {
|
||||
current, _ := c.Get(userCtx)
|
||||
currentUser, err := h.services.AuthorizeById(current.(int64))
|
||||
if (err != nil) || (currentUser.Access != "admin") {
|
||||
util.NewErrorResponse(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
_, err = h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = h.repo.DeleteAccount(id)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, "{ \"status\": \"ok\" }")
|
||||
}
|
||||
|
||||
// confidential godoc
|
||||
// @Summary Get all confidential settings by id
|
||||
// @Tags confidential
|
||||
// @Produce json
|
||||
// @Param id path int true "id of user"
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200
|
||||
// @Router /api/confidential/{id} [get]
|
||||
func (h *Handler) getConfidentialById(c *gin.Context) {
|
||||
current, _ := c.Get(userCtx)
|
||||
currentUser, err := h.services.AuthorizeById(current.(int64))
|
||||
if (err != nil) || (currentUser.Access != "admin") {
|
||||
util.NewErrorResponse(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
account, err := h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
authorized, err := h.services.AuthorizeById(id)
|
||||
if (err == nil) && (authorized.Id == id) {
|
||||
account, err = h.repo.CreateAccount(id)
|
||||
}
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, account.Confidentials)
|
||||
}
|
||||
|
||||
// confidential godoc
|
||||
// @Summary Set confidential settings by id
|
||||
// @Tags confidential
|
||||
// @Produce json
|
||||
// @Param id path int true "id of user"
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Param confidencial body string true "Confidencial settings"
|
||||
// @Success 200 {object} esaccount.AuthorizedUser
|
||||
// @Router /api/confidential/{id} [post]
|
||||
func (h *Handler) setConfidentialById(c *gin.Context) {
|
||||
current, _ := c.Get(userCtx)
|
||||
currentUser, err := h.services.AuthorizeById(current.(int64))
|
||||
if (err != nil) || (currentUser.Access != "admin") {
|
||||
util.NewErrorResponse(c, http.StatusForbidden, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
account, err := h.repo.GetAccount(id)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var input esaccount.ConfidentialSettings
|
||||
if err := c.BindJSON(&input); err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range input {
|
||||
account.Confidentials[k] = v
|
||||
}
|
||||
account.Confidentials["picture_url"] = esaccount.All
|
||||
|
||||
h.repo.SaveAccount(account)
|
||||
|
||||
c.JSON(http.StatusOK, account)
|
||||
}
|
||||
|
||||
// following godoc
|
||||
// @Summary Follow to user
|
||||
// @Tags following
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200
|
||||
// @Router /api/following/follow/{id} [put]
|
||||
func (h *Handler) follow(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err = strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
followed, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !slices.Contains(followed.Followers, account.Id) {
|
||||
followed.Followers = append(followed.Followers, account.Id)
|
||||
h.repo.SaveAccount(followed)
|
||||
}
|
||||
|
||||
if !slices.Contains(account.Follows, followed.Id) {
|
||||
account.Follows = append(followed.Follows, followed.Id)
|
||||
h.repo.SaveAccount(account)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, "{ \"status\": \"ok\" }")
|
||||
}
|
||||
|
||||
// following godoc
|
||||
// @Summary Unfollow user
|
||||
// @Tags following
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "JWT Bearer token (authorization)"
|
||||
// @Success 200
|
||||
// @Router /api/following/unfollow/{id} [put]
|
||||
func (h *Handler) unfollow(c *gin.Context) {
|
||||
id, _ := c.Get(userCtx)
|
||||
account, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
id, err = strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
followed, err := h.repo.GetAccount(id.(int64))
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusNotFound, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
followed.Followers = removeElement(followed.Followers, account.Id)
|
||||
account.Follows = removeElement(followed.Follows, followed.Id)
|
||||
|
||||
h.repo.SaveAccount(followed)
|
||||
h.repo.SaveAccount(account)
|
||||
|
||||
c.JSON(http.StatusOK, "{ \"status\": \"ok\" }")
|
||||
}
|
||||
|
||||
func removeElement(slice []int64, value int64) []int64 {
|
||||
// Find the index of the value
|
||||
for i, v := range slice {
|
||||
if v == value {
|
||||
// Remove the element by slicing around it
|
||||
return append(slice[:i], slice[i+1:]...)
|
||||
}
|
||||
}
|
||||
// If the value is not found, return the original slice
|
||||
return slice
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"esaccount/pkg/util"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
authorizationHeader = "Authorization"
|
||||
userCtx = "UserInfo"
|
||||
userHeader = "UserHeader"
|
||||
)
|
||||
|
||||
func (h *Handler) userIdentity(c *gin.Context) {
|
||||
header := c.GetHeader(authorizationHeader)
|
||||
if header == "" {
|
||||
util.NewErrorResponse(c, http.StatusUnauthorized, "empty auth header")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.services.Authorization.Authorize(header)
|
||||
if err != nil {
|
||||
util.NewErrorResponse(c, http.StatusUnauthorized, err.Error())
|
||||
}
|
||||
|
||||
_, err = h.repo.GetAccount(user.Id)
|
||||
if err != nil {
|
||||
h.repo.CreateAccount(user.Id)
|
||||
}
|
||||
|
||||
c.Set(userCtx, user.Id)
|
||||
c.Set(userHeader, header)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user