Commit a2592770 authored by Cool Fire's avatar Cool Fire

Test release of signup site

parent b038dcfa
Pipeline #1084 failed with stages
in 1 minute and 13 seconds
......@@ -44,17 +44,17 @@ rack_test_2-4:
stage: testing
image: ruby:2.4-alpine
script:
- gem install simplecov rack-test --no-ri --no-rdoc
- bundle install
- touch .current
- ruby deployment/create_config.rb > config.yaml
- ruby test.rb
rack_test_2-3:
stage: testing
image: ruby:2.3-alpine
script:
- gem install simplecov rack-test --no-ri --no-rdoc
- bundle install
- touch .current
- ruby deployment/create_config.rb > config.yaml
- ruby test.rb
deploy_to_production:
stage: deploy
......
---
Metrics/LineLength:
Max: 120
Metrics/ClassLength:
Enabled: false
Metrics/MethodLength:
Enabled: false
Metrics/AbcSize:
Enabled: false
Metrics/BlockLength:
Enabled: false
Layout/AlignHash:
EnforcedHashRocketStyle: table
AllCops:
Exclude:
- test.rb
# frozen_string_literal: true
source 'https://rubygems.org'
gem 'mysql2'
gem 'pony'
gem 'sinatra'
group :test, :development do
gem 'rack-test'
gem 'rubocop'
gem 'simplecov'
gem 'yamllint'
end
# frozen_string_literal: true
require File.expand_path '../signup_site.rb', __FILE__
require File.expand_path 'signup_site.rb', __dir__
run SignupSite.new
---
error_message_username: The username you entered appears to be invalid. Please go back and try again.
error_message_email: The e-mail address you entered appears to be invalid. Please go back and try again.
error_message_phone: The phone number you entered appears to be invalid. Please go back and try again. Note that the phone number is an optional field and may be left empty.
error_message_reason: It appears you have not specified a reason. This is technically allowed but makes it extremely unlikely your application will be accepted.
error_message_username_in_use: The username you have chosen is already in use. Please go back and try another username.
......@@ -2,7 +2,7 @@
header: Insomnia 24/7 shells signup
blurb: |
<h3>Specifying your reasons</h3>
<p>If you have an invite code you need not enter any additional reasons, though you are free to add them if you so desire. For those of you who do not have an invite code, please be as detailed as possible. Describe what projects you have planned or are working on now, what role our shell server would play in the development process, and why you cannot use another free service such as a free web host or GitHub for example. Add anything else you feel is relevant or may help us decide to give you a shell account.</p>
<p>If you have an invite code you need not enter any additional reasons, though you are free to add them if you so desire. For those of you who do not have an invite code, please be as detailed as possible. Describe what projects you have planned or are working on now, what role our shell server would play in the development process, and why you cannot use another free service such as a free web host or Github for example. Add anything else you feel is relevant or may help us decide to give you a shell account. If you have any question or doubts about any of this please stop by <a class="text-info" href="https://chat.insomnia247.nl:9000/">our chat</a>.</p>
<p>Though we do not have a set list of reasons for which we do create accounts, there are a few we will definitely not give out accounts for. We are very sorry if this includes your desired usage but we need to enforce this to keep our service viable in the long term. We hope you understand.</p>
<p>The list of known "bad" reasons can be found on <a class="text-info" href="https://wiki.insomnia247.nl/wiki/Shells_FAQ#What_are_bad_reasons_for_an_invite.3F">our wiki</a>.
body: >
......
......@@ -4,6 +4,6 @@ blurb: |
<h3>About our shells</h3>
<p>We run this service because we believe technology and programming are an important part of shaping the future of human society for the better. This is why chose long ago not to charge for our shell accounts. However, being a small independent shell host with no source of revenue from our services means we have had to make some difficult choices in regards to giving out shell accounts. To keep our service viable for the foreseeable future we need to be quite strict about giving out accounts and ensure that the available resources are used optimally and that no abuse will take place. This is why the invite and application system was created.</p>
<h3>About invite codes</h3>
<p>An invite can be acquired from a staff member or from someone you know who already has a shell account with us. Alternatively, you may apply without an invite code, but know that your application will be scrutinized very closely and only the very best applications will be able to get a shell account this way.</p>
<p>An invite can be acquired from a staff member or from someone you know who already has a shell account with us. If you would like to petition our staff for an invite code, please <a class="text-info" href="https://www.insomnia247.nl/page/chat">contact us</a>.</p>
body: >
Please choose below if you have an invite code or not.
Continue below if you have an invite code.
......@@ -3,14 +3,13 @@
require 'yaml'
config = {
messagebird: {
key: ENV['MESSAGEBIRD_KEY']
},
db: {
host: ENV['DB_HOST'],
name: ENV['DB_NAME'],
user: ENV['DB_USER'],
pass: ENV['DB_PASS']
'mysql' => {
'server' => '127.0.0.1',
'port' => 3306,
'database' => 'signup_invites',
'username' => 'signup_invites',
'password' => ENV['DB_PASS'],
'timeout' => 10
}
}
......
......@@ -2,5 +2,5 @@
for c in {1..4}
do
scp config.yaml signup@insomnia247.nl:/home/signup/public_html && break || sleep 3 && echo "retry"
scp config.yaml signup@insomnia247.nl:/home/signup/public_html/signup.insomnia247.nl/ && break || sleep 3 && echo "retry"
done
......@@ -2,5 +2,5 @@
for c in {1..4}
do
ssh signup@insomnia247.nl "cd /home/signup/public_html && git pull" && break || sleep 3 && echo "retry"
ssh signup@insomnia247.nl "cd /home/signup/public_html/signup.insomnia247.nl/ && git pull" && break || sleep 3 && echo "retry"
done
......@@ -2,5 +2,5 @@
for c in {1..4}
do
ssh signup@insomnia247.nl "cd /home/signup/public_html && touch tmp/restart.txt" && break || sleep 3 && echo "retry"
ssh signup@insomnia247.nl "cd /home/signup/public_html/signup.insomnia247.nl/ && touch tmp/restart.txt" && break || sleep 3 && echo "retry"
done
......@@ -2,5 +2,5 @@
for c in {1..4}
do
ssh signup@insomnia247.nl "cd /home/signup/public_html && git log -n1 --pretty=%h > .current" && break || sleep 3 && echo "retry"
ssh signup@insomnia247.nl "cd /home/signup/public_html/signup.insomnia247.nl && git log -n1 --pretty=%h > .current" && break || sleep 3 && echo "retry"
done
# frozen_string_literal: true
# Mail helper class
class SignupSite < Sinatra::Base
helpers do
def email_send
Pony.mail(
to: 'coolfire@insomnia247.nl',
from: 'no-reply@insomnia247.nl',
reply_to: session[:email],
subject: "Signup request for: #{session[:username]}",
body: (erb :email),
via: :smtp,
via_options: {
address: 'mail.insomnia247.nl',
enable_starttls_auto: true
}
)
rescue Net::SMTPFatalError
halt erb 'Email error'
end
end
end
# frozen_string_literal: true
# MySQL helper class
class SignupSite < Sinatra::Base
helpers do
def mysql_connect
Mysql2::Client.new(
host: settings.config['mysql']['server'],
port: settings.config['mysql']['port'],
database: settings.config['mysql']['database'],
username: settings.config['mysql']['username'],
password: settings.config['mysql']['password'],
connect_timeout: settings.config['mysql']['timeout']
)
rescue Mysql2::Error
halt erb 'Database error'
end
end
end
......@@ -15,20 +15,32 @@ class SignupSite < Sinatra::Base
session[:invite] = Rack::Utils.escape_html(params[:input_invite])
if check_code session[:invite]
redirect '/enter-details', 302
else
cc = YAML.load_file('content/check-code.yaml')
session[:error_message] = cc['error_message']
session[:error_location] = '/enter-code'
session[:error_progress] = 25
redirect '/error', 302
else
redirect '/enter-details', 302
end
end
private
def check_code(code)
return true if code.nil?
return true if code.match(/^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$/).nil?
# TODO: Check code against database
false
return false if code.nil?
return false if code.match(/^[0-9a-fA-F]{64}$/).nil?
# Check if code is in database
mysql = mysql_connect
check = mysql.prepare 'SELECT * FROM invites where `key` = ? LIMIT 1'
result = check.execute(code).first
mysql&.close
return false if result.nil? # No such code in database
return false unless result['privs'].to_i.zero? # Code has already been used
session[:email] = Rack::Utils.escape_html(result['email'])
true
end
end
......@@ -20,7 +20,6 @@ class SignupSite < Sinatra::Base
session[:username] = Rack::Utils.escape_html(params[:input_username])
session[:email] = Rack::Utils.escape_html(params[:input_email])
session[:phone] = Rack::Utils.escape_html(params[:input_phone])
session[:reason] = Rack::Utils.escape_html(params[:input_reason])
if session[:username] !~ /^\w+$/
......@@ -29,31 +28,36 @@ class SignupSite < Sinatra::Base
elsif session[:email] !~ /^\S+@\S+\.\w+$/
session[:error_message] = cd['error_message_email']
redirect '/error', 302
elsif check_phone session[:phone]
session[:error_message] = cd['error_message_phone']
redirect '/error', 302
elsif session[:reason].empty?
session[:error_message] = cd['error_message_reason']
redirect '/warning', 302
else
# TODO: put new request into database and call notification handlers
redirect '/finished', 302
end
end
mysql = mysql_connect
check = mysql.prepare 'SELECT * FROM invites where `username` = ? LIMIT 1'
result = check.execute(session[:username]).first
mysql&.close
def check_phone(number)
# Not providing a phone number is allowed
return false if number.empty?
unless result.nil?
session[:error_message] = cd['error_message_username_in_use']
redirect '/error', 302
end
# Normalize phone number formatting
number.delete!('-')
number.gsub!(/^(00|\+)/, '')
mysql = mysql_connect
unless session.key?(:invite)
insert = mysql.prepare 'INSERT INTO invites (`email`, `key`, `parent`) VALUES (?, ?, ?)'
insert.execute session[:email], 'No invite code', 'SignupSite'
end
# Check for stray characters
return false unless number.match(/^\d+$/).nil?
update_username = mysql.prepare 'UPDATE `invites` SET `username` = ? WHERE `key` = ?'
update_privs = mysql.prepare 'UPDATE `invites` SET `privs` = ? WHERE `key` = ?'
update_username.execute(session[:username], session[:invite])
update_privs.execute('2', session[:invite])
# Check with messagebird HLR if the phone number is valid
# TODO: Actually implement HLR lookup.
true
mysql&.close
email_send
redirect '/finished', 302
end
end
end
# frozen_string_literal: true
require 'mysql2'
require 'pony'
require 'sinatra/base'
require 'yaml'
......@@ -8,6 +10,7 @@ class SignupSite < Sinatra::Base
use Rack::Session::Pool, expire_after: 60 * 60 * 4
set :title, 'Shell signup - Insomnia 24/7'
set :gitid, IO.read('.current')
set :config, YAML.load_file('config.yaml')
get '/' do
landing = YAML.load_file('content/landing.yaml')
......@@ -20,6 +23,8 @@ class SignupSite < Sinatra::Base
end
end
require_relative 'helpers/email'
require_relative 'helpers/mysql'
require_relative 'routes/code'
require_relative 'routes/details'
require_relative 'routes/error'
......
# frozen_string_literal: true
require File.expand_path '../test_helper.rb', __FILE__
require File.expand_path 'test_helper.rb', __dir__
include Rack::Test::Methods
......@@ -28,11 +28,6 @@ describe 'Landing page' do
get '/'
last_response.body.must_include 'href="enter-code"'
end
it 'should display link to enter-details' do
get '/'
last_response.body.must_include 'href="enter-details"'
end
end
describe 'Enter code page' do
......@@ -60,19 +55,6 @@ describe 'Check code page' do
follow_redirect!
last_request.url.must_include 'error'
end
it 'should accept properly formatted invite codes' do
post '/check-code',
input_invite: 'c65d8c31-482b-4329-b288-8b0959a43ea2'
assert_equal last_response.status, 302
end
it 'should redirect to details form for properly formatted invite codes' do
post '/check-code',
input_invite: 'c65d8c31-482b-4329-b288-8b0959a43ea2'
follow_redirect!
last_request.url.must_include 'enter-details'
end
end
describe 'Enter details page' do
......@@ -104,17 +86,6 @@ describe 'Check username' do
end
end
describe 'Check full set' do
it 'should accept valid usernames, email and reason' do
post '/check-details',
input_username: 'username',
input_email: 'username@example.com',
input_reason: 'My reasons are my own.'
follow_redirect!
last_request.url.must_include 'finished'
end
end
describe 'Check reason' do
it 'should warn for empty reasons' do
post '/check-details',
......@@ -134,37 +105,6 @@ describe 'Check email address' do
follow_redirect!
last_request.url.must_include 'error'
end
it 'should accept valid email addresses' do
post '/check-details',
input_username: 'username',
input_email: 'username@example.com',
input_reason: 'My reasons are my own.'
follow_redirect!
last_request.url.must_include 'finished'
end
end
describe 'Check phonenumber' do
it 'should reject invalid phone numbers' do
post '/check-details',
input_username: 'username',
input_email: 'username@example.com',
input_reason: 'My reasons are my own.',
input_phone: '+31g28282828'
follow_redirect!
last_request.url.must_include 'error'
end
it 'should accept valid phone numbers' do
post '/check-details',
input_username: 'username',
input_email: 'username@example.com',
input_reason: 'My reasons are my own.',
input_phone: '+31628282828'
follow_redirect!
last_request.url.must_include 'finished'
end
end
describe 'Error and warning pages' do
......
......@@ -7,4 +7,4 @@ require 'rack/test'
SimpleCov.start
require File.expand_path '../signup_site.rb', __FILE__
require File.expand_path 'signup_site.rb', __dir__
username:
<%= session[:username] %>
email:
<%= session[:email] %>
invite:
<%= session[:invite] %>
reason:
<%= session[:reason] %>
......@@ -7,7 +7,7 @@
<input type="text" class="form-control" id="input_invite" name="input_invite" value="<%= session[:invite] %>">
<% session[:error_reload_form] = false %>
<% else %>
<input type="text" class="form-control" id="input_invite" name="input_invite" placeholder="1234abcd-1234-5678-9abc-432abc987def">
<input type="text" class="form-control" id="input_invite" name="input_invite">
<% end%>
</div>
</div>
......
......@@ -15,7 +15,7 @@
<div class="form-group">
<label for="input_email" class="col-lg-2 control-label">E-mail address</label>
<div class="col-lg-10">
<% if session[:error_reload_form] %>
<% if session[:error_reload_form] || session.has_key?(:email) %>
<input type="text" class="form-control" id="input_email" name="input_email" value="<%= session[:email] %>">
<% else %>
<input type="text" class="form-control" id="input_email" name="input_email" placeholder="E-mail address">
......@@ -23,18 +23,6 @@
</div>
</div>
<div class="form-group">
<label for="input_phone" class="col-lg-2 control-label">Phone number (Optional)</label>
<div class="col-lg-10">
<% if session[:error_reload_form] %>
<input type="text" class="form-control" id="input_phone" name="input_phone" value="<%= session[:phone] %>">
<% else %>
<input type="text" class="form-control" id="input_phone" name="input_phone" placeholder="+15415553421">
<% end %>
<span class="help-block">If you provide your phone number here we will use it to send you an SMS message with your password. Please enter your full phone number including the country code.</span>
</div>
</div>
<div class="form-group">
<label for="input_reason" class="col-lg-2 control-label">Reasons</label>
<div class="col-lg-10">
......
<a href="enter-code" class="btn btn-info">Yes</a>
<a href="enter-details" class="btn btn-info">No</a>
<a href="enter-code" class="btn btn-info">Continue</a>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment