feat(admin): handle user demotion & promotion
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
7c6acad689
commit
546600db93
@ -71,7 +71,7 @@ const (
|
|||||||
type requestAdminUpdateUser struct {
|
type requestAdminUpdateUser struct {
|
||||||
User string `form:"user"`
|
User string `form:"user"`
|
||||||
Password *string `form:"password"`
|
Password *string `form:"password"`
|
||||||
isAdmin *bool `form:"is_admin"`
|
IsAdmin *string `form:"is_admin"`
|
||||||
Operation operationType `form:"operation"`
|
Operation operationType `form:"operation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,14 +674,14 @@ func (api *API) restoreData(zipReader *zip.Reader) error {
|
|||||||
destPath := filepath.Join(api.cfg.DataPath, file.Name)
|
destPath := filepath.Join(api.cfg.DataPath, file.Name)
|
||||||
destFile, err := os.Create(destPath)
|
destFile, err := os.Create(destPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error creating destination file:", err)
|
log.Errorf("error creating destination file: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer destFile.Close()
|
defer destFile.Close()
|
||||||
|
|
||||||
// Copy the contents from the zip file to the destination file.
|
// Copy the contents from the zip file to the destination file.
|
||||||
if _, err := io.Copy(destFile, rc); err != nil {
|
if _, err := io.Copy(destFile, rc); err != nil {
|
||||||
fmt.Println("Error copying file contents:", err)
|
log.Errorf("Error copying file contents: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -796,8 +796,8 @@ func (api *API) createUser(createRequest requestAdminUpdateUser) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle Admin (Explicit or False)
|
// Handle Admin (Explicit or False)
|
||||||
if createRequest.isAdmin != nil {
|
if createRequest.IsAdmin != nil {
|
||||||
createParams.Admin = *createRequest.isAdmin
|
createParams.Admin = *createRequest.IsAdmin == "true"
|
||||||
} else {
|
} else {
|
||||||
createParams.Admin = false
|
createParams.Admin = false
|
||||||
}
|
}
|
||||||
@ -835,7 +835,7 @@ func (api *API) updateUser(updateRequest requestAdminUpdateUser) error {
|
|||||||
if updateRequest.User == "" {
|
if updateRequest.User == "" {
|
||||||
return fmt.Errorf("username can't be empty")
|
return fmt.Errorf("username can't be empty")
|
||||||
}
|
}
|
||||||
if updateRequest.Password == nil && updateRequest.isAdmin == nil {
|
if updateRequest.Password == nil && updateRequest.IsAdmin == nil {
|
||||||
return fmt.Errorf("nothing to update")
|
return fmt.Errorf("nothing to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,8 +845,8 @@ func (api *API) updateUser(updateRequest requestAdminUpdateUser) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle Admin (Update or Existing)
|
// Handle Admin (Update or Existing)
|
||||||
if updateRequest.isAdmin != nil {
|
if updateRequest.IsAdmin != nil {
|
||||||
updateParams.Admin = *updateRequest.isAdmin
|
updateParams.Admin = *updateRequest.IsAdmin == "true"
|
||||||
} else {
|
} else {
|
||||||
user, err := api.db.Queries.GetUser(api.db.Ctx, updateRequest.User)
|
user, err := api.db.Queries.GetUser(api.db.Ctx, updateRequest.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -855,8 +855,12 @@ func (api *API) updateUser(updateRequest requestAdminUpdateUser) error {
|
|||||||
updateParams.Admin = user.Admin
|
updateParams.Admin = user.Admin
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// Check Admins
|
||||||
// - Validate Not Last Admin
|
if isLast, err := api.isLastAdmin(updateRequest.User); err != nil {
|
||||||
|
return err
|
||||||
|
} else if isLast {
|
||||||
|
return fmt.Errorf("unable to demote %s - last admin", updateRequest.User)
|
||||||
|
}
|
||||||
|
|
||||||
// Handle Password
|
// Handle Password
|
||||||
if updateRequest.Password != nil {
|
if updateRequest.Password != nil {
|
||||||
@ -891,7 +895,31 @@ func (api *API) updateUser(updateRequest requestAdminUpdateUser) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) deleteUser(updateRequest requestAdminUpdateUser) error {
|
func (api *API) deleteUser(updateRequest requestAdminUpdateUser) error {
|
||||||
// TODO:
|
// Check Admins
|
||||||
// - Validate Not Last Admin
|
if isLast, err := api.isLastAdmin(updateRequest.User); err != nil {
|
||||||
|
return err
|
||||||
|
} else if isLast {
|
||||||
|
return fmt.Errorf("unable to demote %s - last admin", updateRequest.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - Implementation
|
||||||
|
|
||||||
return errors.New("unimplemented")
|
return errors.New("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) isLastAdmin(userID string) (bool, error) {
|
||||||
|
allUsers, err := api.db.Queries.GetUsers(api.db.Ctx)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, fmt.Sprintf("GetUsers DB Error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
hasAdmin := false
|
||||||
|
for _, user := range allUsers {
|
||||||
|
if user.Admin && user.ID != userID {
|
||||||
|
hasAdmin = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !hasAdmin, nil
|
||||||
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -68,11 +68,8 @@
|
|||||||
<form method="POST"
|
<form method="POST"
|
||||||
action="./users"
|
action="./users"
|
||||||
class="flex flex gap-2 text-black dark:text-white text-sm">
|
class="flex flex gap-2 text-black dark:text-white text-sm">
|
||||||
<input type="text"
|
<input type="hidden" id="operation" name="operation" value="UPDATE" />
|
||||||
id="operation"
|
<input type="hidden" id="user" name="user" value="{{ $user.ID }}" />
|
||||||
name="operation"
|
|
||||||
value="UPDATE"
|
|
||||||
class="hidden" />
|
|
||||||
<input type="password"
|
<input type="password"
|
||||||
id="password"
|
id="password"
|
||||||
name="password"
|
name="password"
|
||||||
@ -83,9 +80,29 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="p-3 border-b border-gray-200 text-center min-w-40">
|
<td class="flex gap-2 justify-center p-3 border-b border-gray-200 text-center min-w-40">
|
||||||
<span class="px-2 py-1 rounded-md text-white dark:text-black {{ if $user.Admin }}bg-gray-800 dark:bg-gray-100{{ else }}bg-gray-400 dark:bg-gray-600 cursor-pointer{{ end }}">admin</span>
|
<!-- Set Admin & User Styles -->
|
||||||
<span class="px-2 py-1 rounded-md text-white dark:text-black {{ if $user.Admin }}bg-gray-400 dark:bg-gray-600 cursor-pointer{{ else }}bg-gray-800 dark:bg-gray-100{{ end }}">user</span>
|
{{ $adminStyle := "bg-gray-400 dark:bg-gray-600 cursor-pointer" }}
|
||||||
|
{{ $userStyle := "bg-gray-400 dark:bg-gray-600 cursor-pointer" }}
|
||||||
|
{{ if $user.Admin }}{{ $adminStyle = "bg-gray-800 dark:bg-gray-100 cursor-default" }}{{ end }}
|
||||||
|
{{ if not $user.Admin }}{{ $userStyle = "bg-gray-800 dark:bg-gray-100 cursor-default" }}{{ end }}
|
||||||
|
<form method="POST"
|
||||||
|
action="./users"
|
||||||
|
class="flex flex gap-2 text-black dark:text-white text-sm">
|
||||||
|
<input type="hidden" id="operation" name="operation" value="UPDATE" />
|
||||||
|
<input type="hidden" id="user" name="user" value="{{ $user.ID }}" />
|
||||||
|
<input type="hidden" id="is_admin" name="is_admin" value="true" />
|
||||||
|
<button {{ if $user.Admin }}type="button"{{ else }}type="submit"{{ end }} class="px-2 py-1 rounded-md text-white dark:text-black {{ $adminStyle }}">admin
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<form method="POST"
|
||||||
|
action="./users"
|
||||||
|
class="flex flex gap-2 text-black dark:text-white text-sm">
|
||||||
|
<input type="hidden" id="operation" name="operation" value="UPDATE" />
|
||||||
|
<input type="hidden" id="user" name="user" value="{{ $user.ID }}" />
|
||||||
|
<input type="hidden" id="is_admin" name="is_admin" value="false" />
|
||||||
|
<button {{ if $user.Admin }}type="submit"{{ else }}type="button"{{ end }} class="px-2 py-1 rounded-md text-white dark:text-black {{ $userStyle }}">user
|
||||||
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td class="p-3 border-b border-gray-200">
|
<td class="p-3 border-b border-gray-200">
|
||||||
<p>{{ $user.CreatedAt }}</p>
|
<p>{{ $user.CreatedAt }}</p>
|
||||||
@ -94,6 +111,6 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
Loading…
Reference in New Issue
Block a user