[ First commit ]

This commit is contained in:
Mateus Cezário Barreto 2025-11-02 15:33:20 -03:00
commit 25db02e2a1
5 changed files with 200 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
wiki/
database.sqlite

8
Gemfile Normal file
View file

@ -0,0 +1,8 @@
source "https://rubygems.org"
gem 'gollum'
gem 'sinatra'
gem 'puma'
gem 'warden'
gem 'sqlite3'
gem 'sinatra-flash'

13
config.ru Normal file
View file

@ -0,0 +1,13 @@
require 'gollum/app'
require 'warden'
wiki_options = {universal_toc: false, math: :mathjax, css: true}
Precious::App.set(:gollum_path, ENV['GOLLUM_WIKI'])
Precious::App.set(:default_markup, :markdown)
Precious::App.set(:wiki_options, wiki_options)
require_relative 'tonton'
use Rack::Session::Cookie, key: 'rack.session', secret: ENV.fetch('SESSION_SECRET')
run TonTon::App

155
tonton.rb Normal file
View file

@ -0,0 +1,155 @@
require 'gollum/app'
require 'warden'
require 'sinatra/flash'
require 'securerandom'
require "sqlite3"
class TonTon
end
TonTon::User = Struct.new(:id, :username, :email, :name, :password)
Warden::Manager.serialize_into_session do |user|
user.id
end
Warden::Manager.serialize_from_session do |id|
TonTon::App.find_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 = TonTon::App.find_user_by_username user_params['username']
if user and user.password == user_params['password']
success!(user)
else
throw(:warden)
end
end
end
class TonTon::App < Precious::App
use Warden::Manager do |manager|
manager.default_strategies :password
manager.failure_app = self
manager.scope_defaults :default, strategies: [:password], action: 'unauthenticated'
end
register Sinatra::Flash
set :root, File.dirname(__FILE__)
@db = SQLite3::Database.new "database.sqlite"
def self.find_user id
user = nil
@db.execute("select id, username, email, name, password from users where id = ?", id) do |row|
user = TonTon::User.new(*row)
end
return user
end
def self.find_user_by_username username
user = nil
@db.execute("select id, username, email, name, password from users where username = ?", username) do |row|
user = TonTon::User.new(*row)
end
return user
end
helpers do
def check_authentication
if not env['warden'].authenticated?
flash[:error] = 'You must log in to access this page.'
redirect '/login'
else
session['gollum.author'] = {
name: current_user.name,
email: current_user.email
}
end
end
def current_user
env['warden'].user
end
end
before do
public_patterns = [
'/',
'/*',
'/login',
'/logout',
'/unauthenticated',
'/gollum/*',
'/gollum/history/**',
'/gollum/latest_changes',
'/gollum/commit/**'
]
request_path = Pathname.new(request.path_info)
looks_public = false
for pattern in public_patterns
if request_path.fnmatch(pattern, File::FNM_PATHNAME)
looks_public = true
end
end
if not looks_public then check_authentication end
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

20
views/login.erb Normal file
View file

@ -0,0 +1,20 @@
<h2>Login</h2>
<% if @error %>
<p style="color: red; font-weight: bold;">
<%= @error %>
</p>
<% end %>
<form method="POST" action="/login">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="user[username]" required>
</div>
<br>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="user[password]" required>
</div>
<br>
<button type="submit">Log In</button>
</form>