tane 0.0.1

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 (45) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/README.md +22 -0
  5. data/Rakefile +10 -0
  6. data/bin/tane +18 -0
  7. data/lib/tane.rb +64 -0
  8. data/lib/tane/commands/app.rb +5 -0
  9. data/lib/tane/commands/base.rb +15 -0
  10. data/lib/tane/commands/claim.rb +26 -0
  11. data/lib/tane/commands/create.rb +46 -0
  12. data/lib/tane/commands/email.rb +50 -0
  13. data/lib/tane/commands/event.rb +21 -0
  14. data/lib/tane/commands/exec.rb +37 -0
  15. data/lib/tane/commands/help.rb +33 -0
  16. data/lib/tane/commands/init.rb +25 -0
  17. data/lib/tane/commands/login.rb +91 -0
  18. data/lib/tane/commands/logout.rb +25 -0
  19. data/lib/tane/commands/refresh.rb +26 -0
  20. data/lib/tane/commands/signup.rb +43 -0
  21. data/lib/tane/commands/support.rb +37 -0
  22. data/lib/tane/helpers.rb +168 -0
  23. data/lib/tane/helpers/bushido_helper.rb +50 -0
  24. data/lib/tane/helpers/init_helper.rb +116 -0
  25. data/lib/tane/parser.rb +52 -0
  26. data/lib/tane/version.rb +3 -0
  27. data/spec/commands/base_spec.rb +26 -0
  28. data/spec/commands/claim_spec.rb +31 -0
  29. data/spec/commands/email_spec.rb +71 -0
  30. data/spec/commands/event_spec.rb +20 -0
  31. data/spec/commands/exec_spec.rb +18 -0
  32. data/spec/commands/help_spec.rb +12 -0
  33. data/spec/commands/init_spec.rb +27 -0
  34. data/spec/commands/login_spec.rb +81 -0
  35. data/spec/commands/support_spec.rb +59 -0
  36. data/spec/executable_spec.rb +11 -0
  37. data/spec/fixtures/credentials.yml +2 -0
  38. data/spec/helpers/bushido_helper_spec.rb +87 -0
  39. data/spec/helpers/init_helper_spec.rb +127 -0
  40. data/spec/helpers_spec.rb +223 -0
  41. data/spec/spec_helper.rb +15 -0
  42. data/tane.gemspec +29 -0
  43. data/tasks/spec.rake +10 -0
  44. data/tasks/tane.rake +11 -0
  45. metadata +188 -0
@@ -0,0 +1,25 @@
1
+ class Tane::Commands::Logout < Tane::Commands::Base
2
+ class << self
3
+ def process(args)
4
+ if logged_in?
5
+ term.say "Logging out #{username} from this computer..."
6
+ destroy_credentials
7
+ term.say "Finished! All gone! Buh bye!"
8
+ else
9
+ term.say "Couldn't find any Bushido account on this computer... kind of lonesome in that way, what with just you and me and all..."
10
+ end
11
+ end
12
+
13
+
14
+ def help_text
15
+ <<-EOL
16
+ Usage:
17
+
18
+ tane logout
19
+
20
+ Deletes the Bushido credentials from the user's `$HOME` directory.
21
+ EOL
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,26 @@
1
+ class Tane::Commands::Refresh < Tane::Commands::Base
2
+
3
+ class << self
4
+ def process(args)
5
+ if in_rails_dir?
6
+ Tane::Helpers::Init.update_app
7
+ else
8
+ term.say("You have to be in the local rails app's root directory when running `tane update`")
9
+
10
+ exit 1
11
+ end
12
+ end
13
+
14
+ def help_text
15
+ <<-EOL
16
+ Usage:
17
+
18
+ tane refresh
19
+
20
+ Updates the Bushido environment for the local application from the
21
+ latest settings from the Bushido server.
22
+ EOL
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,43 @@
1
+ class Tane::Commands::Signup < Tane::Commands::Base
2
+ include Tane::Helpers
3
+
4
+ class << self
5
+ def process(args)
6
+ warn_if_credentials
7
+
8
+ email, password = prompt_for_credentials
9
+
10
+ auth_token, errors = Tane::Helpers::Bushido.signup(email, password)
11
+
12
+ if auth_token.nil?
13
+ term.say "Couldn't signup - "
14
+ errors.each do |field|
15
+ term.say "\n"
16
+ field.last.each do |error|
17
+ term.say " #{field.first} #{error} \n"
18
+ end
19
+ end
20
+
21
+ exit
22
+ else
23
+ term.say "Ok, you're signed up as #{email}!"
24
+ end
25
+
26
+ term.say "Done!"
27
+ term.say "Saving credentials"
28
+ save_credentials(email, auth_token)
29
+ end
30
+
31
+
32
+ def help_text
33
+ <<-EOL
34
+ Usage:
35
+
36
+ tane signup
37
+
38
+ Prompts you to signup for a Bushido account.
39
+ EOL
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,37 @@
1
+ class Tane::Commands::Support < Tane::Commands::Base
2
+ class << self
3
+ def process(args)
4
+ message = term.ask("Your message to the Bushido clan: ")
5
+ send_message_to_bushido(message)
6
+ end
7
+
8
+ def send_message_to_bushido(message)
9
+ support_data = {}
10
+ support_data[:source] = "tane"
11
+ support_data[:email] = email_from_credentials_or_prompt
12
+ support_data[:message] = message
13
+
14
+ RestClient.post support_url, support_data
15
+
16
+ term.say("Send the bushido team your message:")
17
+ term.say("\t#{message}")
18
+ term.say("Boy are they gonna be excited to hear from you, #{support_data[:email]}")
19
+ end
20
+
21
+ def email_from_credentials_or_prompt
22
+ return username if logged_in?
23
+ return term.ask("And your email address is: ")
24
+ end
25
+
26
+ def help_text
27
+ <<-EOL
28
+ Usage:
29
+
30
+ tane support
31
+
32
+ Prompts you for a message to send to the Bushido team.
33
+ EOL
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,168 @@
1
+ require 'erb'
2
+ require 'fileutils'
3
+ require 'yaml'
4
+ require 'rest-client'
5
+ require 'json'
6
+
7
+ module Tane
8
+ module Helpers
9
+ def self.included(mod)
10
+ mod.extend(ClassMethods)
11
+ end
12
+
13
+ module ClassMethods
14
+ def term
15
+ @hl ||= HighLine.new
16
+ end
17
+
18
+ def verbose_say(message)
19
+ term.say(message) if opts.verbose
20
+ end
21
+
22
+ def opts
23
+ @opts ||= OpenStruct.new
24
+ end
25
+
26
+ def bushido_url
27
+ ENV['BUSHIDO_URL'] || "http://bushi.do"
28
+ end
29
+
30
+ def bushido_dir
31
+ "#{ENV['HOME']}/.bushido"
32
+ end
33
+
34
+ def email_template_file_path(template_name)
35
+ "#{email_templates_path}/#{template_name}.yml"
36
+ end
37
+
38
+ def email_templates_path
39
+ ".bushido/emails"
40
+ end
41
+
42
+ def tane_file_path
43
+ ".bushido/tane.yml"
44
+ end
45
+
46
+ def credentials_file_path
47
+ "#{bushido_dir}/credentials.yml"
48
+ end
49
+
50
+ def credentials
51
+ YAML.load(ERB.new(File.read( credentials_file_path )).result)
52
+ end
53
+
54
+ def destroy_credentials
55
+ File.delete(credentials_file_path)
56
+ end
57
+
58
+ def logged_in?
59
+ File.exists?(credentials_file_path)
60
+ end
61
+
62
+ def in_rails_dir?
63
+ Dir.exists?('./rails') || Dir.exists?('./script')
64
+ end
65
+
66
+ def bushido_app_exists?
67
+ File.exists?('.bushido/tane.yml') and File.exists?('.bushido/email.yml')
68
+ end
69
+
70
+ def username
71
+ begin
72
+ return credentials[:username]
73
+ rescue
74
+ term.say "Looks like your Bushido credentials file is corrupted - try deleting ~/.bushido/credentials.yml and then logging in again"
75
+ exit 1
76
+ end
77
+ end
78
+
79
+ def password
80
+ begin
81
+ return credentials[:password]
82
+ rescue
83
+ term.say "Looks like your Bushido credentials file is corrupted - try deleting ~/.bushido/credentials.yml and then logging in again"
84
+ exit 1
85
+ end
86
+ end
87
+
88
+ def make_global_bushido_dir
89
+ FileUtils.mkdir_p bushido_dir
90
+ end
91
+
92
+ def make_app_bushido_dir
93
+ if bushido_app_exists?
94
+ term.say("There's already a Bushido app created for this local rails app. If you'd like to create a new one, please remove the .bushido file in this directory")
95
+
96
+ exit 1
97
+ else
98
+ FileUtils.mkdir_p '.bushido/emails'
99
+ end
100
+ end
101
+
102
+ def authenticate_user
103
+ unless logged_in?
104
+ Tane::Commands::Login.process(:exit => false)
105
+ end
106
+ end
107
+
108
+ def save_credentials(username, password)
109
+ new_credentials = credentials rescue {}
110
+ new_credentials[:username] = username
111
+ new_credentials[:password] = password
112
+ Dir.mkdir(bushido_dir) unless File.exists?(bushido_dir)
113
+ File.open(credentials_file_path, 'w+') { |file| file.puts YAML.dump(new_credentials) }
114
+ end
115
+
116
+ def prompt_for_credentials
117
+ email = term.ask("Enter your email: ") { |email| email }
118
+ password = term.ask("Enter your password: ") { |password| password.echo = false }
119
+ return email.to_s, password.to_s
120
+ end
121
+
122
+ def warn_if_credentials
123
+ if logged_in?
124
+ if term.agree("This computer already has the Bushido user '#{username}' logged in, are you sure you would like to proceed? Y/N")
125
+ term.say("Ok, continuing along like nothing happened")
126
+ else
127
+ term.say("Phew, I think we might have dodged a bullet there!")
128
+ exit
129
+ end
130
+ end
131
+ end
132
+
133
+ def bushido_envs
134
+ YAML.load(ERB.new(File.read( '.bushido/tane.yml' )).result)
135
+ end
136
+
137
+ def base_url
138
+ "#{opts.scheme}://#{opts.host}:#{opts.port}"
139
+ end
140
+
141
+ def data_url
142
+ "#{base_url}/bushido/data"
143
+ end
144
+
145
+ def support_url
146
+ "#{bushido_url}/support/v1/message"
147
+ end
148
+
149
+ def envs_url
150
+ "#{base_url}/bushido/envs"
151
+ end
152
+
153
+ def mail_url
154
+ "#{base_url}/bushido/mail"
155
+ end
156
+
157
+ def post(url, data)
158
+ data['key'] = bushido_envs["BUSHIDO_APP_KEY"]
159
+
160
+ verbose_say("RestClient.put #{url}, #{data.inspect}, :content_type => :json, :accept => :json)")
161
+ result = JSON(RestClient.put url, data, :content_type => :json, :accept => :json)
162
+ verbose_say(result.inspect)
163
+
164
+ result
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,50 @@
1
+ class Tane::Helpers::Bushido
2
+ include Tane::Helpers
3
+
4
+ class << self
5
+ def bushido_url
6
+ ENV['BUSHIDO_URL'] || "http://bushi.do"
7
+ end
8
+
9
+ # Returns nil if credentials are invalid
10
+ # Returns the authentication_token if credentials are valid
11
+ def verify_credentials(email, password)
12
+ begin
13
+ result = JSON(RestClient.get("#{bushido_url}/users/verify.json", { :params => {:email => email, :password => password }}))
14
+ if result['errors'].nil?
15
+ return result['authentication_token'], nil
16
+ else
17
+ return nil, result['errors']
18
+ end
19
+ rescue => e
20
+ return nil, ["Couldn't login with those credentials!"]
21
+ end
22
+ end
23
+
24
+ def signup(email, password)
25
+ term.say "Contacting bushido..."
26
+ term.say "(using #{bushido_url}/users/create.json)"
27
+
28
+ begin
29
+ result = JSON(RestClient.get("#{bushido_url}/users/create.json", { :params => {:email => email, :password => password }}))
30
+
31
+ if result['errors'].nil?
32
+ return result['authentication_token'], nil
33
+ else
34
+ return nil, result['errors']
35
+ end
36
+ rescue => e
37
+ if e.respond_to?(:http_body)
38
+ return nil, [["", [JSON(e.http_body)['error']]]]
39
+ end
40
+
41
+ return nil
42
+ end
43
+ end
44
+
45
+ def authenticate_user(email, password)
46
+ warn_if_credentials
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,116 @@
1
+ class Tane::Helpers::Init
2
+ include Tane::Helpers
3
+
4
+ class << self
5
+ def initialize_app
6
+ term.say "Initializing a local Bushido app for this rails app..."
7
+ if bushido_app_exists?
8
+ update_app
9
+ else
10
+ app = create_app
11
+ make_app_bushido_dir
12
+ save_envs(get_app_envs(app['name']))
13
+ save_emails
14
+ end
15
+
16
+ term.say "Finished successfully! Check out .bushido/tane.yml for the env vars if you care, or .bushido/emails/#{example_email_template.keys.first}.yml to create email templates to test with"
17
+ end
18
+
19
+ def update_app
20
+ save_envs(get_app_envs(bushido_envs['BUSHIDO_NAME']))
21
+ end
22
+
23
+ # TODO: Replace envs_template with values retrieved from Bushido side
24
+ def save_envs(env_vars)
25
+ if File.exists?('.bushido/tane.yml')
26
+ if not term.agree('.bushido/tane.yml already exists! Are you sure you want to overwrite it?')
27
+ return
28
+ end
29
+ end
30
+
31
+ File.open('.bushido/tane.yml', 'w+') { |file| file.puts YAML.dump(envs_template(env_vars)) }
32
+ end
33
+
34
+ def save_emails
35
+ if File.exists?("#{email_templates_path}/#{example_email_template.keys.first}")
36
+ if not term.agree("#{example_email_template.keys.first} already exists! Are you sure you want to overwrite it?")
37
+ return
38
+ end
39
+ end
40
+
41
+ File.open("#{email_templates_path}/#{example_email_template.keys.first}", "w") do |file|
42
+ file.puts email_template_explanation
43
+ file.puts YAML.dump(example_email_template)
44
+ end
45
+ end
46
+
47
+ def envs_template(app_envs)
48
+ envs = {}
49
+ env_var_keys = [
50
+ 'APP_TLD', 'BUNDLE_WITHOUT', 'BUSHIDO_APP', 'BUSHIDO_APP_KEY',
51
+ 'BUSHIDO_DOMAIN', 'BUSHIDO_EVENTS', 'BUSHIDO_HOST', 'BUSHIDO_NAME',
52
+ 'BUSHIDO_PROJECT_NAME', 'BUSHIDO_SALT', 'BUSHIDO_SUBDOMAIN',
53
+ 'B_SQL_DB', 'B_SQL_PASS', 'B_SQL_USER', 'DATABASE_URL',
54
+ 'HOSTING_PLATFORM', 'LANG', 'PUBLIC_URL', 'RACK_ENV',
55
+ 'RAILS_ENV', 'S3_ACCESS_KEY_ID', 'S3_ARN', 'S3_BUCKET',
56
+ 'SHARED_DATABASE_URL', 'S3_PREFIX', 'S3_SECRET_ACCESS_KEY',
57
+ 'SMTP_AUTHENTICATION', 'SMTP_DOMAIN', 'SMTP_PASSWORD',
58
+ 'SMTP_PORT', 'SMTP_SERVER', 'SMTP_TLS', 'SMTP_USER'
59
+ ]
60
+
61
+ env_var_keys.each { |env_var_key| envs[env_var_key] = app_envs[env_var_key] }
62
+ envs
63
+ end
64
+
65
+ def example_email_template
66
+ email = {}
67
+ email['example_email_1'] = {}
68
+
69
+ email['example_email_1']['recipient'] = "postmaster@your-app-name.gobushido.com"
70
+ email['example_email_1']['sender'] = "sender@example.org"
71
+ email['example_email_1']['from'] = "Example Sender <example.sender@example.org>"
72
+ email['example_email_1']['subject'] = "Example subject"
73
+ email['example_email_1']['body-plain'] = "Example plain body with no HTML, but with all the quoted conversations"
74
+ email['example_email_1']['stripped-text'] = "Example stripped text, with no HTML, quotes, or signature"
75
+ email['example_email_1']['stripped-signature'] = "Example stripped signature with no HTML"
76
+ email['example_email_1']['body-html'] = "Example body containing <a href='http://example.org'>HTML</a>, and all of the quotes"
77
+ email['example_email_1']['stripped-html'] = "Example body containing <a href='http://example.org'>HTML</a>, but no quotes or signature "
78
+ email['example_email_1']['attachment-count'] = "How many attachments the email has"
79
+ email['example_email_1']['attachment-1'] = "binary blob of file to be sent as attachment-1"
80
+ email['example_email_1']['timestamp'] = "1323286600"
81
+
82
+ email
83
+ end
84
+
85
+ def email_template_explanation
86
+ explanation=<<-EOL
87
+ # Email format description
88
+ #
89
+ # 'name': - name of the email template (used with `tane email 'name'`)
90
+ # recipient - Recipient of the message as reported by MAIL TO during SMTP chat.
91
+ # sender - Sender of the message as reported by MAIL FROM during SMTP chat. Note- this value may differ from From MIME header.
92
+ # from - Sender of the message as reported by From message header, for example Example Sender <example.sender@example.org>".
93
+ # subject - Subject string.
94
+ # body-plain - Text Version of the email. This field is always present. If the incoming message only has HTML body, this will be the text representation of it.
95
+ # stripped-text - Text Version of the message without quoted parts and signature block (if found).
96
+ # stripped-signature - The Signature block stripped from the plain text message (if found).
97
+ # body-html - HTML version of the message, if message was multipart. Note that all parts of the message will be posted, not just text/html. For instance if a message arrives with "foo" part it will be posted as "body-foo".
98
+ # stripped-html - HTML version of the message, without quoted parts.
99
+ # attachment-count - How many attachments the message has.
100
+ # attachment-x - Attached file ('x' stands for number of the attachment). Attachments are handled as file uploads, encoded as multipart/form-data.
101
+ # timestamp - Number of second passed since January 1, 1970
102
+
103
+
104
+ EOL
105
+ end
106
+
107
+ def create_app
108
+ JSON(RestClient.post("#{bushido_url}/apps.json", {:app => {:url => "https://github.com/Bushido/tane.git", :platform => "developer"}, :authentication_token => password}))
109
+ end
110
+
111
+ def get_app_envs(app_name)
112
+ result = JSON(RestClient.get("#{bushido_url}/apps/#{app_name}.json", {:params => {:authentication_token => password}}))
113
+ result["app"]["full_app_env_vars"]
114
+ end
115
+ end
116
+ end