Concepts of modular tonton web application that share authentication

This commit is contained in:
Mateus Cezário Barreto 2025-11-21 00:17:42 -03:00
commit eb759a8454
7 changed files with 192 additions and 75 deletions

109
lib/tonton_web/app.rb Normal file
View file

@ -0,0 +1,109 @@
require_relative 'auth'
require "warden"
require 'sinatra/flash'
Warden::Manager.serialize_from_session do |id|
TonTonWeb::App.find_user id: id
end
Warden::Manager.serialize_into_session do |user|
user.id
end
Warden::Manager.before_failure do |env,opts|
env['REQUEST_METHOD'] = "POST"
env['rack.session']['warden.options'] = opts
end
Warden::Strategies.add(:password) do
def valid?
params['user'] && params['user']['username'] && params['user']['password']
end
def authenticate!
user_params = params['user']
user = TonTonWeb::App.authenticate user_params['username'], user_params['password']
if not user
throw(:warden)
else
success!(user)
end
end
end
class TonTonWeb::App < Sinatra::Base
@db = SQLite3::Database.new(Dir.getwd + '/database.sqlite')
register Sinatra::Flash
register TonTonWeb::Auth
use Warden::Manager do |manager|
manager.default_strategies :password
manager.failure_app = self
manager.scope_defaults :default, strategies: [:password], action: 'unauthenticated'
end
helpers do
def check_authentication
if not env['warden'].authenticated?
flash[:error] = 'You must log in to access this page.'
redirect '/login'
end
end
def current_user
env['warden'].user
end
end
set :host_authorization, { permitted_hosts: ['localhost', 'mytonton.com.br'] }
get '/' do
redirect "/readme.md"
end
get '/status' do
puts env['warden']
check_authentication
"Hello"
end
post '/unauthenticated' do
session['warden.return_to'] = env['warden.options'][:attempted_path]
flash[:error] = 'You must log in to access this page.'
redirect '/login'
end
get '/login' do
@error = flash[:error]
erb :login
end
post '/login' do
env['warden'].authenticate!
if env['warden'].authenticated?
redirect_path = session.delete('warden.return_to') || '/'
redirect redirect_path
else
redirect '/login'
end
end
get '/logout' do
env['warden'].logout
redirect '/'
end
end

View file

@ -4,70 +4,63 @@ require 'bcrypt'
module TonTonWeb
User = Struct.new(:id, :name, :username, :email, :password_digest)
end
class Auth
attr_reader :root
module TonTonWeb::Auth
def create_tables
@db.execute "create table users (id integer primary key, name text, username text, email text, password_digest text);"
end
def initialize root_path
@root = Pathname.new root_path
def create_user **options
name = options.fetch :name
username = options.fetch :username
email = options.fetch :email
password = options.fetch :password
@db = SQLite3::Database.new(@root+ 'database.sqlite')
# Assert user doesn't exists
hashed_password = BCrypt::Password.create(password)
@db.execute(
"insert into users (name, username, email, password_digest) values (?,?,?,?);",
[name, username, email, hashed_password]
)
return # Return user
end
def delete_user id
@db.execute "delete from users where id = ?;", id
end
def find_user **options
id = options[:id]
name = options[:name]
username = options[:username]
email = options[:email]
if not (id or name or username or email)
raise "No options to find user."
end
def create_tables
@db.execute "create table users (id integer primary key, name text, username text, email text, password_digest text);"
user = nil
user_query_template = "select id, name, username, email, password_digest from users where id = ? or name = ? or username = ? or email = ?"
@db.execute(user_query_template, [id, name, username, email]) do |row|
user = TonTonWeb::User.new(*row)
end
def create_user **options
name = options.fetch :name
username = options.fetch :username
email = options.fetch :email
password = options.fetch :password
return user
end
# Assert user doesn't exists
hashed_password = BCrypt::Password.create(password)
@db.execute(
"insert into users (name, username, email, password_digest) values (?,?,?,?);",
[name, username, email, password]
)
return # Return user
end
def delete_user id
@db.execute "delete from users where id = ?;", id
end
def find_user **options
name = options[:name]
username = options[:username]
email = options[:email]
if not (name or username or email)
raise "No options to find user."
end
user = nil
user_query_template = "select id, name, username, email, password_digest from users where name = ? or username = ? or email = ?"
@db.execute(user_query_template, [name, username, email]) do |row|
user = TonTonWeb::User.new(*row)
end
def authenticate username, password
user = find_user(username: username)
if BCrypt::Password.new(user.password_digest) == password
return user
end
def authenticate username, password
user = find_user(username: username)
if BCrypt::Password.new(user.password_digest) == password
return user
else
return false
end
else
return false
end
end
end