add personal address
This commit is contained in:
1 parent
50d1ba630e
commit
d2a153536f
17 files changed
+239
-50
No files matched your search
@@ -59,7 +59,6 @@ func (fr *TursoFileRepository) Upload(reader io.Reader, path string, name string
|
||||
ContentType: contentType,
|
||||
VersionId: utility.GenID(),
|
||||
DateCreated: time.Now(),
|
||||
DateUpdated: time.Now(),
|
||||
Content: bytes,
|
||||
}
|
||||
|
||||
|
||||
@@ -131,13 +131,16 @@ func (ur *TursoUserRepository) ListUserAddresses(id string) ([]*domain.UserAddre
|
||||
return ur.AddressTable.SelectWhere("user_id=$1", id)
|
||||
}
|
||||
|
||||
func (ur *TursoUserRepository) CreateUserAddress(userid string, addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||
addr.UserID = userid
|
||||
func (ur *TursoUserRepository) GetUserAddress(addrID string) (*domain.UserAddress, error) {
|
||||
return ur.AddressTable.Get(addrID)
|
||||
}
|
||||
|
||||
func (ur *TursoUserRepository) CreateUserAddress(addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||
return ur.AddressTable.Insert(addr)
|
||||
}
|
||||
func (ur *TursoUserRepository) UpdateUserAddress(userid string, addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||
func (ur *TursoUserRepository) UpdateUserAddress(addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||
return ur.AddressTable.Update(addr)
|
||||
}
|
||||
func (ur *TursoUserRepository) DeleteUserAddress(userid string, addrID string) error {
|
||||
return ur.AddressTable.DeleteWhere("id=$1 and user_id=$2", addrID, userid)
|
||||
func (ur *TursoUserRepository) DeleteUserAddress(addrID string) error {
|
||||
return ur.AddressTable.DeleteWhere("id=$1", addrID)
|
||||
}
|
||||
@@ -117,8 +117,8 @@ func (tm *JwtTokenManager) TokenMiddleware(next echo.HandlerFunc) echo.HandlerFu
|
||||
|
||||
// Rend les infos disponibles aux handlers suivants via c.Get(...)
|
||||
c.Set(auth.ContextUserIDKey, claims.ID)
|
||||
c.Set(auth.ContextEmailKey, claims.Email)
|
||||
c.Set(auth.ContextNameKey, claims.Firstname+" "+claims.Lastname)
|
||||
//c.Set(auth.ContextEmailKey, claims.Email)
|
||||
//c.Set(auth.ContextNameKey, claims.Firstname+" "+claims.Lastname)
|
||||
|
||||
return next(c)
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import (
|
||||
)
|
||||
|
||||
type File struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
ContentType string `db:"content_type" json:"contentType"`
|
||||
StoragePath string `db:"storage_path" json:"-"`
|
||||
StorageFilename string `db:"storage_filename" json:"-"`
|
||||
Content []byte `db:"content" json:"-"`
|
||||
DateCreated time.Time `db:"date_created" json:"-"`
|
||||
DateUpdated time.Time `db:"date_updated" json:"-"`
|
||||
VersionId string `db:"_version" json:"-"`
|
||||
ID string `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
ContentType string `db:"content_type" json:"contentType"`
|
||||
StoragePath string `db:"storage_path" json:"-"`
|
||||
StorageFilename string `db:"storage_filename" json:"-"`
|
||||
Content []byte `db:"content" json:"-"`
|
||||
DateCreated time.Time `db:"date_created" json:"-"`
|
||||
DateUpdated *time.Time `db:"date_updated" json:"-"`
|
||||
VersionId string `db:"_version" json:"-"`
|
||||
}
|
||||
|
||||
type FileRepository interface {
|
||||
|
||||
@@ -7,7 +7,7 @@ type Settings struct {
|
||||
DefaultLang string `db:"default_lang"`
|
||||
RegisterEnabled bool `db:"register_enabled"`
|
||||
PasswordEnabled bool `db:"password_enabled"`
|
||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
}
|
||||
|
||||
@@ -5,25 +5,25 @@ import (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
Firstname string `db:"firstname" json:"firstname,omitempty"`
|
||||
Lastname string `db:"lastname" json:"lastname,omitempty"`
|
||||
Password string `db:"password" json:"-"`
|
||||
Email string `db:"email" json:"email,omitempty"`
|
||||
PictureID string `db:"picture" json:"picture,omitempty"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Theme string `db:"theme" json:"theme"`
|
||||
Lang string `db:"lang" json:"lang"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
ID string `db:"id" json:"id"`
|
||||
Firstname string `db:"firstname" json:"firstname,omitempty"`
|
||||
Lastname string `db:"lastname" json:"lastname,omitempty"`
|
||||
Password string `db:"password" json:"-"`
|
||||
Email string `db:"email" json:"email,omitempty"`
|
||||
PictureID string `db:"picture" json:"picture,omitempty"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
Theme string `db:"theme" json:"theme"`
|
||||
Lang string `db:"lang" json:"lang"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
}
|
||||
|
||||
type Team struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
Label string `db:"label" json:"label"`
|
||||
DefaultModelID *string `db:"default_model_id" json:"default_model_id"`
|
||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
}
|
||||
@@ -33,7 +33,7 @@ type UserTeam struct {
|
||||
UserID string `db:"user_id" json:"user_id"`
|
||||
TeamID string `db:"team_id" json:"team_id"`
|
||||
Administrator bool `db:"administrator" json:"administrator"`
|
||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
}
|
||||
@@ -42,8 +42,8 @@ type UserAddress struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
UserID string `db:"user_id" json:"user_id"`
|
||||
Type string `db:"type" json:"type"`
|
||||
Address string `db:"address_id" json:"address"`
|
||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
||||
Address string `db:"address" json:"address"`
|
||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||
VersionId string `db:"_version" json:"_version"`
|
||||
}
|
||||
@@ -58,6 +58,15 @@ type UserWithTeams struct {
|
||||
Teams []*TeamRelation `json:"teams"`
|
||||
}
|
||||
|
||||
func AddressTypes() []string {
|
||||
return []string{
|
||||
"email",
|
||||
"telegram",
|
||||
"whatsapp",
|
||||
"signal",
|
||||
}
|
||||
}
|
||||
|
||||
type UserRepository interface {
|
||||
FindUser(id string) (*User, error)
|
||||
FindUserByEmail(email string) (*User, error)
|
||||
@@ -81,7 +90,8 @@ type UserRepository interface {
|
||||
PopulateUserWithTeams(user *User) (*UserWithTeams, error)
|
||||
|
||||
ListUserAddresses(userid string) ([]*UserAddress, error)
|
||||
CreateUserAddress(userid string, addr *UserAddress) (*UserAddress, error)
|
||||
UpdateUserAddress(userid string, addr *UserAddress) (*UserAddress, error)
|
||||
DeleteUserAddress(userid string, addrID string) error
|
||||
GetUserAddress(addrID string) (*UserAddress, error)
|
||||
CreateUserAddress(addr *UserAddress) (*UserAddress, error)
|
||||
UpdateUserAddress(addr *UserAddress) (*UserAddress, error)
|
||||
DeleteUserAddress(addrID string) error
|
||||
}
|
||||
@@ -17,6 +17,10 @@ func NewUserGroup(prefix string, e *echo.Group, service *user.Service, middlewar
|
||||
auth := e.Group(prefix, middlewares...)
|
||||
auth.GET("/me", userHandler.Me)
|
||||
auth.PUT("/:id", userHandler.Update)
|
||||
auth.GET("/:id/address", userHandler.Addresses)
|
||||
auth.POST("/:id/address", userHandler.CreateAddress)
|
||||
auth.PUT("/:id/address", userHandler.UpdateAddress)
|
||||
auth.DELETE("/:id/address/:address", userHandler.DeleteAddress)
|
||||
return auth
|
||||
}
|
||||
|
||||
@@ -43,15 +47,86 @@ func (h UserHandler) Update(c *echo.Context) error {
|
||||
}
|
||||
updUser.ID = id
|
||||
|
||||
isAdmin := false // TODO : check if caller is admin
|
||||
if !(isAdmin || userID == id) {
|
||||
if !(userID == id) {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "unauthorized to update user")
|
||||
}
|
||||
|
||||
user, err := h.userService.UpdateUser(&updUser, isAdmin)
|
||||
user, err := h.userService.UpdateUser(&updUser, false)
|
||||
if err != nil {
|
||||
return c.String(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
func (h UserHandler) Addresses(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
id := c.Param("id")
|
||||
if !(userID == id) {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||
}
|
||||
addresses, err := h.userService.ListAdresses(userID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return c.JSON(http.StatusOK, addresses)
|
||||
}
|
||||
|
||||
func (h UserHandler) CreateAddress(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
id := c.Param("id")
|
||||
if !(userID == id) {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||
}
|
||||
|
||||
var address domain.UserAddress
|
||||
if err := c.Bind(&address); err != nil {
|
||||
return c.String(http.StatusBadRequest, "bad request")
|
||||
}
|
||||
address.UserID = userID
|
||||
|
||||
newaddress, err := h.userService.AddAddress(userID, address.Type, address.Address)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, newaddress)
|
||||
|
||||
}
|
||||
|
||||
func (h UserHandler) UpdateAddress(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
id := c.Param("id")
|
||||
if !(userID == id) {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||
}
|
||||
|
||||
var address domain.UserAddress
|
||||
if err := c.Bind(&address); err != nil {
|
||||
return c.String(http.StatusBadRequest, "bad request")
|
||||
}
|
||||
address.UserID = userID
|
||||
|
||||
newaddress, err := h.userService.UpdateAddress(userID, &address)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, newaddress)
|
||||
}
|
||||
|
||||
func (h UserHandler) DeleteAddress(c *echo.Context) error {
|
||||
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||
id := c.Param("id")
|
||||
addressID := c.Param("address")
|
||||
if !(userID == id) {
|
||||
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||
}
|
||||
|
||||
err := h.userService.DeleteAddress(userID, addressID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, "deleted")
|
||||
}
|
||||
@@ -31,8 +31,10 @@ type Session struct {
|
||||
}
|
||||
|
||||
const ContextUserIDKey = "userID"
|
||||
const ContextEmailKey = "userEmail"
|
||||
const ContextNameKey = "userName"
|
||||
const ContextUserAdminKey = "userAdmin"
|
||||
|
||||
//const ContextEmailKey = "userEmail"
|
||||
//const ContextNameKey = "userName"
|
||||
|
||||
// Interface définie ici car c'est un port propre au cas d'usage "auth"
|
||||
type Authenticator interface {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"trankilou.fr/lassistanoque/backend/internal/domain"
|
||||
)
|
||||
@@ -53,8 +54,10 @@ func (s *Service) Register(registration Registration) (*Session, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
now := time.Now()
|
||||
_, err = s.userRepository.CreateTeam(session.User.ID, &domain.Team{
|
||||
Label: "Espace personnel",
|
||||
Label: "Espace personnel",
|
||||
DateCreated: now,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -45,3 +45,38 @@ func (s *Service) UpdateUser(updUser *domain.User, fromAdmin bool) (*domain.User
|
||||
return s.repo.UpdateUser(user)
|
||||
|
||||
}
|
||||
|
||||
func (s *Service) ListAdresses(userId string) ([]*domain.UserAddress, error) {
|
||||
return s.repo.ListUserAddresses(userId)
|
||||
}
|
||||
|
||||
func (s *Service) AddAddress(userId string, typ string, address string) (*domain.UserAddress, error) {
|
||||
addr := &domain.UserAddress{
|
||||
UserID: userId,
|
||||
Type: typ,
|
||||
Address: address,
|
||||
}
|
||||
return s.repo.CreateUserAddress(addr)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateAddress(userId string, address *domain.UserAddress) (*domain.UserAddress, error) {
|
||||
old, err := s.repo.GetUserAddress(address.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if old.UserID != userId {
|
||||
return nil, fmt.Errorf("unauthorized")
|
||||
}
|
||||
return s.repo.UpdateUserAddress(address)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteAddress(userId string, addressId string) error {
|
||||
old, err := s.repo.GetUserAddress(addressId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if old.UserID != userId {
|
||||
return fmt.Errorf("unauthorized")
|
||||
}
|
||||
return s.repo.DeleteUserAddress(addressId)
|
||||
}
|
||||
Reference in new issue
Block a user