backend added struct merging and FieldPermissionsOnRoleId
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/alexedwards/argon2id"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"GoMembership/internal/config"
|
||||
@@ -116,6 +117,22 @@ func TestSuite(t *testing.T) {
|
||||
if err := initLicenceCategories(); err != nil {
|
||||
log.Fatalf("Failed to init Categories: %v", err)
|
||||
}
|
||||
hash, err := argon2id.CreateHash("securepassword", argon2id.DefaultParams)
|
||||
admin := models.User{
|
||||
FirstName: "Ad",
|
||||
LastName: "min",
|
||||
Email: "admin@example.com",
|
||||
Password: hash,
|
||||
DateOfBirth: time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
Company: "SampleCorp",
|
||||
Phone: "+123456789",
|
||||
Address: "123 Main Street",
|
||||
ZipCode: "12345",
|
||||
City: "SampleCity",
|
||||
Status: 1,
|
||||
RoleID: 8,
|
||||
}
|
||||
database.DB.Create(&admin)
|
||||
validation.SetupValidators()
|
||||
t.Run("userController", func(t *testing.T) {
|
||||
testUserController(t)
|
||||
@@ -262,6 +279,7 @@ func getBaseUser() models.User {
|
||||
ProfilePicture: "",
|
||||
Password: "password123",
|
||||
Company: "",
|
||||
RoleID: 8,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,35 @@ func (uc *UserController) UpdateHandler(c *gin.Context) {
|
||||
user = updateData.User
|
||||
|
||||
if !utils.HasPrivilige(requestUser, constants.Priviliges.Update) && user.ID != requestUser.ID {
|
||||
utils.RespondWithError(c, errors.ErrNotAuthorized, "Not allowed to update user", http.StatusForbidden, "user.user", "server.error.unauthorized")
|
||||
utils.RespondWithError(c, errors.ErrNotAuthorized, "Not allowed to update user", http.StatusUnauthorized, "user.user", "server.error.unauthorized")
|
||||
return
|
||||
}
|
||||
existingUser, err := uc.Service.GetUserByID(user.ID)
|
||||
if err != nil {
|
||||
utils.RespondWithError(c, err, "Error finding an existing user", http.StatusNotFound, "user.user", "server.error.not_found")
|
||||
return
|
||||
}
|
||||
// user.Membership.ID = existingUser.Membership.ID
|
||||
|
||||
// user.MembershipID = existingUser.MembershipID
|
||||
// if existingUser.Licence != nil {
|
||||
// user.Licence.ID = existingUser.Licence.ID
|
||||
// }
|
||||
// user.LicenceID = existingUser.LicenceID
|
||||
// user.BankAccount.ID = existingUser.BankAccount.ID
|
||||
// user.BankAccountID = existingUser.BankAccountID
|
||||
|
||||
if requestUser.RoleID <= constants.Priviliges.View {
|
||||
existingUser.Password = ""
|
||||
if err := utils.FilterAllowedStructFields(&user, existingUser, constants.MemberUpdateFields, ""); err != nil {
|
||||
if err.Error() == "Not authorized" {
|
||||
utils.RespondWithError(c, errors.ErrNotAuthorized, "Trying to update unauthorized fields", http.StatusUnauthorized, "user.user", "server.error.unauthorized")
|
||||
return
|
||||
}
|
||||
utils.RespondWithError(c, err, "Error filtering users input fields", http.StatusInternalServerError, "user.user", "server.error.internal_server_error")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
updatedUser, err := uc.Service.UpdateUser(&user)
|
||||
if err != nil {
|
||||
|
||||
@@ -75,7 +75,37 @@ func testUserController(t *testing.T) {
|
||||
|
||||
loginEmail, loginCookie := testLoginHandler(t)
|
||||
logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie)
|
||||
testUpdateUser(t, loginCookie)
|
||||
|
||||
// creating a admin cookie
|
||||
c, w, _ := GetMockedJSONContext([]byte(`{
|
||||
"email": "admin@example.com",
|
||||
"password": "securepassword"
|
||||
}`), "/login")
|
||||
|
||||
Uc.LoginHandler(c)
|
||||
|
||||
var response map[string]interface{}
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "Login successful", response["message"])
|
||||
var adminCookie http.Cookie
|
||||
for _, cookie := range w.Result().Cookies() {
|
||||
if cookie.Name == "jwt" {
|
||||
adminCookie = *cookie
|
||||
|
||||
tokenString := adminCookie.Value
|
||||
_, claims, err := middlewares.ExtractContentFrom(tokenString)
|
||||
assert.NoError(t, err, "FAiled getting cookie string")
|
||||
jwtUserID := uint((*claims)["user_id"].(float64))
|
||||
user, err := Uc.Service.GetUserByID(jwtUserID)
|
||||
assert.NoError(t, err, "FAiled getting cookie string")
|
||||
logger.Error.Printf("ADMIN USER: %#v", user)
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.NotEmpty(t, adminCookie)
|
||||
testUpdateUser(t, loginCookie, adminCookie)
|
||||
testLogoutHandler(t, logoutCookie)
|
||||
}
|
||||
|
||||
@@ -190,7 +220,7 @@ func testLoginHandler(t *testing.T) (string, http.Cookie) {
|
||||
|
||||
for _, tt := range tests {
|
||||
logger.Error.Print("==============================================================")
|
||||
logger.Error.Printf("Testing : %v", tt.name)
|
||||
logger.Error.Printf("Login Testing : %v", tt.name)
|
||||
logger.Error.Print("==============================================================")
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Setup
|
||||
@@ -213,6 +243,14 @@ func testLoginHandler(t *testing.T) (string, http.Cookie) {
|
||||
if cookie.Name == "jwt" {
|
||||
loginCookie = *cookie
|
||||
|
||||
// tokenString := loginCookie.Value
|
||||
// _, claims, err := middlewares.ExtractContentFrom(tokenString)
|
||||
// assert.NoError(t, err, "FAiled getting cookie string")
|
||||
// jwtUserID := uint((*claims)["user_id"].(float64))
|
||||
// user, err := Uc.Service.GetUserByID(jwtUserID)
|
||||
// assert.NoError(t, err, "FAiled getting cookie string")
|
||||
|
||||
// logger.Error.Printf("cookie user: %#v", user)
|
||||
err = json.Unmarshal([]byte(tt.input), &loginInput)
|
||||
assert.NoError(t, err, "Failed to unmarshal input JSON")
|
||||
|
||||
@@ -413,7 +451,7 @@ func validateUser(assert bool, wantDBData map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
func testUpdateUser(t *testing.T, loginCookie http.Cookie, adminCookie http.Cookie) {
|
||||
|
||||
invalidCookie := http.Cookie{
|
||||
Name: "jwt",
|
||||
@@ -437,13 +475,14 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
name string
|
||||
setupCookie func(*http.Request)
|
||||
updateFunc func(*models.User)
|
||||
expectedReturn func(*models.User)
|
||||
expectedStatus int
|
||||
expectedErrors []map[string]string
|
||||
}{
|
||||
{
|
||||
name: "Valid Update",
|
||||
name: "Valid Admin Update",
|
||||
setupCookie: func(req *http.Request) {
|
||||
req.AddCookie(&loginCookie)
|
||||
req.AddCookie(&adminCookie)
|
||||
},
|
||||
updateFunc: func(u *models.User) {
|
||||
u.Password = ""
|
||||
@@ -486,8 +525,23 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
{"field": "Email", "key": "server.validation.email"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Change Number",
|
||||
name: "admin may change licence number",
|
||||
setupCookie: func(req *http.Request) {
|
||||
req.AddCookie(&adminCookie)
|
||||
},
|
||||
updateFunc: func(u *models.User) {
|
||||
u.Password = ""
|
||||
u.FirstName = "John Updated"
|
||||
u.LastName = "Doe Updated"
|
||||
u.Phone = "01738484994"
|
||||
u.Licence.Number = "B072RRE2I50"
|
||||
},
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
{
|
||||
name: "Change phone number",
|
||||
setupCookie: func(req *http.Request) {
|
||||
req.AddCookie(&loginCookie)
|
||||
},
|
||||
@@ -578,12 +632,13 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
updateFunc: func(u *models.User) {
|
||||
u.Password = ""
|
||||
u.ID = 1
|
||||
u.FirstName = "John Updated"
|
||||
u.LastName = "Doe Updated"
|
||||
u.Phone = "01738484994"
|
||||
u.Licence.Number = "B072RRE2I50"
|
||||
u.FirstName = "John Missing ID"
|
||||
},
|
||||
expectedStatus: http.StatusForbidden,
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedErrors: []map[string]string{
|
||||
{"field": "user.user", "key": "server.error.unauthorized"},
|
||||
},
|
||||
@@ -594,7 +649,27 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
req.AddCookie(&loginCookie)
|
||||
},
|
||||
updateFunc: func(u *models.User) {
|
||||
u.FirstName = "John Updated"
|
||||
u.LastName = "Doe Updated"
|
||||
u.Phone = "01738484994"
|
||||
u.Licence.Number = "B072RRE2I50"
|
||||
u.Password = "NewPassword"
|
||||
},
|
||||
expectedReturn: func(u *models.User) {
|
||||
u.Password = ""
|
||||
u.FirstName = "John Updated"
|
||||
u.LastName = "Doe Updated"
|
||||
u.Phone = "01738484994"
|
||||
u.Licence.Number = "B072RRE2I50"
|
||||
},
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
{
|
||||
name: "Admin Password Update",
|
||||
setupCookie: func(req *http.Request) {
|
||||
req.AddCookie(&adminCookie)
|
||||
},
|
||||
updateFunc: func(u *models.User) {
|
||||
u.LastName = "Doe Updated"
|
||||
u.Phone = "01738484994"
|
||||
u.Licence.Number = "B072RRE2I50"
|
||||
@@ -602,19 +677,21 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
},
|
||||
expectedStatus: http.StatusAccepted,
|
||||
},
|
||||
// {
|
||||
// name: "Non-existent User",
|
||||
// setupCookie: func(req *http.Request) {
|
||||
// req.AddCookie(&loginCookie)
|
||||
// },
|
||||
// updateFunc: func(u *models.User) {
|
||||
// u.Password = ""
|
||||
// u.ID = 99999
|
||||
// u.FirstName = "Non-existent"
|
||||
// },
|
||||
// expectedStatus: http.StatusNotFound,
|
||||
// expectedError: "User not found",
|
||||
// },
|
||||
{
|
||||
name: "Non-existent User",
|
||||
setupCookie: func(req *http.Request) {
|
||||
req.AddCookie(&loginCookie)
|
||||
},
|
||||
updateFunc: func(u *models.User) {
|
||||
u.Password = ""
|
||||
u.ID = 99999
|
||||
u.FirstName = "Non-existent"
|
||||
},
|
||||
expectedErrors: []map[string]string{
|
||||
{"field": "user.user", "key": "server.error.unauthorized"},
|
||||
},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
logger.Error.Print("==============================================================")
|
||||
@@ -623,9 +700,8 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a copy of the user and apply the updates
|
||||
updatedUser := user
|
||||
logger.Error.Printf("user to be updated: %+v", user.Licence)
|
||||
// logger.Error.Printf("users licence to be updated: %+v", user.Licence)
|
||||
tt.updateFunc(&updatedUser)
|
||||
// Convert user to JSON
|
||||
|
||||
updateData := &RegistrationData{User: updatedUser}
|
||||
jsonData, err := json.Marshal(updateData)
|
||||
@@ -633,7 +709,11 @@ func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
|
||||
t.Fatalf("Failed to marshal user data: %v", err)
|
||||
}
|
||||
|
||||
// logger.Error.Printf("Updated User: %#v", updatedUser)
|
||||
logger.Error.Printf("Updated User: %#v", updatedUser.Safe())
|
||||
if tt.expectedReturn != nil {
|
||||
tt.expectedReturn(&updatedUser)
|
||||
}
|
||||
|
||||
// Create request
|
||||
req, _ := http.NewRequest("PUT", "/users/"+strconv.FormatUint(uint64(user.ID), 10), bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
@@ -987,6 +1067,7 @@ func getTestUsers() []RegisterUserTest {
|
||||
Assert: false,
|
||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
user.BankAccount.IBAN = ""
|
||||
user.RoleID = 0
|
||||
return user
|
||||
})),
|
||||
},
|
||||
@@ -997,6 +1078,7 @@ func getTestUsers() []RegisterUserTest {
|
||||
Assert: false,
|
||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
user.BankAccount.IBAN = "DE1234234123134"
|
||||
user.RoleID = 0
|
||||
return user
|
||||
})),
|
||||
},
|
||||
@@ -1110,35 +1192,35 @@ func getTestUsers() []RegisterUserTest {
|
||||
// return user
|
||||
// })),
|
||||
// },
|
||||
{
|
||||
Name: "empty driverslicence number, should fail",
|
||||
WantResponse: http.StatusBadRequest,
|
||||
WantDBData: map[string]interface{}{"email": "john.wronglicence.doe@example.com"},
|
||||
Assert: false,
|
||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
user.Email = "john.wronglicence.doe@example.com"
|
||||
user.Licence = &models.Licence{
|
||||
Number: "",
|
||||
ExpirationDate: time.Now().AddDate(1, 0, 0),
|
||||
IssuedDate: time.Now().AddDate(-1, 0, 0),
|
||||
}
|
||||
return user
|
||||
})),
|
||||
},
|
||||
{
|
||||
Name: "Correct Licence number, should pass",
|
||||
WantResponse: http.StatusCreated,
|
||||
WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
|
||||
Assert: true,
|
||||
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
user.Email = "john.correctLicenceNumber@example.com"
|
||||
user.Licence = &models.Licence{
|
||||
Number: "B072RRE2I55",
|
||||
ExpirationDate: time.Now().AddDate(1, 0, 0),
|
||||
IssuedDate: time.Now().AddDate(-1, 0, 0),
|
||||
}
|
||||
return user
|
||||
})),
|
||||
},
|
||||
// {
|
||||
// Name: "empty driverslicence number, should fail",
|
||||
// WantResponse: http.StatusBadRequest,
|
||||
// WantDBData: map[string]interface{}{"email": "john.wronglicence.doe@example.com"},
|
||||
// Assert: false,
|
||||
// Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
// user.Email = "john.wronglicence.doe@example.com"
|
||||
// user.Licence = &models.Licence{
|
||||
// Number: "",
|
||||
// ExpirationDate: time.Now().AddDate(1, 0, 0),
|
||||
// IssuedDate: time.Now().AddDate(-1, 0, 0),
|
||||
// }
|
||||
// return user
|
||||
// })),
|
||||
// },
|
||||
// {
|
||||
// Name: "Correct Licence number, should pass",
|
||||
// WantResponse: http.StatusCreated,
|
||||
// WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
|
||||
// Assert: true,
|
||||
// Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
||||
// user.Email = "john.correctLicenceNumber@example.com"
|
||||
// user.Licence = &models.Licence{
|
||||
// Number: "B072RRE2I55",
|
||||
// ExpirationDate: time.Now().AddDate(1, 0, 0),
|
||||
// IssuedDate: time.Now().AddDate(-1, 0, 0),
|
||||
// }
|
||||
// return user
|
||||
// })),
|
||||
// },
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user