Skip to content

Commit 786be0f

Browse files
committed
Lots of howto
1 parent 417c7cc commit 786be0f

12 files changed

+788
-2
lines changed

server-security.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Next edit `/etc/apt/apt.conf.d/10periodic` so it looks like:
3434
Now we want a user. We'll call this user `deploy`:
3535

3636
useradd -D -s /bin/bash
37-
useradd deploy
37+
useradd deploy --shell /bin/bash
3838
mkdir /home/deploy
3939
mkdir /home/deploy/.ssh
4040
chmod 700 /home/deploy/.ssh
@@ -244,7 +244,33 @@ For example, on Cloudflare you might have entries like this:
244244

245245
![Sample DNS config](./images/mail-dns-records.png "DNS")
246246

247+
### Forwarding mail
247248

249+
From [How to setup MX forwarding](http://www.cyberciti.biz/faq/linux-unix-bsd-postfix-forward-email-to-another-account/)
250+
251+
In `/etc/postfix/main.cf` add the following:
252+
253+
virtual_alias_domains = example.com
254+
virtual_alias_maps = hash:/etc/postfix/virtual
255+
256+
If you followed the previous section you'll actually need to change your `inet_interfaces` line:
257+
258+
inet_interfaces = all
259+
260+
Then in `/etc/postfix/virtual`:
261+
262+
# you can add specific virtual emails here for specific forwarding
263+
@example.com [email protected]
264+
265+
Then restart the service:
266+
267+
postmap /etc/postfix/virtual
268+
service postfix reload
269+
270+
Now that your server can forward email you'll want to ensure the port is open (see the Firewall section below) and that the MX domain records are pointing to your server.
271+
272+
Test that your server is configured correctly (and is not an open relay) using a service like [http://mxtoolbox.com/diagnostic.aspx](http://mxtoolbox.com/diagnostic.aspx)
273+
248274
### Watching the logs
249275

250276
Next get logwatch:
@@ -488,6 +514,7 @@ Note, this means that you won't be able to SSH from a coffee-shop, the office, e
488514

489515
ufw allow 443
490516
ufw allow 80
517+
ufw allow 25
491518
ufw enable
492519

493520
* [http://blog.viktorpetersson.com/post/101707677489/the-dangers-of-ufw-docker](http://blog.viktorpetersson.com/post/101707677489/the-dangers-of-ufw-docker)
@@ -533,6 +560,8 @@ See [http://ubuntuforums.org/showthread.php?t=862620](http://ubuntuforums.org/sh
533560

534561
## OSSEC
535562

563+
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ossec-security-notifications-on-ubuntu-14-04
564+
536565
## logstash
537566

538567
## Jump servers / Bastion servers

shopify_api_interaction.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Shopify API interaction
2+
3+
You'll want to talk to the API and the best way to do this is using the Shopify API gem. Add the following to your `Gemfile`
4+
5+
gem 'shopify_api'
6+
gem 'rest-client'
7+
8+
Then `bundle`.
9+
10+
## API keys
11+
12+
In order to get started you are going to need to setup your application as a _Private Application_ on your shop. To do this, create a new private application:
13+
14+
https://YOURSHOP.myshopify.com/admin/apps/private/new
15+
16+
Once created, go to the application and find the API keys, add them to your `.env`:
17+
18+
SHOPIFY_API_KEY="YOUR_API_KEY"
19+
SHOPIFY_PASSWORD="YOUR_PASSWORD"
20+
SHOPIFY_SHOP="YOUR_SHOP_NAME"
21+
22+
23+
Once you have the API keys in your `.env` you should import them into your `config/secrets.yml`:
24+
25+
shopify_api_key: <%= ENV["SHOPIFY_API_KEY"] %>
26+
shopify_password: <%= ENV["SHOPIFY_PASSWORD"] %>
27+
shopify_shop: <%= ENV["SHOPIFY_SHOP"] %>
28+
29+
30+
## Initializer
31+
32+
Once you've setup your API keys you'll want to preload them in an initializer. Create `/config/initializers/shopify.rb`:
33+
34+
shopify_shop_url = "https://#{Rails.application.secrets.shopify_api_key}:#{Rails.application.secrets.shopify_password}@#{Rails.application.secrets.shopify_shop}.myshopify.com/admin"
35+
ShopifyAPI::Base.site = shopify_shop_url
36+
37+
38+
## Metafields
39+
40+
41+
product.add_metafield(ShopifyAPI::Metafield.new({
42+
:description => 'Author of book',
43+
:namespace => 'book',
44+
:key => 'author',
45+
:value => 'Kurt Vonnegut',
46+
:value_type => 'string'
47+
}))

shopify_embedded_app.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Shopify embedded app
2+
3+
Start with a basic rails application. Then do the following:
4+
5+
* Setup the secrets for the embedded app
6+
* Add the gems
7+
* Setup omniauth
8+
*
9+
10+
11+
## Secrets
12+
13+
Edit your `config/secrets.yml`
14+
15+
defaults: &defaults
16+
shopify_app_api_key: <%= ENV["SHOPIFY_APP_API_KEY"] %>
17+
shopify_app_api_secret: <%= ENV["SHOPIFY_APP_API_SECRET"] %>
18+
19+
Add the environment variables to the `.env`:
20+
21+
SHOPIFY_APP_API_KEY=12345abcdef....
22+
SHOPIFY_APP_API_SECRET=12345abcdef....
23+
24+
25+
## Gems
26+
27+
Add the following to your `Gemfile`:
28+
29+
gem 'shopify_api'
30+
gem 'omniauth'
31+
gem 'omniauth-shopify-oauth2', git: 'git://github.com/jeffrafter/omniauth-shopify-oauth2'
32+
33+
Then `bundle`.
34+
35+
## Setup omniauth
36+
37+
Omniauth is middleware which is setup in an initializer. Create `config/initializers/omniauth.rb`:
38+
39+
# See http://docs.shopify.com/api/tutorials/oauth for all scopes
40+
SHOPIFY_SCOPES = [
41+
'read_content',
42+
'write_content',
43+
'read_products',
44+
'write_products',
45+
'read_customers',
46+
'write_customers',
47+
'read_orders'
48+
]
49+
50+
Rails.application.config.middleware.use OmniAuth::Builder do
51+
provider :shopify,
52+
Rails.application.secrets.shopify_app_api_key,
53+
Rails.application.secrets.shopify_app_api_secret,
54+
:scope => SHOPIFY_SCOPES.join(', '),
55+
:setup => lambda {|env|
56+
params = Rack::Utils.parse_query(env['QUERY_STRING'])
57+
site_url = "https://#{params['shop']}"
58+
env['omniauth.strategy'].options[:client_options][:site] = site_url
59+
}
60+
end
61+
62+
63+
## Shopify Models
64+
65+
rails g model shop_session shop_id:integer uid:string access_token:string ip:string user_agent:string access_at:datetime logout_at:datetime revoked_at:datetime
66+
67+
68+
class CreateShopSessions < ActiveRecord::Migration
69+
def change
70+
create_table :shop_sessions do |t|
71+
t.string :url
72+
t.string :uid
73+
t.string :access_token
74+
t.string :ip
75+
t.string :user_agent
76+
t.datetime :access_at
77+
t.datetime :logout_at
78+
t.datetime :revoked_at
79+
80+
t.timestamps null: false
81+
end
82+
83+
add_index :shop_sessions, [:uid, :access_token]
84+
add_index :shop_sessions, [:revoked_at, :logout_at, :access_at]
85+
end
86+
end
87+
88+
89+
Add a site method for the API
90+
91+
def site
92+
"https://#{self.url}/admin"
93+
end
94+
95+
def token
96+
self.access_token
97+
end
98+
99+
## Shopify Controller
100+
101+
In order to handle the interactions in Shopify you will want a specific controller. Create `app/controllers/shopify_controller.rb`:
102+
103+
104+
https://gist.github.com/jeffrafter/5f3184de69d6737d2898
105+
106+
107+
# Shopify Layout
108+
109+
https://gist.github.com/jeffrafter/a4ac26761d6a5e0552ce
110+
111+
# Views
112+
113+
114+
New:
115+
116+
Shopify new
117+
118+
<div class="page-header" id="login-header">
119+
<h1>Install This App</h1>
120+
<h1><small>This app requires you to login to start using it.</small></h1>
121+
</div>
122+
123+
<div style="width:340px; margin:0 auto;">
124+
<%= form_tag :shopify_login, method: :get, class: 'form-search' do %>
125+
<%= text_field_tag 'shop', nil, placeholder: 'Shop URL', class: 'btn-large' %>
126+
<%= submit_tag 'Install', class: 'btn btn-primary btn-large' %>
127+
<% end %>
128+
</div>
129+
130+
<p align="center" style="margin-top:30px">
131+
<%= image_tag 'shopify.png' %>
132+
</p>
133+
134+
Welcome:
135+
136+
137+
Shopify welcome!
138+
<br>
139+
<br>
140+
[<%= shop_session.shop %>]
141+
<br>
142+
<br>
143+
<strong><%= flash[:notice] %></strong>
144+
145+
146+
147+
148+
149+
150+
151+
# Routes
152+
153+
Rails.application.routes.draw do
154+
root "shopify#welcome"
155+
156+
get '/shopify/welcome', to: 'shopify#welcome', as: :shopify_welcome
157+
get '/shopify/products', to: 'shopify#products', as: :shopify_products
158+
159+
get '/shopify/login', to: 'shopify#new', as: :shopify_login
160+
post '/shopify/login', to: 'shopify#create'
161+
get '/shopify/logout', to: 'shopify#destroy', as: :shopify_logout
162+
get '/auth/shopify/callback', to: 'shopify#create', as: :shopify_callback
163+
end
164+
165+
166+
167+
168+
169+
170+
Now go to this url:
171+
172+
https://snowe-shopify.herokuapp.com/shopify/login?shop=embedded-test
173+
174+
175+
https://docs.shopify.com/api/authentication/oauth
176+
177+
178+
179+
180+
181+
182+
183+
184+
185+
186+
187+
188+
189+
190+
191+
192+
193+
194+
195+
196+
http://embedded-test.myshopify.com/admin/admin/api_clients/new?shop=embedded-test
197+
198+
https://embedded-test.myshopify.com/admin/api_clients/new?shop=embedded-test&api_client[return_url]=http://snowe-shopify.herokuapp.com/shopify/login
199+
200+
201+
202+
https://embedded-test.myshopify.com/admin/oauth/authorize?client_id=9498a7cd6d0e1a56547c5c618bd8c004&scope=read_content,write_content,read_products,write_products, read_customers,write_customers,read_orders&redirect_uri=https://snowe-shopify.herokuapp.com/welcome
203+
204+
read_content,write_content,read_products,write_products, read_customers,write_customers,read_orders
205+
206+
207+
208+
209+
https://snowe-shopify.herokuapp.com/auth/shopify/callback?code=5bb8f92ff8c7da37eaba890020ed2f45&hmac=6dfa0f1e0b56bb3c4d8390c96634d693a699be896ba7c6e211e14f630d2d502d&shop=embedded-test.myshopify.com&signature=b80e78f1c664bca5dc2c2178905709cb&timestamp=1428965125
210+
211+
212+
# Safari and IE embedded IFrame Cookies
213+
214+
http://www.mendoweb.be/blog/internet-explorer-safari-third-party-cookie-problem/
215+
216+
217+
# Validating the HMAC
218+
219+
The problem is that in many requests the HMAC is blank. For example lets say you go to
220+
221+
https://<your-site>/shopify/welcome
222+
223+
This will hit your controller and render the welcome page (without an HMAC). When this page renders it will render the JavaScript which runs the shopify app embed which will reframe your page within the Shopify Admin:
224+
225+
https://<your-shop>.myshopify.com/admin/apps/<your-app-no>/shopify/welcome
226+
227+
This page will re-render your welcome page but this time with the shop and the hmac params included:
228+
229+
https://<your-site>/shopify/welcome?hmac=12345&signature=12345&timestamp=12345&shop=<your-shop>.myshopify.com
230+
231+
232+

ssl.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Now you have the Certificate request files. Go through a service (like [https://
4646

4747
Startssl is a good option to use because the generated certs are approved and you can get a free cert for a single domain. The website can be sluggish if it is overloaded, but that is only a problem when generating your request. They are also a great option for Wildcard and Verified certs if you need them.
4848

49-
**Note**: StartSSL will work for the root domain and 1 subdomain only for the fee option.
49+
**Note**: StartSSL will work for the root domain and 1 subdomain only for the free option.
5050

5151
Go to:
5252

starting_a_rails_app.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,3 +465,23 @@ You may need to update your test database:
465465
bundle exec rake RAILS_ENV=test rake db:migrate
466466

467467

468+
## Money in Rails
469+
470+
Don't represent money using floating point numbers. Use the [monetize](https://github.com/RubyMoney/monetize) gem and the [money-rails](https://github.com/RubyMoney/money-rails) gem:
471+
472+
gem 'monetize'
473+
gem 'money-rails'
474+
475+
And setup the initializer:
476+
477+
rails g money_rails:initializer
478+
479+
Store your fields as integers with cents (you can customize this with currencies using the `t.money` method):
480+
481+
t.integer :price_cents, default: 0
482+
483+
Then in your models:
484+
485+
class Product < ActiveRecord::Base
486+
monetize :price_cents # allow_nil: true
487+
end

0 commit comments

Comments
 (0)