mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Merge pull request #378 from Freika/feature/user-management
Basic user management
This commit is contained in:
commit
bb9fc2d97b
11 changed files with 168 additions and 31 deletions
|
|
@ -1 +1 @@
|
|||
0.16.3
|
||||
0.16.4
|
||||
|
|
|
|||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# 0.16.4 - 2024-11-12
|
||||
|
||||
### Added
|
||||
|
||||
- Admins can now see all users in the system on the Users page. The path is `/settings/users`.
|
||||
|
||||
### Changed
|
||||
|
||||
- Admins can now provide custom password for new users and update passwords for existing users on the Users page.
|
||||
|
||||
# 0.16.3 - 2024-11-10
|
||||
|
||||
### Fixed
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -14,7 +14,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def authenticate_admin!
|
||||
return if current_user.admin?
|
||||
return if current_user&.admin?
|
||||
|
||||
redirect_to root_path, notice: 'You are not authorized to perform this action.', status: :see_other
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,24 +4,51 @@ class Settings::UsersController < ApplicationController
|
|||
before_action :authenticate_user!
|
||||
before_action :authenticate_admin!
|
||||
|
||||
def index
|
||||
@users = User.order(created_at: :desc)
|
||||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(params[:id])
|
||||
|
||||
if @user.update(user_params)
|
||||
redirect_to settings_users_url, notice: 'User was successfully updated.'
|
||||
else
|
||||
redirect_to settings_users_url, notice: 'User could not be updated.', status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.new(
|
||||
email: user_params[:email],
|
||||
password: 'password',
|
||||
password_confirmation: 'password'
|
||||
password: user_params[:password],
|
||||
password_confirmation: user_params[:password]
|
||||
)
|
||||
|
||||
if @user.save
|
||||
redirect_to settings_url,
|
||||
notice: "User was successfully created, email is #{@user.email}, password is \"password\"."
|
||||
redirect_to settings_users_url, notice: 'User was successfully created'
|
||||
else
|
||||
redirect_to settings_url, notice: 'User could not be created.', status: :unprocessable_entity
|
||||
redirect_to settings_users_url, notice: 'User could not be created.', status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@user = User.find(params[:id])
|
||||
|
||||
if @user.destroy
|
||||
redirect_to settings_url, notice: 'User was successfully deleted.'
|
||||
else
|
||||
redirect_to settings_url, notice: 'User could not be deleted.', status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:email)
|
||||
params.require(:user).permit(:email, :password)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
<div role="tablist" class="tabs tabs-lifted tabs-lg">
|
||||
<%= link_to 'Main', settings_path, role: 'tab', class: "tab #{active_tab?(settings_path)}" %>
|
||||
<%= link_to 'Background Jobs', settings_background_jobs_path, role: 'tab', class: "tab #{active_tab?(settings_background_jobs_path)}" %>
|
||||
<% if current_user.admin? %>
|
||||
<%= link_to 'Users', settings_users_path, role: 'tab', class: "tab #{active_tab?(settings_users_path)}" %>
|
||||
<%= link_to 'Background Jobs', settings_background_jobs_path, role: 'tab', class: "tab #{active_tab?(settings_background_jobs_path)}" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,19 +20,5 @@
|
|||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||
<h2 class="text-2xl font-bold">Create a new user!</h1>
|
||||
<%= form_for :user, url: settings_users_path, method: :post, data: { turbo_method: :post, turbo: false } do |f| %>
|
||||
<div class="form-control">
|
||||
<%= f.label :email do %>
|
||||
Email
|
||||
<% end %>
|
||||
<%= f.email_field :email, value: '', class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control mt-5">
|
||||
<%= f.submit "Create", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
28
app/views/settings/users/edit.html.erb
Normal file
28
app/views/settings/users/edit.html.erb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<% content_for :title, 'Editing user' %>
|
||||
|
||||
<div class="min-h-content w-full">
|
||||
<%= render 'settings/navigation' %>
|
||||
|
||||
<div class="flex w-full my-10 space-x-4">
|
||||
<div class="overflow-x-auto w-4/12 mx-auto">
|
||||
<h1 class="text-2xl font-bold">Editing user</h1>
|
||||
<%= form_for @user, url: settings_user_path(@user), method: :put, data: { turbo_method: :put, turbo: false } do |f| %>
|
||||
<div class="form-control">
|
||||
<%= f.label :email do %>
|
||||
Email
|
||||
<% end %>
|
||||
<%= f.email_field :email, value: @user.email, class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<%= f.label :password do %>
|
||||
Password
|
||||
<% end %>
|
||||
<%= f.password_field :password, autofocus: true, autocomplete: "new-password", class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control mt-5">
|
||||
<%= f.submit "Update", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
63
app/views/settings/users/index.html.erb
Normal file
63
app/views/settings/users/index.html.erb
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<% content_for :title, 'Users' %>
|
||||
|
||||
<div class="min-h-content w-full">
|
||||
<%= render 'settings/navigation' %>
|
||||
|
||||
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
|
||||
<div class="overflow-x-auto w-10/12 mx-auto">
|
||||
<button class="btn" onclick="create_user.showModal()">Add new user</button>
|
||||
<table class="table w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th>Points</th>
|
||||
<th>Created at</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @users.each do |user| %>
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
<%= link_to user.email, edit_settings_user_path(user), class: 'font-bold underline hover:no-underline' %>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<%= number_with_delimiter user.tracked_points.count %>
|
||||
</td>
|
||||
<td>
|
||||
<%= user.created_at.strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog id="create_user" class="modal">
|
||||
<div class="modal-box">
|
||||
<h2 class="text-2xl font-bold">Create a new user!</h1>
|
||||
<%= form_for :user, url: settings_users_path, method: :post, data: { turbo_method: :post, turbo: false } do |f| %>
|
||||
<div class="form-control">
|
||||
<%= f.label :email do %>
|
||||
Email
|
||||
<% end %>
|
||||
<%= f.email_field :email, value: '', class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<%= f.label :password do %>
|
||||
Password
|
||||
<% end %>
|
||||
<%= f.password_field :password, autofocus: true, autocomplete: "new-password", class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control mt-5">
|
||||
<%= f.submit "Create", class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
|
|
@ -19,7 +19,7 @@ Rails.application.routes.draw do
|
|||
resources :settings, only: :index
|
||||
namespace :settings do
|
||||
resources :background_jobs, only: %i[index create destroy]
|
||||
resources :users, only: :create
|
||||
resources :users, only: %i[index create destroy edit update]
|
||||
end
|
||||
|
||||
patch 'settings', to: 'settings#update'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe '/settings/users', type: :request do
|
||||
let(:valid_attributes) { { email: 'user@domain.com' } }
|
||||
let(:valid_attributes) { { email: 'user@domain.com', password: '4815162342' } }
|
||||
let!(:admin) { create(:user, :admin) }
|
||||
|
||||
context 'when user is not authenticated' do
|
||||
it 'redirects to sign in page' do
|
||||
|
|
@ -25,8 +26,6 @@ RSpec.describe '/settings/users', type: :request do
|
|||
end
|
||||
|
||||
context 'when user is an admin' do
|
||||
let!(:admin) { create(:user, :admin) }
|
||||
|
||||
describe 'POST /create' do
|
||||
before { sign_in admin }
|
||||
|
||||
|
|
@ -35,13 +34,16 @@ RSpec.describe '/settings/users', type: :request do
|
|||
expect do
|
||||
post settings_users_url, params: { user: valid_attributes }
|
||||
end.to change(User, :count).by(1)
|
||||
|
||||
expect(User.last.email).to eq(valid_attributes[:email])
|
||||
expect(User.last.valid_password?(valid_attributes[:password])).to be_truthy
|
||||
end
|
||||
|
||||
it 'redirects to the created settings_user' do
|
||||
post settings_users_url, params: { user: valid_attributes }
|
||||
|
||||
expect(response).to redirect_to(settings_url)
|
||||
expect(flash[:notice]).to eq("User was successfully created, email is #{valid_attributes[:email]}, password is \"password\".")
|
||||
expect(response).to redirect_to(settings_users_url)
|
||||
expect(flash[:notice]).to eq('User was successfully created')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -61,6 +63,24 @@ RSpec.describe '/settings/users', type: :request do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH /update' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before { sign_in admin }
|
||||
|
||||
context 'with valid parameters' do
|
||||
let(:new_attributes) { { email: FFaker::Internet.email, password: '4815162342' } }
|
||||
|
||||
it 'updates the requested user' do
|
||||
patch settings_user_url(user), params: { user: new_attributes }
|
||||
|
||||
user.reload
|
||||
expect(user.email).to eq(new_attributes[:email])
|
||||
expect(user.valid_password?(new_attributes[:password])).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue