mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 01:31:39 -05:00
Disable registration and implement user creation in the settings page
This commit is contained in:
parent
1fee34b3db
commit
2c9a88aba4
22 changed files with 229 additions and 22 deletions
File diff suppressed because one or more lines are too long
32
app/controllers/settings/users_controller.rb
Normal file
32
app/controllers/settings/users_controller.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Settings::UsersController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
before_action :authenticate_first_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
@user = User.new(
|
||||||
|
email: user_params[:email],
|
||||||
|
password: 'password',
|
||||||
|
password_confirmation: 'password'
|
||||||
|
)
|
||||||
|
|
||||||
|
if @user.save
|
||||||
|
redirect_to settings_url, notice: "User was successfully created, email is #{@user.email}, password is \"password\"."
|
||||||
|
else
|
||||||
|
redirect_to settings_url, notice: 'User could not be created.', status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def user_params
|
||||||
|
params.require(:user).permit(:email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_first_user!
|
||||||
|
return if current_user == User.first
|
||||||
|
|
||||||
|
redirect_to settings_users_url, notice: 'You are not authorized to perform this action.', status: :unauthorized
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<%= render 'devise/registrations/api_key' %>
|
<%= render 'devise/registrations/api_key' %>
|
||||||
</div>
|
</div>
|
||||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body', html: { method: :put }) do |f| %>
|
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), class: 'form-body', method: :put, data: { turbo_method: :put, turbo: false }) do |f| %>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<%= f.label :email, class: 'label' do %>
|
<%= f.label :email, class: 'label' do %>
|
||||||
<span class="label-text">Email</span>
|
<span class="label-text">Email</span>
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% if devise_mapping.registerable? && controller_name != 'registrations' %>
|
<%# if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||||
<div class='my-2'>
|
<%# <div class='my-2'> %>
|
||||||
<%= link_to "Sign up", new_registration_path(resource_name) %>
|
<%#= link_to "Sign up", new_registration_path(resource_name) %>
|
||||||
</div>
|
<%# </div> %>
|
||||||
<% end %>
|
<%# end %>
|
||||||
|
|
||||||
<% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
<% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||||
<div class='my-2'>
|
<div class='my-2'>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<h1 class="text-5xl font-bold">Dawarich</h1>
|
<h1 class="text-5xl font-bold">Dawarich</h1>
|
||||||
<p class="py-6 text-3xl">The only Dawarich you'll ever need.</p>
|
<p class="py-6 text-3xl">The only Dawarich you'll ever need.</p>
|
||||||
|
|
||||||
<%= link_to 'Sign up', new_user_registration_path, class: "rounded-lg py-3 px-5 my-3 bg-blue-600 text-white block font-medium" %>
|
<%#= link_to 'Sign up', new_user_registration_path, class: "rounded-lg py-3 px-5 my-3 bg-blue-600 text-white block font-medium" %>
|
||||||
<%= link_to 'Sign in', new_user_session_path, class: "rounded-lg py-3 px-5 bg-neutral text-neutral-content block font-medium" %>
|
<%= link_to 'Sign in', new_user_session_path, class: "rounded-lg py-3 px-5 bg-neutral text-neutral-content block font-medium" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Processed</th>
|
<th>Processed</th>
|
||||||
<th>Doubles</th>
|
|
||||||
<th>Created at</th>
|
<th>Created at</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -37,10 +36,8 @@
|
||||||
<%= link_to import.name, import, class: 'underline hover:no-underline' %> (<%= import.source %>)
|
<%= link_to import.name, import, class: 'underline hover:no-underline' %> (<%= import.source %>)
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<%= "✅" if import.processed == import.raw_points %>
|
<%= "#{number_with_delimiter import.points.size}" %>
|
||||||
<%= "#{import.processed}/#{import.raw_points}" %>
|
|
||||||
</td>
|
</td>
|
||||||
<td><%= import.doubles %></td>
|
|
||||||
<td><%= import.created_at.strftime("%d.%m.%Y, %H:%M") %></td>
|
<td><%= import.created_at.strftime("%d.%m.%Y, %H:%M") %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
<% content_for :title, 'Settings' %>
|
<% content_for :title, 'Settings' %>
|
||||||
|
|
||||||
<div class="hero min-h-content bg-base-200">
|
<div class="min-h-content bg-base-200 w-full">
|
||||||
<div class="hero-content flex-col lg:flex-row-reverse w-full my-10">
|
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
|
||||||
<div class="text-center lg:text-left">
|
|
||||||
<h1 class="text-5xl font-bold">Edit your Dawarich settings!</h1>
|
|
||||||
</div>
|
|
||||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||||
|
<h1 class="text-2xl font-bold">Edit your Dawarich settings!</h1>
|
||||||
<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
|
<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
|
||||||
<div class="form-control my-2">
|
<div class="form-control my-2">
|
||||||
<%= f.label :meters_between_routes do %>
|
<%= f.label :meters_between_routes do %>
|
||||||
|
|
@ -85,5 +83,18 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
|
||||||
|
<%= 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>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
17
app/views/settings/users/_form.html.erb
Normal file
17
app/views/settings/users/_form.html.erb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<%= form_with(model: settings_user, class: "contents") do |form| %>
|
||||||
|
<% if settings_user.errors.any? %>
|
||||||
|
<div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3">
|
||||||
|
<h2><%= pluralize(settings_user.errors.count, "error") %> prohibited this settings_user from being saved:</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<% settings_user.errors.each do |error| %>
|
||||||
|
<li><%= error.full_message %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="inline">
|
||||||
|
<%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
2
app/views/settings/users/_user.html.erb
Normal file
2
app/views/settings/users/_user.html.erb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<div id="<%= dom_id user %>">
|
||||||
|
</div>
|
||||||
8
app/views/settings/users/edit.html.erb
Normal file
8
app/views/settings/users/edit.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="mx-auto md:w-2/3 w-full">
|
||||||
|
<h1 class="font-bold text-4xl">Editing user</h1>
|
||||||
|
|
||||||
|
<%= render "form", settings_user: @settings_user %>
|
||||||
|
|
||||||
|
<%= link_to "Show this user", @settings_user, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
<%= link_to "Back to users", settings_users_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
</div>
|
||||||
21
app/views/settings/users/index.html.erb
Normal file
21
app/views/settings/users/index.html.erb
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="w-full">
|
||||||
|
<% if notice.present? %>
|
||||||
|
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% content_for :title, "Users" %>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<h1 class="font-bold text-4xl">Users</h1>
|
||||||
|
<%= link_to "New user", new_settings_user_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="settings_users" class="min-w-full">
|
||||||
|
<% @settings_users.each do |settings_user| %>
|
||||||
|
<%= render settings_user %>
|
||||||
|
<p>
|
||||||
|
<%= link_to "Show this user", settings_user, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
7
app/views/settings/users/new.html.erb
Normal file
7
app/views/settings/users/new.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="mx-auto md:w-2/3 w-full">
|
||||||
|
<h1 class="font-bold text-4xl">New user</h1>
|
||||||
|
|
||||||
|
<%= render "form", settings_user: @settings_user %>
|
||||||
|
|
||||||
|
<%= link_to "Back to users", settings_users_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
</div>
|
||||||
15
app/views/settings/users/show.html.erb
Normal file
15
app/views/settings/users/show.html.erb
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="mx-auto md:w-2/3 w-full flex">
|
||||||
|
<div class="mx-auto">
|
||||||
|
<% if notice.present? %>
|
||||||
|
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render @settings_user %>
|
||||||
|
|
||||||
|
<%= link_to "Edit this user", edit_settings_user_path(@settings_user), class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
<%= link_to "Back to users", settings_users_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
|
||||||
|
<div class="inline-block ml-2">
|
||||||
|
<%= button_to "Destroy this user", @settings_user, method: :delete, class: "mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
</details>
|
</details>
|
||||||
<% else %>
|
<% else %>
|
||||||
<li><%= link_to 'Login', new_user_session_path %></li>
|
<li><%= link_to 'Login', new_user_session_path %></li>
|
||||||
<li><%= link_to 'Register', new_user_registration_path %></li>
|
<li><%#= link_to 'Register', new_user_registration_path %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ Rails.application.routes.draw do
|
||||||
mount Sidekiq::Web => '/sidekiq'
|
mount Sidekiq::Web => '/sidekiq'
|
||||||
|
|
||||||
resources :settings, only: :index
|
resources :settings, only: :index
|
||||||
|
namespace :settings do
|
||||||
|
resources :users
|
||||||
|
end
|
||||||
|
|
||||||
patch 'settings', to: 'settings#update'
|
patch 'settings', to: 'settings#update'
|
||||||
get 'settings/theme', to: 'settings#theme'
|
get 'settings/theme', to: 'settings#theme'
|
||||||
|
|
@ -28,7 +31,13 @@ Rails.application.routes.draw do
|
||||||
get 'stats/:year', to: 'stats#show', constraints: { year: /\d{4}/ }
|
get 'stats/:year', to: 'stats#show', constraints: { year: /\d{4}/ }
|
||||||
|
|
||||||
root to: 'home#index'
|
root to: 'home#index'
|
||||||
devise_for :users
|
devise_for :users, skip: [:registrations]
|
||||||
|
as :user do
|
||||||
|
get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'
|
||||||
|
put 'users' => 'devise/registrations#update', :as => 'user_registration'
|
||||||
|
end
|
||||||
|
|
||||||
|
# And then modify the app/views/devise/shared/_links.erb
|
||||||
|
|
||||||
get 'map', to: 'map#index'
|
get 'map', to: 'map#index'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddFogOfWarToDefaultSettings < ActiveRecord::Migration[7.1]
|
||||||
|
def change
|
||||||
|
change_column_default :users, :settings,
|
||||||
|
from: { meters_between_routes: '1000', minutes_between_routes: '60' },
|
||||||
|
to: { fog_of_war_meters: '100', meters_between_routes: '1000', minutes_between_routes: '60' }
|
||||||
|
end
|
||||||
|
end
|
||||||
18
db/schema.rb
generated
18
db/schema.rb
generated
|
|
@ -10,10 +10,24 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_06_20_205120) do
|
ActiveRecord::Schema[7.1].define(version: 2024_06_30_093005) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
create_table "active_admin_comments", force: :cascade do |t|
|
||||||
|
t.string "namespace"
|
||||||
|
t.text "body"
|
||||||
|
t.string "resource_type"
|
||||||
|
t.bigint "resource_id"
|
||||||
|
t.string "author_type"
|
||||||
|
t.bigint "author_id"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author"
|
||||||
|
t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
|
||||||
|
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "active_storage_attachments", force: :cascade do |t|
|
create_table "active_storage_attachments", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "record_type", null: false
|
t.string "record_type", null: false
|
||||||
|
|
@ -135,7 +149,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_20_205120) do
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "api_key", default: "", null: false
|
t.string "api_key", default: "", null: false
|
||||||
t.string "theme", default: "dark", null: false
|
t.string "theme", default: "dark", null: false
|
||||||
t.jsonb "settings", default: {"meters_between_routes"=>500, "minutes_between_routes"=>60}
|
t.jsonb "settings", default: {"fog_of_war_meters"=>"200", "meters_between_routes"=>"1000", "minutes_between_routes"=>"60"}
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
end
|
end
|
||||||
|
|
|
||||||
11
db/seeds.rb
11
db/seeds.rb
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
return if User.any?
|
||||||
|
|
||||||
|
User.create!(
|
||||||
|
email: 'user@domain.com',
|
||||||
|
password: 'password',
|
||||||
|
password_confirmation: 'password'
|
||||||
|
)
|
||||||
|
|
||||||
|
puts "User created: #{User.first.email} / password: 'password'"
|
||||||
|
|
@ -32,5 +32,9 @@ bundle exec rails db:prepare
|
||||||
echo "Running DATA migrations..."
|
echo "Running DATA migrations..."
|
||||||
bundle exec rake data:migrate
|
bundle exec rake data:migrate
|
||||||
|
|
||||||
|
# Run seeds
|
||||||
|
echo "Running seeds..."
|
||||||
|
bundle exec rake db:seed
|
||||||
|
|
||||||
# run passed commands
|
# run passed commands
|
||||||
bundle exec ${@}
|
bundle exec ${@}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe 'users', type: :request do
|
RSpec.describe 'users', type: :request do
|
||||||
describe 'POST /create' do
|
# Skip this because user registration is disabled
|
||||||
|
xdescribe 'POST /create' do
|
||||||
let(:user_params) do
|
let(:user_params) do
|
||||||
{ user: FactoryBot.attributes_for(:user) }
|
{ user: FactoryBot.attributes_for(:user) }
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe 'Homes', type: :request do
|
RSpec.describe 'Homes', type: :request do
|
||||||
|
|
@ -9,6 +11,7 @@ RSpec.describe 'Homes', type: :request do
|
||||||
|
|
||||||
it 'returns http success' do
|
it 'returns http success' do
|
||||||
get '/'
|
get '/'
|
||||||
|
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
44
spec/requests/settings/users_spec.rb
Normal file
44
spec/requests/settings/users_spec.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe '/settings/users', type: :request do
|
||||||
|
before do
|
||||||
|
sign_in create(:user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST /create' do
|
||||||
|
context 'with valid parameters' do
|
||||||
|
let(:valid_attributes) { { email: 'user@domain.com' } }
|
||||||
|
|
||||||
|
it 'creates a new User' do
|
||||||
|
expect do
|
||||||
|
post settings_users_url, params: { user: valid_attributes }
|
||||||
|
end.to change(User, :count).by(1)
|
||||||
|
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\".")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with invalid parameters' do
|
||||||
|
let(:invalid_attributes) { { email: nil } }
|
||||||
|
|
||||||
|
it 'does not create a new User' do
|
||||||
|
expect do
|
||||||
|
post settings_users_url, params: { user: invalid_attributes }
|
||||||
|
end.to change(User, :count).by(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders a response with 422 status (i.e. to display the "new" template)' do
|
||||||
|
post settings_users_url, params: { user: invalid_attributes }
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue