Merge pull request #91 from Freika/disable-registration

Disable registration and implement user creation in the settings page
This commit is contained in:
Evgenii Burmakin
2024-06-30 12:58:49 +02:00
committed by GitHub
19 changed files with 156 additions and 39 deletions

View File

@@ -1 +1 @@
0.8.0
0.8.1

View File

@@ -5,6 +5,19 @@ 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.8.1] — 2024-06-30
### Added
- First user in the system can now create new users from the Settings page. This is useful for creating new users without the need to enable registrations. Default password for new users is `password`.
### Changed
- Registrations are now disabled by default. On the initial setup, a default user with email `user@domain.com` and password `password` is created. You can change the password in the Settings page.
- On the Imports page, now you can see the real number of points imported. Previously, this number might have not reflect the real number of points imported.
---
## [0.8.0] — 2024-06-25
### Added

File diff suppressed because one or more lines are too long

View 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

View File

@@ -7,7 +7,7 @@
<%= render 'devise/registrations/api_key' %>
</div>
<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">
<%= f.label :email, class: 'label' do %>
<span class="label-text">Email</span>

View File

@@ -5,12 +5,6 @@
</div>
<% end %>
<% if devise_mapping.registerable? && controller_name != 'registrations' %>
<div class='my-2'>
<%= link_to "Sign up", new_registration_path(resource_name) %>
</div>
<% end %>
<% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<div class='my-2'>
<%= link_to "Forgot your password?", new_password_path(resource_name) %>

View File

@@ -6,7 +6,7 @@
<h1 class="text-5xl font-bold">Dawarich</h1>
<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" %>
</div>
</div>

View File

@@ -1,16 +1,4 @@
<%= form_with model: import, class: "contents" do |form| %>
<% if import.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(import.errors.count, "error") %> prohibited this import from being saved:</h2>
<ul>
<% import.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-control w-full max-w-xs">
<label class="label">
<span class="label-text">Select source</span>

View File

@@ -21,12 +21,10 @@
<% else %>
<div class="overflow-x-auto">
<table class="table">
<!-- head -->
<thead>
<tr>
<th>Name</th>
<th>Processed</th>
<th>Doubles</th>
<th>Imported points</th>
<th>Created at</th>
</tr>
</thead>
@@ -37,10 +35,8 @@
<%= link_to import.name, import, class: 'underline hover:no-underline' %> (<%= import.source %>)
</td>
<td>
<%= "✅" if import.processed == import.raw_points %>
<%= "#{import.processed}/#{import.raw_points}" %>
<%= "#{number_with_delimiter import.points.size}" %>
</td>
<td><%= import.doubles %></td>
<td><%= import.created_at.strftime("%d.%m.%Y, %H:%M") %></td>
</tr>
<% end %>

View File

@@ -1,11 +1,9 @@
<% content_for :title, 'Settings' %>
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full my-10">
<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="min-h-content bg-base-200 w-full">
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5 mx-5">
<h2 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| %>
<div class="form-control my-2">
<%= f.label :meters_between_routes do %>
@@ -85,5 +83,19 @@
</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>

View File

@@ -64,7 +64,6 @@
</details>
<% else %>
<li><%= link_to 'Login', new_user_session_path %></li>
<li><%= link_to 'Register', new_user_registration_path %></li>
<% end %>
</ul>
</div>

View File

@@ -8,6 +8,9 @@ Rails.application.routes.draw do
mount Sidekiq::Web => '/sidekiq'
resources :settings, only: :index
namespace :settings do
resources :users, only: :create
end
patch 'settings', to: 'settings#update'
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}/ }
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'

View File

@@ -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

4
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# 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
enable_extension "plpgsql"
@@ -135,7 +135,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_20_205120) do
t.datetime "updated_at", null: false
t.string "api_key", default: "", 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 ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

View File

@@ -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'"

View File

@@ -32,5 +32,9 @@ bundle exec rails db:prepare
echo "Running DATA migrations..."
bundle exec rake data:migrate
# Run seeds
echo "Running seeds..."
bundle exec rake db:seed
# run passed commands
bundle exec ${@}

View File

@@ -1,7 +1,10 @@
# frozen_string_literal: true
require 'rails_helper'
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
{ user: FactoryBot.attributes_for(:user) }
end

View File

@@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Homes', type: :request do
@@ -9,6 +11,7 @@ RSpec.describe 'Homes', type: :request do
it 'returns http success' do
get '/'
expect(response).to have_http_status(:success)
end
end

View 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