From d0534f2b8372375042cf1d98b2eadd255b1bb797 Mon Sep 17 00:00:00 2001 From: Patrick Neumann Date: Sat, 16 Jun 2018 21:43:20 +0200 Subject: [PATCH] added all files that I have found --- .gitattributes | 2 + Gemfile | 10 + app/controllers.rb | 115 ++++++++++ app/models.rb | 16 ++ app/root.rb | 26 +++ app/views.rb | 205 ++++++++++++++++++ cnf/db.yml | 6 + cnf/thin.yml | 21 ++ config.ru | 17 ++ db/drugstore.sqlite | Bin 0 -> 131072 bytes drugstore | 21 ++ lighttpd.conf.sample.conf | 27 +++ log/thin.3000.log | 0 log/thin.3001.log | 0 log/thin.3002.log | 0 pub/favicon.ico | Bin 0 -> 1150 bytes .../15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png | Bin 0 -> 3529 bytes pub/img/broken_cookies.jpg | Bin 0 -> 29452 bytes pub/img/dark_chocolate.jpg | Bin 0 -> 8508 bytes pub/img/salt_crystal.jpg | Bin 0 -> 5120 bytes pub/robots.txt | 2 + tmp/pids/.placeholder | 0 22 files changed, 468 insertions(+) create mode 100644 .gitattributes create mode 100644 Gemfile create mode 100755 app/controllers.rb create mode 100755 app/models.rb create mode 100755 app/root.rb create mode 100755 app/views.rb create mode 100644 cnf/db.yml create mode 100644 cnf/thin.yml create mode 100755 config.ru create mode 100644 db/drugstore.sqlite create mode 100755 drugstore create mode 100644 lighttpd.conf.sample.conf create mode 100644 log/thin.3000.log create mode 100644 log/thin.3001.log create mode 100644 log/thin.3002.log create mode 100644 pub/favicon.ico create mode 100755 pub/img/15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png create mode 100644 pub/img/broken_cookies.jpg create mode 100644 pub/img/dark_chocolate.jpg create mode 100644 pub/img/salt_crystal.jpg create mode 100644 pub/robots.txt create mode 100644 tmp/pids/.placeholder diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..29c3998 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.gitignore export-ignore +.gitattributes export-ignore \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..f903ad5 --- /dev/null +++ b/Gemfile @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +ruby '2.3.2' + +gem 'tilt', '<2.0' +gem 'camping' +gem 'activerecord' +gem 'sqlite3' +gem 'markaby' +gem 'thin' diff --git a/app/controllers.rb b/app/controllers.rb new file mode 100755 index 0000000..bfd230a --- /dev/null +++ b/app/controllers.rb @@ -0,0 +1,115 @@ +#!/usr/bin/env ruby + +module Drugstore::Controllers + class Index < R '/' + def get + @cart = 0 + unless @state.cart.blank? + @state.cart.each do |product_id, quantity| + @cart = @cart + quantity.to_i + end + end + @products = Product.all + render :index + end + + def post + if( ( @input.has_key?( "product_id" ) ) && ( @input.has_key?( "quantity" ) ) ) + @state.cart ||= {} + if @state.cart.has_key?( @input.product_id ) + @state.cart[ @input.product_id.to_i ] = @state.cart[ @input.product_id.to_i ].to_i + @input.quantity.to_i + else + @state.cart[ @input.product_id.to_i ] = @input.quantity.to_i + end + @state.cart[ @input.product_id.to_i ] = 10 if @state.cart[ @input.product_id.to_i ] > 10 + @state.info = ' <= Product successfully added.' + end + redirect Index + end + end + + class Cart < R '/cart' + def get + unless @state.cart.blank? + @products = [] + @sum = 0 + @state.cart.each do |product_id, quantity| + product = Product.find_by_id( product_id ) + subtotal = ( product.price * quantity.to_f ).round(6) + line = { "quantity" => quantity, + "title" => product.title, + "price" => product.price, + "subtotal" => subtotal, + "id" => product_id } + @products << line + @sum = ( @sum + subtotal ).round(6) + end + render :card + else + redirect Index + end + end + + def post + if @input.has_key?( "cleanup" ) + if @input.cleanup == "all" + @state.cart = nil + redirect Index + elsif @input.cleanup =~ /\A\d+\Z/ + @state.cart = @state.cart.select{ |x| x != @input.cleanup.to_i } + redirect Cart + end + end + end + end + + class Checkout < R '/checkout' + def get + unless @state.cart.blank? + render :checkout + else + redirect Index + end + end + + def post + order = Order.create( :fullname => @input.fullname, + :addrline1 => @input.addrline1, + :zippostalcode => @input.zippostalcode, + :city => @input.city, + :country => @input.country, + :cart => @state.cart.to_s, + :bitcoinaddress => "15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf", + :addrline2 => @input.addrline2, + :stateprovinceregion => @input.stateprovinceregion, + :email => @input.email, + :orderdate => Time.now.strftime( "%Y-%m-%dT%H:%M:%S" ) ) + if order.errors.any? + @error = 'ERROR: Creation of order failed! Please check the form and try again.' + render :checkout, @input + else + @state.order = "done" + # We skip autocreation of bitcoin addresses here! + redirect Bitcoin + end + end + end + + class Bitcoin < R '/bitcoin' + def get + unless @state.cart.blank? + if @state.has_key?( "order" ) + if @state.order == "done" + @state.order = nil + @state.cart = nil + render :bitcoin + end + else + redirect Checkout + end + else + redirect Index + end + end + end +end diff --git a/app/models.rb b/app/models.rb new file mode 100755 index 0000000..cfdf35c --- /dev/null +++ b/app/models.rb @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby + +module Drugstore::Models + class Product < Base + after_find do + ActiveRecord::Base.clear_active_connections! + end + end + + class Order < Base + validates :fullname, :addrline1, :zippostalcode, :city, :country, :cart, :bitcoinaddress, presence: true + after_create do + ActiveRecord::Base.clear_active_connections! + end + end +end \ No newline at end of file diff --git a/app/root.rb b/app/root.rb new file mode 100755 index 0000000..ff57b21 --- /dev/null +++ b/app/root.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby + +HeadTitle = "Drugstore" +HeaderH1 = "Hidden drugstore" + +module Drugstore + include Camping::Session + set :secret, '48be8eda8ea970a3f621974822091127895784c0' + def service(*) + @headers['Content-Type'] = 'text/html; charset=utf-8' + super + end + + def r404( path ) + "Sorry, but Magento Community Edition can't find #{path}." + end + + def r501( method ) + "Sorry, but Magento Community Edition can't respond to #{method}." + end + + def r500( klass, method, ex ) + "Sorry, but #{klass}##{method} failed with #{ex}." + end + +end \ No newline at end of file diff --git a/app/views.rb b/app/views.rb new file mode 100755 index 0000000..0c3d6e8 --- /dev/null +++ b/app/views.rb @@ -0,0 +1,205 @@ +#!/usr/bin/env ruby + +module Drugstore::Views + # Layout for all sites + def layout + html do + head do + title HeadTitle + style do + text 'h1{background-color:grey;color:white;padding-left:8px;margin-left:-8px;margin-right:-8px;}' + text '.greenbutton{background-color:green;font-weight:bold;color:white;}' + text 'table,th,td{border:1px dotted;border-collapse:collapse;padding:8px;}' + text 'th,td{text-align:center;}' + text '.redbutton{background-color:red;font-weight:bold;color:white;}' + text '.boldgreen{font-weight:bold;color:green;}' + text '.boldred{font-weight:bold;color:red;}' + text 'fieldset{width:32em;}' + text 'fieldset label{display:inline;float:left;width:12em;}' + end + end + body do + center 'This is NOT a real drugstore. This site just exists for educational purpose!', :class => "boldred" + h1 HeaderH1 + self << yield + hr + p do + text '(c) 2016 - ' + a 'The Onion Root', :href => 'mailto:the-onion-root@riseup.net' + end + center 'This is NOT a real drugstore. This site just exists for educational purpose!', :class => "boldred" + end + end + end + + # Index and Catalog + def index + if @products.empty? + h2 'No products found' + p do + text 'Could not find any products.' + br + text 'Please try again later.' + end + else + h2 'Products' + if @cart == 0 + p { text 'Items on cart: ' + @cart.to_s } + else + p do + a 'Items on cart: ' + @cart.to_s, :href => "/cart" + if @state.info + span @state.info, :class => "boldgreen" + @state.info = nil + end + end + end + @products.each do |product| + hr + _product( product ) + end + end + end + + # Cart + def card + h2 'Cart' + p { a '<- Back to the calalog' + @cart.to_s, :href => "/" } + hr + unless @products.empty? + form :action => "/cart", :method => 'post' do + input :name => 'cleanup', :type => 'hidden', :value => "all" + input :type => 'submit', :value => 'Delete Cart', :class => "redbutton" + end + br + table do + tr do + th 'Quantity (Gramm)' + th 'Title' + th 'Price (Bitcoin)' + th 'Subtotal (Bitcoin)' + th 'Action' + end + @products.each do |product| + tr do + td product[ "quantity" ] + td product[ "title" ] + td product[ "price" ] + td do + b product[ "subtotal" ] + end + td do + form :action => "/cart", :method => 'post' do + input :name => 'cleanup', :type => 'hidden', :value => product[ "id" ] + input :type => 'submit', :value => 'Delete product', :class => "redbutton" + end + end + end + end + end + p do + text 'Total: ' + span @sum.to_s, :class => "boldred" + text ' BTC' + end + form :action => "/checkout" do + input :type => "submit", :value => "Checkout", :class => "greenbutton" + end + p 'Hint: the max of gramms per product per order is set at 10.' + else + p 'Cart is empty.' + end + end + + def checkout + h2 'Checkout' + p { a '<- Back to the cart', :href => "/cart" } + hr + if @error + p @error, :class => "boldred" + end + form :action => "/checkout", :method => 'post', :id => "shippingaddress" do + label 'Shipping Address:', :form => "shippingaddress" + fieldset do + label 'Full Name:', :for => 'fullname', :class => 'boldred' + input :name => 'fullname', :type => 'text', :size => "30", :value => @input.fullname + br + label 'Address Line 1:', :for => 'addrline1', :class => 'boldred' + input :name => 'addrline1', :type => 'text', :size => "30", :value => @input.addrline1 + br + label 'Address Line 2:', :for => 'addrline2' + input :name => 'addrline2', :type => 'text', :size => "30", :value => @input.addrline2 + br + label 'City:', :for => 'city', :class => 'boldred' + input :name => 'city', :type => 'text', :size => "30", :value => @input.city + br + label 'State/Province/Region:', :for => 'stateprovinceregion' + input :name => 'stateprovinceregion', :type => 'text', :size => "30", :value => @input.stateprovinceregion + br + label 'ZIP/Postal Code:', :for => 'zippostalcode', :class => 'boldred' + input :name => 'zippostalcode', :type => 'text', :size => "30", :value => @input.zippostalcode + br + label 'Country:', :for => 'country', :class => 'boldred' + input :name => 'country', :type => 'text', :size => "30", :value => @input.country + br + label 'Email:', :for => 'email' + input :name => 'email', :type => 'text', :size => "30", :value => @input.email + br + end + br + input :type => 'submit', :value => 'Place order', :class => "greenbutton" + end + p do + text 'Some hints:' + ul do + li { span 'Fields with a bold red label are mandatory fields!', :class => "boldred" } + li 'After successfully placing the order you will get a bitcoin address.' + li 'Shipping will be done after you have proceeded a transaction to that address.' + li 'Unpayed orders will be deleted in the database after the request expires (1 day).' + end + end + end + + def bitcoin + h2 'Bitcoin' + p { a '<- Back to the calalog' + @cart.to_s, :href => "/" } + hr + br + br + br + center do + p '15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf' + img :src => "img/15zveKrrJWbp3BVpv36VWr1kPq3opNK6xf.png", :alt => 'QR code' + end + br + br + br + p do + text 'Hint: ' + span "This bitcoin address has expired. DON'T use it!", :class => "boldred" + end + end + + # Partials + def _product( product ) + img :src => product.image_url, :alt => product.title + h3 product.title + p do + b 'Description' + text ': ' + product.description + br + br + b 'Price per gramm' + text ': ' + product.price.to_s + ' Bitcoin(s)' + end + form :action => "/", :method => 'post' do + input :name => 'product_id', :type => 'hidden', :value => product.id + tag! :select, :name => 'quantity' do + (1..10).each do |q| + tag! :option, q + end + end + input :type => 'submit', :value => 'Add to card', :class => "greenbutton" + end + end +end diff --git a/cnf/db.yml b/cnf/db.yml new file mode 100644 index 0000000..c1ec86b --- /dev/null +++ b/cnf/db.yml @@ -0,0 +1,6 @@ +--- +production: + adapter: sqlite3 + database: /home/dealer/drugstore/db/drugstore.sqlite + pool: 15 + timeout: 5000 diff --git a/cnf/thin.yml b/cnf/thin.yml new file mode 100644 index 0000000..6c59fbd --- /dev/null +++ b/cnf/thin.yml @@ -0,0 +1,21 @@ +--- +chdir: /home/dealer/drugstore +environment: production +address: 127.0.0.1 +port: 3000 +timeout: 30 +log: log/thin.log +pid: tmp/pids/thin.pid +max_conns: 1024 +max_persistent_conns: 512 +require: [] +wait: 30 +threadpool_size: 20 +servers: 3 +rackup: config.ru +daemonize: true +user: neupat75 +group: staff +threaded: true +no-epoll: true # linux only! +tag: Drugstore diff --git a/config.ru b/config.ru new file mode 100755 index 0000000..bee1b1d --- /dev/null +++ b/config.ru @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +require 'camping' +require 'camping/ar' +require 'camping/session' + +db = YAML.load( File.read( 'cnf/db.yml' ) ) +ActiveRecord::Base.establish_connection( db['production'] ) + +Camping.goes :Drugstore + +require_relative 'app/root' +require_relative 'app/models' +require_relative 'app/views' +require_relative 'app/controllers' + +run Drugstore diff --git a/db/drugstore.sqlite b/db/drugstore.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..41a19ce17d395a12a7c23014fc59c40903117f09 GIT binary patch literal 131072 zcmeI*O>Z1Y8Nl%wJFHKJ11#BPg;ZDq#frz9v7Lx`#fxJMF|i%5Gf6gkv1+<&W(s$A zb*igvY46uJ`)YQ+2I- zZ*SOO)WG>%2esIG(rUL`KUS*MYP}}UC3#MNlk#%*yM3DRod2)2=G*U1pWJCpzW0aL z@%N7ZBmejzfB*srAbb!OC0gsiu|xhAu!Mlu6i z49{oG{(8GTb-CMZe{ko*GDwGMorE(Bahfvm|CZvkz>6+Mupv8Vo0=-|whYaTdu#9X zWF9uxL$h1^b5kz8O{C^eH}0Tza+*{#gu+6do;&&hLBxsZ7! z2F9G!oRtXw^NU6KXIN|cy^mXyN6W3_?W5)QJD=e|=o$e85I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q7Vb3w(HYVygAVZ|~ilx~=8f@M^Sal94WK zqBB*QQhOb5{3~My@v>N|tx^P?D6~{B2C3`iDxoPL=b@N|#Qqh_^>3RiV!1)_7mdtDcNd z1sP#s<&JM9AA5y6C}OK}O}q?i5TxaqSkTCzsyd6`s&of(&-|RE42<`&Mb}i>vt}?8 zyF0BsGZ))TTwcc8+NI!u4Wnib+RC^FYGibf!Abpo=90atNgKnxrR+eJwKsE3h1j-K z&ob3F(x6d8=ggss^D8r}WkU1n;Yen!)yRrMX7)`Mn~P1T-tE;mk~j<#?V_xSRmV5A zpEj&?mdj1`g07277E8)DJv9BwUGiSCoGe}@$?__VlyVt;XhvPUwLwE16@!yo2#W z!M@&$JG*kJ9!I=HrtI)>>oG^GedFVS;?p<#GRBa}#&m;0=U`-m=>*s5`*?InP&+vi z=9JEzFGq2C^VpV^1#7lKvqfwntL{=;=PJ>@?+Ph0Cp%JxUzYKl7CUb4-+%&zln zuZoqNS+ezFa44HMV%ErM_PjkOgWHqCA#qL)l4`tK*V(* z%g6sZ4qqAuCV~J02q1s}0tg_000IagfB*srAb7TNTRJ!Qf;T3-yS}|@!{Mr{i{KA`)&0Q_ zyYF|eAMKkv-v9hzzg)capxj@)@!+BF?rlF_bmi8a8^0VZT