[ First commit ]
This commit is contained in:
commit
25db02e2a1
5 changed files with 200 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
wiki/
|
||||||
|
|
||||||
|
database.sqlite
|
||||||
|
|
||||||
8
Gemfile
Normal file
8
Gemfile
Normal 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
13
config.ru
Normal 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
155
tonton.rb
Normal 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
20
views/login.erb
Normal 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>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue