waxx 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE +201 -0
  4. data/README.md +879 -0
  5. data/bin/waxx +120 -0
  6. data/lib/waxx/app.rb +173 -0
  7. data/lib/waxx/conf.rb +54 -0
  8. data/lib/waxx/console.rb +204 -0
  9. data/lib/waxx/csrf.rb +14 -0
  10. data/lib/waxx/database.rb +80 -0
  11. data/lib/waxx/encrypt.rb +38 -0
  12. data/lib/waxx/error.rb +60 -0
  13. data/lib/waxx/html.rb +33 -0
  14. data/lib/waxx/http.rb +268 -0
  15. data/lib/waxx/init.rb +273 -0
  16. data/lib/waxx/irb.rb +44 -0
  17. data/lib/waxx/irb_env.rb +18 -0
  18. data/lib/waxx/json.rb +23 -0
  19. data/lib/waxx/mongodb.rb +221 -0
  20. data/lib/waxx/mysql2.rb +234 -0
  21. data/lib/waxx/object.rb +115 -0
  22. data/lib/waxx/patch.rb +138 -0
  23. data/lib/waxx/pdf.rb +69 -0
  24. data/lib/waxx/pg.rb +246 -0
  25. data/lib/waxx/process.rb +270 -0
  26. data/lib/waxx/req.rb +116 -0
  27. data/lib/waxx/res.rb +98 -0
  28. data/lib/waxx/server.rb +304 -0
  29. data/lib/waxx/sqlite3.rb +237 -0
  30. data/lib/waxx/supervisor.rb +47 -0
  31. data/lib/waxx/test.rb +162 -0
  32. data/lib/waxx/util.rb +57 -0
  33. data/lib/waxx/version.rb +3 -0
  34. data/lib/waxx/view.rb +389 -0
  35. data/lib/waxx/waxx.rb +73 -0
  36. data/lib/waxx/x.rb +103 -0
  37. data/lib/waxx.rb +50 -0
  38. data/skel/README.md +11 -0
  39. data/skel/app/app/app.rb +39 -0
  40. data/skel/app/app/error/app_error.rb +16 -0
  41. data/skel/app/app/error/dhtml.rb +9 -0
  42. data/skel/app/app/error/html.rb +8 -0
  43. data/skel/app/app/error/json.rb +8 -0
  44. data/skel/app/app/error/pdf.rb +13 -0
  45. data/skel/app/app/log/app_log.rb +13 -0
  46. data/skel/app/app.rb +20 -0
  47. data/skel/app/home/home.rb +16 -0
  48. data/skel/app/home/html.rb +145 -0
  49. data/skel/app/html.rb +192 -0
  50. data/skel/app/usr/email.rb +66 -0
  51. data/skel/app/usr/html.rb +115 -0
  52. data/skel/app/usr/list.rb +51 -0
  53. data/skel/app/usr/password.rb +54 -0
  54. data/skel/app/usr/record.rb +98 -0
  55. data/skel/app/usr/usr.js +67 -0
  56. data/skel/app/usr/usr.rb +277 -0
  57. data/skel/app/waxx/waxx.rb +109 -0
  58. data/skel/bin/README.md +1 -0
  59. data/skel/db/README.md +11 -0
  60. data/skel/db/app/0-init.sql +88 -0
  61. data/skel/lib/README.md +1 -0
  62. data/skel/log/README.md +1 -0
  63. data/skel/opt/dev/config.yaml +1 -0
  64. data/skel/opt/prod/config.yaml +1 -0
  65. data/skel/opt/stage/config.yaml +1 -0
  66. data/skel/opt/test/config.yaml +1 -0
  67. data/skel/private/README.md +1 -0
  68. data/skel/public/lib/site.css +202 -0
  69. data/skel/public/lib/waxx/w.ico +0 -0
  70. data/skel/public/lib/waxx/w.png +0 -0
  71. data/skel/public/lib/waxx/waxx.js +111 -0
  72. data/skel/tmp/pids/README.md +1 -0
  73. data.tar.gz.sig +0 -0
  74. metadata +140 -0
  75. metadata.gz.sig +3 -0
data/bin/waxx ADDED
@@ -0,0 +1,120 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ command = ARGV[0]
6
+ commands = %w(on off buff start stop restart console get put post delete patch config migrate migration deploy test init help)
7
+ if not commands.include? command
8
+ puts "Enter a command: #{commands.join(", ")}"
9
+ puts "waxx --help for all options"
10
+ exit 1
11
+ end
12
+
13
+ def parse_options(commands)
14
+ options = {
15
+ sub_command: ARGV[1],
16
+ port: 7700,
17
+ base: Dir.pwd,
18
+ env: "active",
19
+ pid_path: "tmp/pids/waxx.pid",
20
+ daemonize: false,
21
+ log_path: "log/waxx.log",
22
+ user: ENV['USER'],
23
+ group: nil,
24
+ debug: false,
25
+ to: "stage",
26
+ app: "all",
27
+ format: "yaml"
28
+ }
29
+ headline = ["Waxx", "The high-performance flexible framework"].compact.join(" - ")
30
+ OptionParser.new do |opts|
31
+ opts.summary_width = 25
32
+ opts.banner = [headline, "\n\n",
33
+ "Usage: waxx command [-b base_dir] [-p port] [-P pid_file] [-d] [-e env_name] [-l file] [-u user] [-g group] [-f format]\n",
34
+ "Commands: #{commands.join(" ")}\n",
35
+ " waxx help:\n"].compact.join("")
36
+ opts.separator ""
37
+
38
+ opts.on("-p", "--port PORT", Integer, "Specify port", "(default: #{options[:port]})") do |v|
39
+ options[:port] = v
40
+ end
41
+
42
+ opts.on("-b", "--base DIR", String, "The base/root directory of the app. Should contain: app, bin, opt, log, etc.", "(default: cwd: #{options[:base]})") do |v|
43
+ options[:base] = v.sub(/\/$/,"")
44
+ end
45
+
46
+ opts.on("-e", "--env ENVIRONMENT", String, "The env to find the config.yaml file.", "(default: #{options[:env]})") do |v|
47
+ options[:env] = v
48
+ end
49
+
50
+ opts.on("-P", "--pid FILE", String, "save PID in FILE when using -d option.", "(default: #{options[:pid_path]})") do |v|
51
+ options[:pid_path] = File.expand_path(v)
52
+ end
53
+
54
+ opts.on("-d", "--daemon", "Daemonize mode", "(default: false)") do |v|
55
+ options[:daemonize] = v
56
+ end
57
+
58
+ opts.on("-l", "--log FILE", String, "Logfile for output", "(default: /var/log/#{@name}.log)") do |v|
59
+ options[:log_path] = v
60
+ end
61
+
62
+ opts.on("-n", "--name NAME", String, "The name of the migration", "(default: ask)") do |name|
63
+ options[:name] = name
64
+ end
65
+
66
+ opts.on("-t", "--to TO", String, "Where to deploy to (defined in opt/deploy.yaml)", "(default: stage)") do |to|
67
+ options[:to] = to
68
+ end
69
+
70
+ opts.on("-u", "--user USER", String, "User to run as", "(default: current user)") do |user|
71
+ options[:user] = user
72
+ end
73
+
74
+ opts.on("-g", "--group GROUP", String, "Group to run as", "(default: current user's primary group)") do |group|
75
+ options[:group] = group
76
+ end
77
+
78
+ opts.on("-D", "--debug", "Output debug messages (console only) 0-9","(default: 0)") do |level|
79
+ options[:debug] = level
80
+ end
81
+
82
+ opts.on("-a", "--app app_name or all", "The app to test.","(default: all)") do |app|
83
+ options[:app] = app
84
+ end
85
+
86
+ opts.on("-f", "--format FORMAT", String, "The format output that supports it (tests and config) (yaml or json).","(default: yaml)") do |format|
87
+ options[:format] = format
88
+ end
89
+
90
+ opts.on_tail("-h", "--help", "Display this usage information.") do
91
+ puts "#{opts}\n"
92
+ exit
93
+ end
94
+
95
+ end.parse!
96
+ options
97
+ end
98
+
99
+ opts = parse_options(commands)
100
+ require_relative '../lib/waxx'
101
+ $:.unshift "#{opts[:base]}"
102
+ if %w(init help).include? command
103
+ Waxx::Conf["opts"] = opts
104
+ else
105
+ Waxx::Conf.load_yaml(opts[:base], opts[:env])
106
+ Waxx::Conf["opts"] = opts
107
+ require "#{opts[:base]}/app/app"
108
+ end
109
+
110
+ if Waxx::Console::Command.respond_to? command
111
+ if %w(migration).include? command
112
+ Waxx::Console::Command.send(command, ARGV[1], ARGV[2], opts)
113
+ elsif %w(get post put delete patch test deploy migration migrate).include? command
114
+ Waxx::Console::Command.send(command, ARGV[1], opts)
115
+ else
116
+ Waxx::Console::Command.send(command, opts)
117
+ end
118
+ else
119
+ puts "The #{command} command has not been implemented yet. opts: #{opts.inspect} conf: #{Waxx::Conf.data.inspect}"
120
+ end
data/lib/waxx/app.rb ADDED
@@ -0,0 +1,173 @@
1
+ # Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
2
+ # Released under the Apache Version 2 License. See LICENSE.txt.
3
+
4
+ ##
5
+ # Defines the applications handlers and runs the handlers
6
+ #
7
+ # `@runs` holds a hash of the entire app (routes) with the methods for each
8
+ #
9
+ module Waxx::App
10
+ extend self
11
+
12
+ Root = Waxx::Root + '/app'
13
+
14
+ class ParameterParseError < StandardError; end
15
+
16
+ # `@runs` holds a hash of the entire app (routes) with the methods for each
17
+ attr :runs
18
+
19
+ def init
20
+ @runs = {}
21
+ Waxx::Server.require_apps
22
+ end
23
+
24
+ ##
25
+ # Return website page or an error message with status 404
26
+ # `App.not_found(x, title: "Not Found", message: "The record you requested was not found.")`
27
+ # The layout of the error page (html) is defined in app/app/error/html.rb
28
+ def not_found(x, title:"Not Found", message:nil)
29
+ begin
30
+ if message.nil?
31
+ return @runs[:website][:page][:get].call(x, *(x.args))
32
+ end
33
+ rescue => e
34
+ message = e.to_s
35
+ end
36
+ error(x, status: 404, type: "request", title: title, message: message)
37
+ end
38
+
39
+ ##
40
+ # Set an app runner
41
+ # You don't normally call this directly (see Waxx::Object.runs)
42
+ def []=(name, opts)
43
+ @runs[name.to_sym] = opts
44
+ end
45
+
46
+ ##
47
+ # Get an app runner
48
+ # You don't normally call this directly (see Waxx::Object.runs)
49
+ def [](name)
50
+ @runs[name.to_sym]
51
+ end
52
+
53
+ def csrf_failure(x)
54
+ error(x, status:400, type:"request", title:"Cross Site Request Forgery Error", message:"The request is missing the correct CSRF token.", args: [])
55
+ end
56
+
57
+ ##
58
+ # Run an app
59
+ #
60
+ # Can run the request method (get post put patch delete) or the generic "run".
61
+ #
62
+ # 1. x
63
+ # 2. app: The name of the app (Symbol)
64
+ # 3. act: The act to run (String or Symbol - type must match definition)
65
+ # 4, meth: The request method (Symbol)
66
+ # 5. args: The args to pass to the method (after x) (Array)
67
+ #
68
+ # Example: `App.run(x, :person, :record, :get, [1])` will call the get method with the parameter "1" of the record handler defined in App::Person
69
+ def run(x, app, act, meth, args)
70
+ if @runs[app.to_sym][act][meth.to_sym]
71
+ begin
72
+ @runs[app.to_sym][act][meth.to_sym][x, *args]
73
+ rescue ArgumentError => e
74
+ if Waxx['debug']['on_screen']
75
+ error(x, status: 405, type: "request", title: "Argument Error", message: "#{e.to_s}\n\n#{e.backtrace.join("\n")}")
76
+ else
77
+ Waxx.debug e
78
+ App.not_found(x)
79
+ end
80
+ end
81
+ elsif @runs[app.to_sym][act][:run]
82
+ begin
83
+ @runs[app.to_sym][act][:run][x, *args]
84
+ rescue ArgumentError => e
85
+ if Waxx['debug']['on_screen']
86
+ error(x, status: 405, type: "request", title: "Argument Error", message: "#{e.to_s}\n\n#{e.backtrace.join("\n")}")
87
+ else
88
+ Waxx.debug e
89
+ App.not_found(x)
90
+ end
91
+ end
92
+ else
93
+ error(x, status: 405, type: "request", title: "Method Not Implemented", message: "The HTTP method requested is not implemented for this interface.")
94
+ end
95
+ end
96
+
97
+ ##
98
+ # Return an error to the client
99
+ # Format is dependant on the request extention x.req.ext.
100
+ # Layouts in app/app/error/*
101
+ def error(x, status:200, type:"request", title:"An error occurred", message:"", args: [])
102
+ x.res.status = status
103
+ App[:app_error][type.to_sym][:get][x, title, message, *args]
104
+ end
105
+
106
+ ##
107
+ # Return an alert/error to the client
108
+ # Format is dependant on the request extention x.req.ext.
109
+ # Layouts in app/app/error/*
110
+ def alert(x, status:200, type:"request", title:"Alert", message:"", args: [])
111
+ x.res.status = status
112
+ App[:app_error][type.to_sym][:get][x, title, message, *args]
113
+ end
114
+
115
+ ##
116
+ # Determine if the client or user has access to the handler method.
117
+ # See Waxx::Object.runs for details
118
+ def access?(x, acl:nil)
119
+ return true if acl.nil?
120
+ return true if %w(* all any public).include? acl.to_s
121
+ return true if acl.to_s == "user" and x.usr?
122
+ case acl
123
+ when String, Symbol
124
+ return (x.usr["grp"] and x.usr["grp"].include? acl.to_s)
125
+ when Array
126
+ return (x.usr["grp"] and (x.usr["grp"] & acl).size > 0)
127
+ when Hash
128
+ g = nil
129
+ if acl.keys.include? :any or acl.keys.include? :all
130
+ g = acl[:any] || acl[:all]
131
+ elsif acl.keys.include? :read and [:get, :head, :options].include? x.meth
132
+ g = acl[:read]
133
+ elsif acl.keys.include? :write and [:put, :post, :delete, :patch].include? x.meth
134
+ g = acl[:write]
135
+ else
136
+ g = acl[x.meth]
137
+ end
138
+ return false if g.nil?
139
+ return true if %w(* all any public).include? g.to_s
140
+ return access?(x, g)
141
+ when Proc
142
+ return acl.call(x)
143
+ else
144
+ Waxx.debug "No acl type recognized in App.access? for acl: #{acl.inspect}", 1
145
+ false
146
+ end
147
+ false
148
+ end
149
+
150
+ def log(x, cat, name, value=nil, id=nil)
151
+ AppLog.log(x, cat:cat, name:name, value:value, id:id)
152
+ end
153
+
154
+ # Return a random string with no confusing chars (0Oo1iIl etc)
155
+ def random_password(size=10)
156
+ random_string(size, :chars, 'ABCDEFGHJKLMNPQRSTUVWXYabcdefghkmnpqrstuvwxyz23456789#%^&$*i-_+=')
157
+ end
158
+
159
+ def login_needed(x)
160
+ if x.ext == "json"
161
+ else
162
+ App::Html.render(x,
163
+ title: "Please Login",
164
+ #message: {type:"info", message: "Please login"},
165
+ content: App::Usr::Html.login(x, return_to: x.req.uri)
166
+ )
167
+ end
168
+ end
169
+
170
+ def debug(str, level=3)
171
+ Waxx.debug(str, level)
172
+ end
173
+ end
data/lib/waxx/conf.rb ADDED
@@ -0,0 +1,54 @@
1
+ # Waxx Copyright (c) 2016-2017 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com>
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ ##
16
+ # The global Waxx::Conf variable. ex: `Waxx::Conf['site']['name']` or
17
+ # shortcut `Waxx['site']['name']`
18
+ # Data is set in opt/env/config.yaml
19
+ module Waxx::Conf
20
+ extend self
21
+
22
+ ##
23
+ # Internal class var for conf data
24
+ attr :data
25
+ @data = {}
26
+
27
+ ##
28
+ # Load the yaml config file into the Waxx module
29
+ # Access variables with Waxx['var1']['var2'] or Waxx/:var1/:var2
30
+ def load_yaml(base=ENV['PWD'], env="active")
31
+ env = "dev" if env == "active" and not File.exist? "#{base}/opt/active"
32
+ @data = ::YAML.load_file("#{base}/opt/#{env}/config.yaml")
33
+ end
34
+
35
+ ##
36
+ # Get a Waxx variable
37
+ def [](n)
38
+ @data[n]
39
+ end
40
+
41
+ ##
42
+ # Set a conf variable
43
+ def []=(n, v)
44
+ @data[n] = v
45
+ end
46
+
47
+ ##
48
+ # Get a Waxx variable
49
+ def /(n)
50
+ @data[n.to_s] || @data[n.to_sym]
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,204 @@
1
+ # Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
2
+ # Released under the Apache Version 2 License. See LICENSE.txt.
3
+
4
+ require 'stringio'
5
+
6
+ ##
7
+ # The console module that is available with irb
8
+ # When `waxx console` is called, the dbs are connected and a StringIO class acts as the response container
9
+ module Waxx::Console
10
+ extend self
11
+ attr_accessor :db
12
+ attr_accessor :x
13
+
14
+ ##
15
+ # Container for response output when using the console
16
+ class Stringy < StringIO
17
+ attr :out
18
+ # Initialize with StringIO args
19
+ def initialize(*args)
20
+ super *args
21
+ @out = ""
22
+ end
23
+ # Write to the output
24
+ def print(str)
25
+ @out << str
26
+ end
27
+ # Get the output
28
+ def output
29
+ @out
30
+ end
31
+ # Clear the out to run another request
32
+ def reset
33
+ @out = ""
34
+ end
35
+ end
36
+
37
+ # Initialize the console variables
38
+ def init
39
+ @db = Waxx::Database.connections
40
+ io = Stringy.new "GET /app/ok HTTP1/0\n#{ENV.map{|n,v| "#{n}: #{v}"}.join("\n")}"
41
+ @x = Waxx::Server.process_request(io, @db)
42
+ end
43
+
44
+ # Run a GET request
45
+ def get(path, opts={})
46
+ puts path
47
+ @db ||= Waxx::Database.connections
48
+ io = Stringy.new "GET #{path} HTTP1/0\n#{ENV.map{|n,v| "#{n}: #{v}"}.join("\n")}"
49
+ x = Waxx::Server.process_request(io, @db)
50
+ #if ARGV[0] == "get"
51
+ puts x.res.out
52
+ #else
53
+ # x.res.out.join
54
+ #end
55
+ end
56
+
57
+ # The x variable used on the console. Singleton.
58
+ def x
59
+ return @x if @x
60
+ @x = Waxx::X.new
61
+ @x.db = Waxx::Database.connections
62
+ @x.usr = {un:ENV['USER']}
63
+ @x.ua = {un:ENV['USER']}
64
+ @x.req = Waxx::Req.new(ENV, nil, :get, "/", {}, {}, {}, Time.new)
65
+ @x.res = Waxx::Res.new(Stringy.new,200,{},[],[],[])
66
+ @x
67
+ end
68
+
69
+ ##
70
+ # Handle console commands. These are called on the command line: waxx on, waxx deploy prod, waxx test app, etc.
71
+ module Command
72
+ extend self
73
+ attr :x
74
+ def on(opts)
75
+ Waxx::Process::Runner.new('waxx').execute(daemonize: true, pid_path: opts[:pid_path], log_path: opts[:log_path]){
76
+ ::App.start(opts)
77
+ }
78
+ end
79
+ alias start on
80
+
81
+ def off(opts)
82
+ Waxx::Process::Runner.new('waxx').execute(kill: true, pid_path: opts[:pid_path])
83
+ end
84
+ alias stop off
85
+
86
+ def restart(opts)
87
+ stop opts
88
+ sleep 1
89
+ start opts
90
+ end
91
+ alias buff restart
92
+
93
+ def get(url=ARGV[1], opts={})
94
+ Waxx['debug']['level'] = 0
95
+ Waxx::Console.get(url, opts)
96
+ end
97
+
98
+ def post(opts)
99
+ App.post(ARGV[1], opts)
100
+ end
101
+
102
+ def put(opts)
103
+ App.put(ARGV[1], opts)
104
+ end
105
+
106
+ def delete(opts)
107
+ App.delete(ARGV[1], opts)
108
+ end
109
+
110
+ def console(opts)
111
+ if File.exist? 'app/app.rb'
112
+ require 'irb'
113
+ puts "waxx console"
114
+ #help = "Use the source, Luke"
115
+ x = Waxx::Console.x
116
+ binding.irb
117
+ #IRB.setup(nil)
118
+ #workspace = IRB::WorkSpace.new(self)
119
+ #irb = IRB::Irb.new(workspace)
120
+ #IRB.conf[:MAIN_CONTEXT] = irb.context
121
+ #irb.eval_input
122
+ #require 'lib/waxx/irb.rb'
123
+ #@x = Waxx::Console.x
124
+ #IRB.start_session(self) #"#{opts[:base]}/lib/waxx/irb_env.rb")
125
+ else
126
+ puts "Error: You need to call 'waxx console' from the root of a waxx installation."
127
+ exit 1
128
+ end
129
+ end
130
+
131
+ def config(opts)
132
+ puts Waxx.data.send("to_#{opts[:format]}")
133
+ end
134
+
135
+ def deploy(target, opts)
136
+ dep = YAML.load_file("#{opts[:base]}/opt/deploy.yaml")
137
+ dep[target.to_s].each{|n,v|
138
+ puts "Deploying #{target} to #{n}"
139
+ `ssh #{v['user']}@#{v['host']} '#{v['command']}'`
140
+ }
141
+ end
142
+
143
+ def init(opts)
144
+ require_relative 'init'
145
+ Waxx::Init.init(x, opts)
146
+ end
147
+
148
+ def migrate(db='app', opts={})
149
+ Waxx::Database.migrate db, opts
150
+ end
151
+
152
+ def migration(db='app', name=nil, opts={})
153
+ dt = Time.new.strftime('%Y%m%d%H%M')
154
+ if name.nil?
155
+ puts "Enter the name of the migration: "
156
+ name = gets.chomp
157
+ end
158
+ m_file = "db/#{db}/#{dt}-#{name.gsub(/\W/,"-")}.sql"
159
+ File.open(m_file, "w"){|f|
160
+ f.puts "BEGIN;\n\n\n\nCOMMIT;"
161
+ }
162
+ system "/usr/bin/env #{ENV['EDITOR']} #{m_file}"
163
+ end
164
+
165
+ def test(target, opts)
166
+ require_relative 'test'
167
+ start_time = Time.new
168
+ re = {}
169
+ total_tests = 0
170
+ total_passed = 0
171
+ if target == "waxx"
172
+ tests = []
173
+ Dir.entries(opts[:base] + '/test').each{|f|
174
+ next if f =~ /^\./
175
+ tests << f.sub(/\.rb$/,"")
176
+ path = opts[:base] + '/test/' + f
177
+ puts path
178
+ require path
179
+ }
180
+
181
+ tests.each{|waxx_module_test|
182
+ re[waxx_module_test] = Waxx.send(waxx_module_test)
183
+ re[waxx_module_test].each{|file, mod|
184
+ mod.map{|meth, test|
185
+ total_tests += test['tests']
186
+ total_passed += test['tests_passed']
187
+ }
188
+ }
189
+ }
190
+ elsif target == "all" or target.nil?
191
+ puts "app testing not impletemented yet: all"
192
+ else
193
+ puts "app testing not impletemented yet: #{target} #{opts[:format]}"
194
+ end
195
+ re["total_tests"] = total_tests
196
+ re["total_passed"] = total_passed
197
+ duration = ((Time.new - start_time) * 100000).to_i/100.0
198
+ re["performance"] = "#{((total_passed.to_f / total_tests.to_f) * 100).to_i}% in #{duration} ms"
199
+ puts re.send("to_#{opts[:format]}")
200
+ end
201
+
202
+ end
203
+
204
+ end
data/lib/waxx/csrf.rb ADDED
@@ -0,0 +1,14 @@
1
+ # Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
2
+ # Released under the Apache Version 2 License. See LICENSE.txt.
3
+
4
+ module Waxx::Csrf
5
+ extend self
6
+
7
+ def ok?(x)
8
+ x['csrf'] == x.usr['uk']
9
+ end
10
+
11
+ def ht(x)
12
+ %(<input type="hidden" name="csrf" value="#{x.usr['uk']}">)
13
+ end
14
+ end
@@ -0,0 +1,80 @@
1
+ # Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
2
+ # Released under the Apache Version 2 License. See LICENSE.txt.
3
+
4
+ module Waxx::Database
5
+ extend self
6
+
7
+ def parse_uri(uri)
8
+ _, schema, user, pass, host, port, database, opts = uri.split(/^(\w*):\/\/(\w*):?(.*)@([\w\-]*):?([0-9]*)?\/([\w\-]*)\??(.*)?$/)
9
+ {
10
+ type: schema,
11
+ user: user,
12
+ pass: pass,
13
+ host: host,
14
+ database: database,
15
+ opts: Waxx::Http.query_string_to_hash(opts)
16
+ }
17
+ end
18
+
19
+ def connect(conf=Waxx['database'])
20
+ # Parse the conf string to load the correct db engine
21
+ engine = conf.split(":").first
22
+ case engine.downcase
23
+ when 'postgresql', 'pg'
24
+ Waxx::Pg.connect(conf)
25
+ when 'mysql2', 'mysql'
26
+ # Parse the string
27
+ uri = parse_uri(conf)
28
+ # Merge the opts into the params
29
+ config = {
30
+ username: uri/:user,
31
+ password: uri/:pass,
32
+ host: uri/:host,
33
+ port: uri/:port,
34
+ database: uri/:database
35
+ }
36
+ config.merge!(uri/:opts)
37
+ Waxx::Mysql2.connect(config)
38
+ when 'sqlite3', 'sqlite'
39
+ Waxx::Sqlite3.connect(conf.sub('sqlite3://',''))
40
+ when 'mongodb', 'mongo'
41
+ Waxx::Mongodb.connect(conf)
42
+ else
43
+ raise 'Unknown Database Type'
44
+ end
45
+ end
46
+
47
+ # Define database connections in config.yaml or pass in a hash
48
+ # {
49
+ # app: connection_string,
50
+ # blog: connection_string
51
+ # }
52
+ def connections(dbs=Waxx['databases'])
53
+ c = {}
54
+ return c if dbs.nil?
55
+ dbs.each{|name, conf|
56
+ c[name.to_sym] = connect(conf)
57
+ c.define_singleton_method(name){self[name.to_sym]}
58
+ }
59
+ c
60
+ end
61
+
62
+ def migrate(db_only=nil, opts={})
63
+ dbs = connections
64
+ dbs.each{|name, db|
65
+ next if db_only and db_only != db
66
+ puts "Migrating: db.#{name}"
67
+ # get the latest version
68
+ latest = db.exec("SELECT value FROM waxx WHERE name = 'db.#{name}.migration.last'").first['value']
69
+ Dir.entries("#{opts[:base]}/db/#{name}/").sort.each{|f|
70
+ if f =~ /\.sql$/ and f > latest
71
+ puts " #{f}"
72
+ db.exec(File.read("#{opts[:base]}/db/#{name}/#{f}"))
73
+ db.exec("UPDATE waxx SET value = $1 WHERE name = 'db.#{name}.migration.last'",[f])
74
+ end
75
+ }
76
+ }
77
+ puts "Migration complete"
78
+ end
79
+
80
+ end
@@ -0,0 +1,38 @@
1
+ # Waxx Copyright (c) 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved.
2
+ # Released under the Apache Version 2 License. See LICENSE.txt.
3
+
4
+ module Waxx::Encrypt
5
+ extend self
6
+ def encrypt(str, encode:'b64', cipher: Waxx['encryption']['cipher'], key:Waxx['encryption']['key'], iv:Waxx['encryption']['iv'])
7
+ aes = OpenSSL::Cipher.new(cipher)
8
+ aes.encrypt
9
+ aes.key = key
10
+ aes.iv = iv if iv
11
+ case encode.to_sym
12
+ when :b64
13
+ Base64.encode64(aes.update(str.to_s) + aes.final).chomp
14
+ when :url
15
+ http_escape(Base64.encode64(aes.update(str.to_s) + aes.final).chomp)
16
+ when :bin
17
+ aes.update(str.to_s) + aes.final
18
+ else
19
+ throw "Encoding not defined"
20
+ end
21
+ end
22
+ def decrypt(str, encode:'b64', cipher: Waxx['encryption']['cipher'], key:Waxx['encryption']['key'], iv:Waxx['encryption']['iv'])
23
+ aes = OpenSSL::Cipher.new(cipher)
24
+ aes.decrypt
25
+ aes.key = key
26
+ aes.iv = iv if iv
27
+ case encode.to_sym
28
+ when :b64
29
+ aes.update(Base64.decode64(str.to_s + "\n")) + aes.final
30
+ when :url
31
+ aes.update(Base64.decode64(http_unescape(str.to_s) + "\n")) + aes.final
32
+ when :bin
33
+ aes.update(str.to_s) + aes.final
34
+ else
35
+ throw "Encoding not defined"
36
+ end
37
+ end
38
+ end