Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] V1.4.x.shopinvader Geoip #132

Open
wants to merge 21 commits into
base: v1.4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fce49e5
Start adding support of accept_language header
sebastienbeau Jun 25, 2018
7788ef8
Improve code, and test if local is set in the session
sebastienbeau Jun 25, 2018
0da2989
finish to implement lang redirection
sebastienbeau Jun 25, 2018
4c65b6f
[IMP] add enable_starttls_auto and authentication for smtp and simpli…
sebastienbeau Aug 31, 2018
05360ca
Merge branch 'better-lang-support' into v1.4.x.shopinvader
sebastienbeau Oct 10, 2018
bc45062
Merge branch 'refactor-smtp' into v1.4.x.shopinvader
sebastienbeau Oct 10, 2018
d63ec4c
complete the PR #111 by handling the case when we want to display the…
did Oct 1, 2018
8f07008
don't use a permanent redirection for the index page in case the loca…
did Oct 13, 2018
b4ac954
better support for the locale in preview mode (engine)
did Oct 20, 2018
adc3b9e
prefix the session key used to store the locale with the string steam…
did Oct 21, 2018
e684053
Adding get/setCookiesProp to access cookies from liquid actions
ljromeroinf Sep 26, 2018
3c27a2d
Tests
ljromeroinf Sep 26, 2018
3077d22
[FIX] fix setting the cookies. Cookies must be added in the response …
sebastienbeau Nov 12, 2018
8aaac35
[IMP] move the storage of the lang selected in a separated cookie ins…
sebastienbeau Nov 12, 2018
639a24f
[FIX] cookie should also be set in case of redirection
sebastienbeau Nov 13, 2018
d226a08
[FIX] sign out should do a redirect to avoid tricky case when one of …
sebastienbeau Nov 15, 2018
3146df0
Merge pull request #2 from akretion/v1.4.x.shopinvader-cookie-backport
sebastienbeau Dec 4, 2018
f085cff
empty commit for travis
sebastienbeau Dec 18, 2018
ea61ffd
[FIX] solve issue on robot.txt page, en is not build in the helper, t…
sebastienbeau Jan 13, 2019
bc7b60d
Merge pull request #3 from akretion/v1.4.x.shopinvader-fixes
sebastienbeau Jan 13, 2019
842907c
[WIP] add a new liquid variable country for geoip location of the vis…
sylvainc Apr 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.swp
*.gem
*.rbc
.bundle
Expand Down
Empty file added .test
Empty file.
4 changes: 4 additions & 0 deletions lib/locomotive/steam/liquid/drops/i18n_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ def context=(context)
@_source.__locale__ = locale
end

if country = context.registers[:country]
@_source.__country__ = country
end

@_source.__default_locale__ = context.registers[:site].try(:default_locale)

super
Expand Down
42 changes: 30 additions & 12 deletions lib/locomotive/steam/middlewares/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def sign_out(options)

store_authenticated(nil)

redirect_to options.callback || path

append_message(:signed_out)
end

Expand Down Expand Up @@ -169,7 +171,7 @@ def reset_token
end

def from
params[:auth_email_from] || '[email protected]'
smtp_config['sender'] || '[email protected]'
end

def subject
Expand All @@ -188,23 +190,39 @@ def entry
params[:auth_entry]
end

def smtp_config
@config ||= _read_smtp_config
end

def smtp
name = params[:auth_email_smtp_namespace] || 'smtp'
namespace = site.metafields.try(:[], name)
if smtp_config.blank?
{}
else
{
address: smtp_config['address'],
port: smtp_config['port'],
user_name: smtp_config['user_name'],
password: smtp_config['password'],
authentication: smtp_config['authentication'] || 'plain',
enable_starttls_auto: (smtp_config['enable_starttls_auto'] || "0").to_bool,
}
end
end

if namespace.blank?
private

def _read_smtp_config
name = params[:auth_email_smtp_namespace] || 'smtp'
config = site.metafields.try(:[], name)
if config.blank?
Locomotive::Common::Logger.error "[Auth] Missing SMTP settings in the Site metafields. Namespace: #{name}".light_red
return {}
{}
else
config
end

{
address: namespace[params[:auth_email_smtp_address_alias] || 'address'],
port: namespace[params[:auth_email_smtp_port_alias] || 'port'],
user_name: namespace[params[:auth_email_smtp_user_name_alias] || 'user_name'],
password: namespace[params[:auth_email_smtp_password_alias] || 'password']
}
end


end

end
Expand Down
1 change: 1 addition & 0 deletions lib/locomotive/steam/middlewares/default_env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def call(env)
env['steam.request'] = request
env['steam.services'] = build_services(request)
env['steam.liquid_assigns'] = {}
env['steam.cookies'] = {}

app.call(env)
end
Expand Down
23 changes: 20 additions & 3 deletions lib/locomotive/steam/middlewares/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def default_locale
site.default_locale
end

def session
env['rack.session']
end

def live_editing?
!!env['steam.live_editing']
end
Expand Down Expand Up @@ -83,16 +87,29 @@ def json?

#= Helper methods

def render_response(content, code = 200, type = nil)
@next_response = [code, { 'Content-Type' => type || 'text/html' }, [content]]
def render_response(content, code = 200, type = nil, no_cookies=false)
headers = { 'Content-Type' => type || 'text/html' }
unless no_cookies
inject_cookies(headers)
end
@next_response = [code, headers, [content]]
end

def redirect_to(location, type = 301)
_location = mounted_on && !location.starts_with?(mounted_on) && (location =~ Locomotive::Steam::IsHTTP).nil? ? "#{mounted_on}#{location}" : location

self.log "Redirected to #{_location}".blue

@next_response = [type, { 'Content-Type' => 'text/html', 'Location' => _location }, []]
headers = { 'Content-Type' => 'text/html', 'Location' => _location }
inject_cookies(headers)

@next_response = [type, headers, []]
end

def inject_cookies(headers)
request.env['steam.cookies'].each do |key, vals|
Rack::Utils.set_cookie_header!(headers, key, vals.symbolize_keys!)
end
end

def modify_path(path = nil, &block)
Expand Down
149 changes: 135 additions & 14 deletions lib/locomotive/steam/middlewares/locale.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'maxmind/db'

module Locomotive::Steam
module Middlewares

Expand All @@ -9,16 +11,26 @@ module Middlewares
# /fr/ => locale = :fr
# /index => locale = :en (default one)
#
# The
# /en/index?locale=fr => locale = :fr
# /index => redirection to /en if the locale in cookie is :en
#
class Locale < ThreadSafe

include Helpers

def _call
locale = extract_locale
env['steam.path'] = request.path_info

env['steam.locale'] = services.locale = extract_locale

country = extract_country
env['steam.country'] = country

set_locale_cookie
set_country_cookie(country)

log "Detecting locale #{locale.upcase}"
log "Locale used: #{locale.upcase}"
log "Country used: #{country.upcase}"

I18n.with_locale(locale) do
self.next
Expand All @@ -27,25 +39,134 @@ def _call

protected

def extract_locale
_locale = locale_from_params || default_locale
_path = request.path_info
def extract_country
country = country_from_params || country_from_cookie || country_from_geoip(env) || country_from_default
country.to_s.downcase
end

def country_from_params
params[:country]&.to_sym.tap do |country|
log 'Country extracted from the params' unless country.blank?
end
end

if _path =~ /^\/(#{site.locales.join('|')})+(\/|$)/
_locale = $1
_path = _path.gsub($1 + $2, '')
def country_from_cookie
if country = services.cookie.get(cookie_country_key_name)
log 'Country extracted from the cookie'
country.to_sym
end
end

def country_from_geoip(remote_ip)
reader = MaxMind::DB.new('/home/akretion/GeoLite2-Country.mmdb', mode: MaxMind::DB::MODE_MEMORY)
remote_ip = env["action_dispatch.remote_ip"].to_s
record = reader.get(remote_ip)
if record.nil?
log "Country not found in database for: #{remote_ip}"
return nil
else
log "Country found in database for: #{remote_ip}"
return record['country']['iso_code']
end
end

# let the other middlewares that the locale was
# extracted from the path.
def country_from_default
return "fr"
end

def locale_from_path
path = request.path_info

if path =~ /^\/(#{site.locales.join('|')})+(\/|$)/
locale = $1

# no need to keep the locale in the path used to fetch the page
env['steam.path'] = path.gsub($1 + $2, '')
env['steam.locale_in_path'] = true

log 'Locale extracted from the path'

locale.to_sym
end
end

env['steam.path'] = _path
env['steam.locale'] = services.locale = _locale

def extract_locale
# Regarding the index page (basically, "/"), we've to see if we could
# guess the locale from the headers the browser sends to us.
locale = if is_index_page?
locale_from_params || locale_from_cookie || locale_from_header
else
locale_from_path || locale_from_params
end

# make sure, the locale is among the ones defined in the site,
# otherwise take the default one.
locale && locales.include?(locale) ? locale : default_locale
end

def locale_from_params
locales.include?(params[:locale]) ? params[:locale] : nil
params[:locale]&.to_sym.tap do |locale|
log 'Locale extracted from the params' unless locale.blank?
end
end

def locale_from_path
path = request.path_info

if path =~ /^\/(#{site.locales.join('|')})+(\/|$)/
locale = $1

# no need to keep the locale in the path used to fetch the page
env['steam.path'] = path.gsub($1 + $2, '')
env['steam.locale_in_path'] = true

log 'Locale extracted from the path'

locale.to_sym
end
end

def locale_from_header
request.accept_language.lazy
.sort { |a, b| b[1] <=> a[1] }
.map { |lang, _| lang[0..1].to_sym }
.find { |lang| locales.include?(lang) }.tap do |locale|
log 'Locale extracted from the header' unless locale.blank?
end
end

def locale_from_cookie
if locale = services.cookie.get(cookie_key_name)

log 'Locale extracted from the cookie'

locale.to_sym
end
end

def set_locale_cookie
services.cookie.set(cookie_key_name, {'value': locale, 'path': '/', 'max_age': 1.year})
end


def set_country_cookie(country)
services.cookie.set(cookie_country_key_name, {'value': country, 'path': '/', 'max_age': 1.year})
end

# The preview urls for all the sites share the same domain, so cookie[:locale]
# would be the same for all the preview urls and this is not good.
# This is why we need to use a different key.
def cookie_key_name
live_editing? ? "steam-locale-#{site.handle}" : 'steam-locale'
end

def cookie_country_key_name
live_editing? ? "steam-country-#{site.handle}" : 'steam-country'
end

def is_index_page?
['/', ''].include?(request.path_info)
end

end
Expand Down
22 changes: 17 additions & 5 deletions lib/locomotive/steam/middlewares/locale_redirection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ class LocaleRedirection < ThreadSafe
include Helpers

def _call
if url = redirect_url
redirect_to url
if redirect_to_root_path_with_lang
redirect_to(path_with_locale, 302)
elsif url = redirect_url
redirect_to(url, redirect_type)
end
end

Expand All @@ -21,13 +23,20 @@ def _call
def redirect_url
if apply_redirection?
if site.prefix_default_locale
path_with_default_locale if locale_not_mentioned_in_path?
path_with_locale if locale_not_mentioned_in_path?
else
env['steam.path'] if default_locale? && locale_mentioned_in_path?
end
end
end

# only applied if redirect_url is not nil
def redirect_type
# We don't want a permanent redirection for the index page in case
# the user wants to change the current locale from the index page.
self.path == '/' && self.locales.size > 1 ? 302 : 301
end

def apply_redirection?
site.locales.size > 1 && request.get? && env['PATH_INFO'] != '/sitemap.xml'
end
Expand All @@ -44,12 +53,15 @@ def locale_not_mentioned_in_path?
!locale_mentioned_in_path?
end

def path_with_default_locale
def path_with_locale
modify_path do |segments|
segments.insert(1, site.default_locale)
segments.insert(1, locale)
end
end

def redirect_to_root_path_with_lang
locale_not_mentioned_in_path? && path.gsub(/^\//, '') == '' && !default_locale?
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/locomotive/steam/middlewares/path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def call(env)
protected

def set_path!(env)
path = (env['steam.path'] || request.path_info).dup
path = env['steam.path'].dup

path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '')
path.gsub!(/^\//, '')
Expand Down
4 changes: 3 additions & 1 deletion lib/locomotive/steam/middlewares/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def liquid_registers
repositories: services.repositories,
logger: Locomotive::Common::Logger,
live_editing: !!env['steam.live_editing'],
session: request.session
session: request.session,
cookies: request.cookies
}
end

Expand Down Expand Up @@ -97,6 +98,7 @@ def _steam_liquid_assigns
def _locale_liquid_assigns
{
'locale' => locale.to_s,
'country' => env['steam.country'],
'default_locale' => site.default_locale.to_s,
'locales' => site.locales.map(&:to_s)
}
Expand Down
Loading