summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/application.js3
-rw-r--r--app/assets/stylesheets/leap.scss85
-rw-r--r--app/helpers/application_helper.rb23
-rw-r--r--config/defaults.yml7
-rw-r--r--core/app/assets/javascripts/platform.js92
-rw-r--r--core/app/helpers/core_helper.rb38
-rw-r--r--core/app/views/common/_download_for_os.html.haml16
-rw-r--r--core/app/views/common/_home_page_buttons.html.haml3
-rw-r--r--core/config/locales/en.yml12
-rw-r--r--public/leap-img/128/mask.pngbin0 -> 10080 bytes
-rw-r--r--test/integration/home_test.rb24
m---------users/app/assets/javascripts/srp0
-rw-r--r--users/app/models/local_email.rb33
-rw-r--r--users/test/unit/local_email_test.rb31
14 files changed, 346 insertions, 21 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index cd90934..03a40da 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -16,9 +16,8 @@
//= require bootstrap
//= require rails.validations
//= require rails.validations.simple_form
-
//= require leap
+//= require platform
//= require tickets
//= require users
-
//= require_tree .
diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss
index b382773..30f7741 100644
--- a/app/assets/stylesheets/leap.scss
+++ b/app/assets/stylesheets/leap.scss
@@ -43,25 +43,95 @@
}
//
+// OS specific
+//
+
+.os-android {
+ display: none !important;
+}
+
+html.android .os-android {
+ display: inherit !important;
+}
+
+.os-linux32 {
+ display: none !important;
+}
+
+html.linux .os-linux32 {
+ display: inherit !important;
+}
+
+.os-linux64 {
+ display: none !important;
+}
+
+html.linux64 .os-linux64 {
+ display: inherit !important;
+}
+
+.os-windows {
+ display: none !important;
+}
+
+html.windows .os-windows {
+ display: inherit !important;
+}
+
+.os-mac {
+ display: none !important;
+}
+
+html.mac .os-mac {
+ display: inherit !important;
+}
+
+.os-other {
+ display: none !important;
+}
+
+html.oldmac, html.oldwin, html.ios, html.fxos, html.other {
+ .os-other {
+ display: inherit !important;
+ }
+}
+
+//
// ICONS
//
-[class^="big-icon-"],
-[class*=" big-icon-"] {
+[class*="-icon-"] {
display: inline-block;
- width: 32px;
- height: 32px;
@include ie7-restore-right-whitespace();
- line-height: 32px;
vertical-align: middle;
background-repeat: no-repeat;
margin-top: 1px;
}
+[class^="big-icon-"],
+[class*=" big-icon-"] {
+ width: 32px;
+ height: 32px;
+ line-height: 32px;
+}
+
+[class^="huge-icon-"],
+[class*=" huge-icon-"] {
+ width: 128px;
+ height: 128px;
+ line-height: 128px;
+}
+
+
.big-icon-arrow-down {
background-image: url(/leap-img/32/arrow-down.png)
}
+.huge-icon-mask {
+ height: 64px;
+ background-image: url(/leap-img/128/mask.png)
+}
+
//
// TYPOGRAPHY
//
@@ -152,6 +222,9 @@ input, textarea {
.download {
a.btn {
width: 14em;
+ small {
+ font-weight: normal;
+ }
}
}
a.btn {
@@ -191,4 +264,4 @@ input, textarea {
.overview li {
padding: 6px 0;
-} \ No newline at end of file
+}
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 1e79990..90e649a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -19,18 +19,25 @@ module ApplicationHelper
# http://twitter.github.io/bootstrap/base-css.html#icons
#
def icon(name, color=nil)
+ "<i class=\"icon-#{name} #{color_class(color)}\"></i> ".html_safe
+ end
+
+ def big_icon(name, color=nil)
+ "<i class=\"big-icon-#{name} #{color_class(color)}\"></i> ".html_safe
+ end
+
+ def huge_icon(name, color=nil)
+ "<i class=\"huge-icon-#{name} #{color_class(color)}\"></i> ".html_safe
+ end
+
+ def color_class(color)
if color.nil?
- color_class = nil
+ nil
elsif color == :black
- color_class = 'icon-black'
+ 'icon-black'
elsif color == :white
- color_class = 'icon-white'
+ 'icon-white'
end
- "<i class=\"icon-#{name} #{color_class}\"></i> ".html_safe
- end
-
- def big_icon(name, color=nil)
- "<i class=\"big-icon-#{name}\"></i> ".html_safe
end
def format_flash(msg)
diff --git a/config/defaults.yml b/config/defaults.yml
index 8d81668..66ec639 100644
--- a/config/defaults.yml
+++ b/config/defaults.yml
@@ -18,6 +18,11 @@ common: &common
pagination_size: 30
auth:
token_expires_after: 60
+ # handles that will be blocked from being used as logins or email aliases
+ # in addition to the ones in /etc/passwd and http://tools.ietf.org/html/rfc2142
+ handle_blacklist: [certmaster, ssladmin, arin-admin, administrator, www-data, maildrop]
+ # handles that will be allowed despite being in /etc/passwd or rfc2142
+ handle_whitelist: []
development:
<<: *dev_ca
@@ -43,4 +48,4 @@ production:
admins: []
domain: example.net
payment: []
-# logfile: /path/to/your/logs
+ # logfile: /path/to/your/logs
diff --git a/core/app/assets/javascripts/platform.js b/core/app/assets/javascripts/platform.js
new file mode 100644
index 0000000..3ab77d7
--- /dev/null
+++ b/core/app/assets/javascripts/platform.js
@@ -0,0 +1,92 @@
+/* Inspired by mozillas platform detection:
+ https://github.com/mozilla/bedrock/tree/master/media/js/base
+*/
+ (function () {
+ 'use strict';
+ function getPlatform() {
+ var ua = navigator.userAgent,
+ pf = navigator.platform;
+ if (/Win(16|9[x58]|NT( [1234]| 5\.0| [^0-9]|[^ -]|$))/.test(ua) ||
+ /Windows ([MC]E|9[x58]|3\.1|4\.10|NT( [1234]| 5\.0| [^0-9]|[^ ]|$))/.test(ua) ||
+ /Windows_95/.test(ua)) {
+ /**
+ * Officially unsupported platforms are Windows 95, 98, ME, NT 4.x, 2000
+ * These regular expressions match:
+ * - Win16
+ * - Win9x
+ * - Win95
+ * - Win98
+ * - WinNT (not followed by version or followed by version <= 5)
+ * - Windows ME
+ * - Windows CE
+ * - Windows 9x
+ * - Windows 95
+ * - Windows 98
+ * - Windows 3.1
+ * - Windows 4.10
+ * - Windows NT (not followed by version or followed by version <= 5)
+ * - Windows_95
+ */
+ return 'oldwin';
+ }
+ if (ua.indexOf("MSIE 6.0") !== -1 &&
+ ua.indexOf("Windows NT 5.1") !== -1 &&
+ ua.indexOf("SV1") === -1) {
+ // Windows XP SP1
+ return 'oldwin';
+ }
+ if (pf.indexOf("Win32") !== -1 ||
+ pf.indexOf("Win64") !== -1) {
+ return 'windows';
+ }
+ if (/android/i.test(ua)) {
+ return 'android';
+ }
+ if (/armv[6-7]l/.test(pf)) {
+ return 'android';
+ }
+ if (pf.indexOf("Linux") !== -1) {
+ if (pf.indexOf("64") !== -1) {
+ return 'linux64';
+ } else {
+ return 'linux32';
+ }
+ }
+ if (pf.indexOf("MacPPC") !== -1) {
+ return 'oldmac';
+ }
+ if (/Mac OS X 10.[0-5]/.test(ua)) {
+ return 'oldmac';
+ }
+ if (pf.indexOf('iPhone') !== -1 ||
+ pf.indexOf('iPad') !== -1 ||
+ pf.indexOf('iPod') !== -1 ) {
+ return 'ios';
+ }
+ if (ua.indexOf("Mac OS X") !== -1) {
+ return 'osx';
+ }
+ if (ua.indexOf("MSIE 5.2") !== -1) {
+ return 'oldmac';
+ }
+ if (pf.indexOf("Mac") !== -1) {
+ return 'oldmac';
+ }
+ if (navigator.platform === '' &&
+ navigator.userAgent.indexOf("Firefox") !== -1 &&
+ navigator.userAgent.indexOf("Mobile") !== -1) {
+ return 'fxos';
+ }
+
+ return 'other';
+ }
+ (function () {
+ // Immediately set the platform classname on the html-element
+ // to avoid lots of flickering
+ var h = document.documentElement;
+ window.site = {
+ platform : getPlatform()
+ };
+ h.className = window.site.platform;
+ })();
+ })();
diff --git a/core/app/helpers/core_helper.rb b/core/app/helpers/core_helper.rb
index a496144..29a4700 100644
--- a/core/app/helpers/core_helper.rb
+++ b/core/app/helpers/core_helper.rb
@@ -10,4 +10,40 @@ module CoreHelper
render 'common/home_page_buttons'
end
-end \ No newline at end of file
+ def available_clients
+ CLIENT_AVAILABILITY
+ end
+
+ def alternative_client_links(os = nil)
+ alternative_clients(os).map do |client|
+ link_to(client.capitalize, client_download_url(client))
+ end
+ end
+
+ def alternative_clients(os = nil)
+ CLIENT_AVAILABILITY - [os]
+ end
+
+ def client_download_url(os = nil)
+ client_download_domain(os) + client_download_path(os)
+ end
+
+ def client_download_domain(os)
+ "https://downloads.leap.se"
+ end
+
+ def client_download_path(os)
+ CLIENT_DOWNLOAD_PATHS[os] || '/client'
+ end
+
+
+ CLIENT_AVAILABILITY = %w/linux32 linux64 mac windows android/
+ CLIENT_DOWNLOAD_PATHS = {
+ android: '/client/android',
+ linux: '/client/linux',
+ linux32: '/client/linux/Bitmask-linux32-latest.tar.bz2',
+ linux64: '/client/linux/Bitmask-linux64-latest.tar.bz2',
+ osx: '/client/osx/Bitmask-OSC-latest.dmg',
+ windows: '/client/windows'
+ }.with_indifferent_access
+end
diff --git a/core/app/views/common/_download_for_os.html.haml b/core/app/views/common/_download_for_os.html.haml
new file mode 100644
index 0000000..b7c88ba
--- /dev/null
+++ b/core/app/views/common/_download_for_os.html.haml
@@ -0,0 +1,16 @@
+- os = download_for_os
+%div{:class => "os-#{os}"}
+ %span.link
+ - btn_class = (os == "other") ? "disabled" : "btn-primary"
+ = link_to client_download_url(os), :class => "btn btn-large #{btn_class}" do
+ .pull-left= huge_icon('mask')
+ = t(:download_client)
+ %br/
+ %small= I18n.t("os.#{os}")
+ %span.info
+ = t(:client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe
+ %br/
+ - if os == "other"
+ = t(:all_downloads_info, :clients => alternative_client_links(os).to_sentence).html_safe
+ - else
+ = t(:other_downloads_info, :clients => alternative_client_links(os).to_sentence).html_safe
diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml
index 7eb4c40..e10fd38 100644
--- a/core/app/views/common/_home_page_buttons.html.haml
+++ b/core/app/views/common/_home_page_buttons.html.haml
@@ -4,8 +4,7 @@
.row-fluid.first
.span3
.download.span6
- %span.link= link_to(big_icon('arrow-down', icon_color) + t(:download_client), "https://downloads.leap.se/client", :class => 'btn btn-large')
- %span.info= t(:download_client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe
+ = render partial: 'common/download_for_os', collection: available_clients + ['other']
.span3
.row-fluid.second
.login.span4
diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml
index 25b377a..344eee4 100644
--- a/core/config/locales/en.yml
+++ b/core/config/locales/en.yml
@@ -21,10 +21,20 @@ en:
are_you_sure: "Are you sure? This change cannot be undone."
download_client: "Download Bitmask"
- download_client_info: "The Bitmask application allows you to use %{provider} services. It is available for Linux, Mac, Windows, and Android."
+ client_info: "The Bitmask application allows you to use %{provider} services."
+ all_downloads_info: "It is available for %{clients}."
+ other_downloads_info: "It is also available for %{clients}."
login_info: "Log in to change your account settings, create support tickets, and manage payments."
signup_info: "Sign up for a new user account via this website (it is better if you use the Bitmask application to sign up, but this website works too)."
welcome: "Welcome to %{provider}."
get_help: "Get Help"
help_info: "Can't login? Create a new support ticket anonymously."
example_email: 'user@domain.org'
+ os:
+ linux32: "Linux (32 bit)"
+ linux64: "Linux (64 bit)"
+ windows: "Windows"
+ android: "Android"
+ mac: "Mac OSX"
+ other: "(not available for your OS.)"
+
diff --git a/public/leap-img/128/mask.png b/public/leap-img/128/mask.png
new file mode 100644
index 0000000..c7390eb
--- /dev/null
+++ b/public/leap-img/128/mask.png
Binary files differ
diff --git a/test/integration/home_test.rb b/test/integration/home_test.rb
new file mode 100644
index 0000000..126a420
--- /dev/null
+++ b/test/integration/home_test.rb
@@ -0,0 +1,24 @@
+require 'test_helper'
+
+class AccountTest < BrowserIntegrationTest
+
+ setup do
+ Capybara.current_driver = Capybara.javascript_driver
+ end
+
+ test "old windows shows deactivated download" do
+ page.driver.headers = { "User-Agent" => "Win98" }
+ visit '/'
+ assert_selector "html.oldwin"
+ assert has_text? "not available"
+ end
+
+ test "android shows android download" do
+ page.driver.headers = { "User-Agent" => "Android" }
+ visit '/'
+ assert_selector "html.android"
+ assert has_no_text? "not available"
+ assert_selector "small", text: "Android"
+ end
+
+end
diff --git a/users/app/assets/javascripts/srp b/users/app/assets/javascripts/srp
-Subproject d22bf3b9fe2fd31192e1e1b358e97e5a0f3f90b
+Subproject 8f33d32d40b1e21ae7fb9a92c78a275422af421
diff --git a/users/app/models/local_email.rb b/users/app/models/local_email.rb
index 6303bb6..2b4c65e 100644
--- a/users/app/models/local_email.rb
+++ b/users/app/models/local_email.rb
@@ -1,5 +1,10 @@
class LocalEmail < Email
+ BLACKLIST_FROM_RFC2142 = [
+ 'postmaster', 'hostmaster', 'domainadmin', 'webmaster', 'www',
+ 'abuse', 'noc', 'security', 'usenet', 'news', 'uucp',
+ 'ftp', 'sales', 'marketing', 'support', 'info'
+ ]
def self.domain
APP_CONFIG[:domain]
@@ -11,6 +16,8 @@ class LocalEmail < Email
:message => "needs to end in @#{domain}"
}
+ validate :handle_allowed
+
def initialize(s)
super
append_domain_if_needed
@@ -32,4 +39,30 @@ class LocalEmail < Email
end
end
+ def handle_allowed
+ errors.add(:handle, "is reserved.") if handle_reserved?
+ end
+
+ def handle_reserved?
+ # *ARRAY in a case statement tests if ARRAY includes the handle.
+ case handle
+ when *APP_CONFIG[:handle_blacklist]
+ true
+ when *APP_CONFIG[:handle_whitelist]
+ false
+ when *BLACKLIST_FROM_RFC2142
+ true
+ else
+ handle_in_passwd?
+ end
+ end
+
+ def handle_in_passwd?
+ begin
+ !!Etc.getpwnam(handle)
+ rescue ArgumentError
+ # handle was not found
+ return false
+ end
+ end
end
diff --git a/users/test/unit/local_email_test.rb b/users/test/unit/local_email_test.rb
index b25f46f..20ee7f1 100644
--- a/users/test/unit/local_email_test.rb
+++ b/users/test/unit/local_email_test.rb
@@ -24,6 +24,37 @@ class LocalEmailTest < ActiveSupport::TestCase
assert_equal ["needs to end in @#{LocalEmail.domain}"], local.errors[:email]
end
+ test "blacklists rfc2142" do
+ black_listed = LocalEmail.new('hostmaster')
+ assert !black_listed.valid?
+ end
+
+ test "blacklists etc passwd" do
+ black_listed = LocalEmail.new('nobody')
+ assert !black_listed.valid?
+ end
+
+ test "whitelist overwrites automatic blacklists" do
+ with_config handle_whitelist: ['nobody', 'hostmaster'] do
+ white_listed = LocalEmail.new('nobody')
+ assert white_listed.valid?
+ white_listed = LocalEmail.new('hostmaster')
+ assert white_listed.valid?
+ end
+ end
+
+ test "blacklists from config" do
+ black_listed = LocalEmail.new('www-data')
+ assert !black_listed.valid?
+ end
+
+ test "blacklist from config overwrites whitelist" do
+ with_config handle_whitelist: ['www-data'] do
+ black_listed = LocalEmail.new('www-data')
+ assert !black_listed.valid?
+ end
+ end
+
def handle
@handle ||= Faker::Internet.user_name
end