From e2c0962077cf759b23639276cca42606ea2135ec Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 7 Nov 2013 23:27:27 +0100 Subject: Token.destroy_all_expired to cleanup expired tokens (#4411) --- users/app/models/token.rb | 35 ++++++++++++++++++++++++----------- users/test/unit/token_test.rb | 15 +++++++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/users/app/models/token.rb b/users/app/models/token.rb index dd87344..bf9b0d0 100644 --- a/users/app/models/token.rb +++ b/users/app/models/token.rb @@ -11,6 +11,24 @@ class Token < CouchRest::Model::Base validates :user_id, presence: true + design do + view :by_last_seen_at + end + + def self.expires_after + APP_CONFIG[:auth] && APP_CONFIG[:auth][:token_expires_after] + end + + def self.expired + self.by_last_seen_at.endkey(expires_after.minutes.ago) + end + + def self.destroy_all_expired + self.expired.each do |token| + token.destroy + end + end + def authenticate if expired? destroy @@ -27,21 +45,16 @@ class Token < CouchRest::Model::Base end def expired? - expires_after and - last_seen_at + expires_after.minutes < Time.now - end - - def expires_after - APP_CONFIG[:auth] && APP_CONFIG[:auth][:token_expires_after] + Token.expires_after and + last_seen_at < Token.expires_after.minutes.ago end def initialize(*args) super - self.id = SecureRandom.urlsafe_base64(32).gsub(/^_*/, '') - self.last_seen_at = Time.now - end - - design do + if new_record? + self.id = SecureRandom.urlsafe_base64(32).gsub(/^_*/, '') + self.last_seen_at = Time.now + end end end diff --git a/users/test/unit/token_test.rb b/users/test/unit/token_test.rb index f56c576..445a20c 100644 --- a/users/test/unit/token_test.rb +++ b/users/test/unit/token_test.rb @@ -61,6 +61,21 @@ class ClientCertificateTest < ActiveSupport::TestCase end end + test "Token.destroy_all_expired cleans up expired tokens only" do + expired = Token.new(user_id: @user.id) + expired.last_seen_at = 2.hours.ago + expired.save + fresh = Token.new(user_id: @user.id) + fresh.save + with_config auth: {token_expires_after: 60} do + Token.destroy_all_expired + end + assert_nil Token.find(expired.id) + assert_equal fresh, Token.find(fresh.id) + fresh.destroy + end + + end -- cgit v1.2.3 From a7cd2ef0877e79302f27fb175384a0cf4ded52d9 Mon Sep 17 00:00:00 2001 From: Azul Date: Thu, 7 Nov 2013 23:36:37 +0100 Subject: fix cornercase of non expiring tokens --- users/app/models/token.rb | 3 ++- users/test/factories.rb | 4 +++- users/test/unit/token_test.rb | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/users/app/models/token.rb b/users/app/models/token.rb index bf9b0d0..001eb40 100644 --- a/users/app/models/token.rb +++ b/users/app/models/token.rb @@ -20,7 +20,8 @@ class Token < CouchRest::Model::Base end def self.expired - self.by_last_seen_at.endkey(expires_after.minutes.ago) + return [] unless expires_after + by_last_seen_at.endkey(expires_after.minutes.ago) end def self.destroy_all_expired diff --git a/users/test/factories.rb b/users/test/factories.rb index c87e290..f5fb77d 100644 --- a/users/test/factories.rb +++ b/users/test/factories.rb @@ -19,6 +19,8 @@ FactoryGirl.define do end end - factory :token + factory :token do + user + end end diff --git a/users/test/unit/token_test.rb b/users/test/unit/token_test.rb index 445a20c..6c9f209 100644 --- a/users/test/unit/token_test.rb +++ b/users/test/unit/token_test.rb @@ -7,9 +7,6 @@ class ClientCertificateTest < ActiveSupport::TestCase @user = find_record :user end - teardown do - end - test "new token for user" do sample = Token.new(:user_id => @user.id) assert sample.valid? @@ -61,12 +58,17 @@ class ClientCertificateTest < ActiveSupport::TestCase end end + test "Token.destroy_all_expired is noop if no expiry is set" do + expired = FactoryGirl.create :token, last_seen_at: 2.hours.ago + with_config auth: {} do + Token.destroy_all_expired + end + assert_equal expired, Token.find(expired.id) + end + test "Token.destroy_all_expired cleans up expired tokens only" do - expired = Token.new(user_id: @user.id) - expired.last_seen_at = 2.hours.ago - expired.save - fresh = Token.new(user_id: @user.id) - fresh.save + expired = FactoryGirl.create :token, last_seen_at: 2.hours.ago + fresh = FactoryGirl.create :token with_config auth: {token_expires_after: 60} do Token.destroy_all_expired end -- cgit v1.2.3 From d70161b55e37e0d9e7a23ed7dbac4ea6d323971a Mon Sep 17 00:00:00 2001 From: jessib Date: Mon, 11 Nov 2013 14:16:16 -0800 Subject: Maybe not ideal fix, but since there is no edit view, we want to show the show view with the appropriate error messages. --- help/app/controllers/tickets_controller.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb index a669e19..c193ff4 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/help/app/controllers/tickets_controller.rb @@ -62,14 +62,11 @@ class TicketsController < ApplicationController @ticket.comments.last.private = false unless admin? end - if @ticket.changed? - if @ticket.save - flash[:notice] = t(:changes_saved) - redirect_to_tickets - else - respond_with @ticket - end + if @ticket.changed? and @ticket.save + flash[:notice] = t(:changes_saved) + redirect_to_tickets else + flash[:error] = @ticket.errors.full_messages.join(". ") if @ticket.changed? redirect_to auto_ticket_path(@ticket) end end -- cgit v1.2.3 From 11e80906b49bea120ae398c7d6524127eaa9363a Mon Sep 17 00:00:00 2001 From: Azul Date: Tue, 12 Nov 2013 14:50:14 +0100 Subject: make sure we log json request errors and their backtraces --- app/controllers/application_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b808e1c..de8d06b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,12 +10,14 @@ class ApplicationController < ActionController::Base rescue_from StandardError do |e| respond_to do |format| - format.json { render_json_error } + format.json { render_json_error(e) } format.all { raise e } # reraise the exception so the normal thing happens. end end - def render_json_error + def render_json_error(e) + Rails.logger.error e + Rails.logger.error e.backtrace.join("\n") render status: 500, json: {error: "The server failed to process your request. We'll look into it."} end -- cgit v1.2.3 From 10be8c0073b67dcfb7925996e81c2e717f8b499e Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 14 Nov 2013 02:19:03 -0800 Subject: added support for easier customizations via "config/customization" directory --- CUSTOM.md | 13 ++++++++----- config/application.rb | 6 ++++++ config/customization/README.md | 27 +++++++++++++++++++++++++++ config/initializers/customization.rb | 31 +++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 config/customization/README.md create mode 100644 config/initializers/customization.rb diff --git a/CUSTOM.md b/CUSTOM.md index 67fdac0..8671323 100644 --- a/CUSTOM.md +++ b/CUSTOM.md @@ -1,11 +1,14 @@ -# Customization # +Customization +============================== -Leap Web is based on Engines. All things in `app` will overwrite the default behaviour. You can either create a new rails app and include the leap_web gem or clone the leap web repository and add your customizations to the `app` directory. +Customization directory +--------------------------------------- -## CSS Customization ## +See config/customization/README.md -We use scss. It's a superset of css3. Add your customizations to `app/assets/stylesheets`. +Engines +--------------------- -## Disabling an Engine ## +Leap Web is based on Engines. All things in `app` will overwrite the default behaviour. You can either create a new rails app and include the leap_web gem or clone the leap web repository and add your customizations to the `app` directory. If you have no use for one of the engines you can remove it from the Gemfile. Not however that your app might still need to provide some functionality for the other engines to work. For example the users engine provides `current_user` and other methods. diff --git a/config/application.rb b/config/application.rb index 8587ffc..8cf7e30 100644 --- a/config/application.rb +++ b/config/application.rb @@ -85,5 +85,11 @@ module LeapWeb # Set to false in order to see asset requests in the log config.quiet_assets = true + + ## + ## CUSTOMIZATION + ## see initializers/customization.rb + ## + config.paths['app/views'].unshift "config/customization/views" end end diff --git a/config/customization/README.md b/config/customization/README.md new file mode 100644 index 0000000..9c3e434 --- /dev/null +++ b/config/customization/README.md @@ -0,0 +1,27 @@ +Customizing LEAP Webapp +============================================ + +By default, this directory is empty. Any file you place here will override the default files for the application. + +For example: + + stylesheets/ -- overrides files Rails.root/app/assets/stylesheets + tail.scss -- included before all others + head.scss -- included after all others + + public/ -- overrides files in Rails.root/public + favicon.ico -- custom favicon + img/ -- customary directory to put images in + + views/ -- overrides files Rails.root/app/views + home/ + index.html.haml -- this file is what shows up on the home page + + locales/ -- overrides files in Rails.root/config/locales + en.yml -- overrides for English + de.yml -- overrides for German + and so on... + +For most changes, the web application must be restarted after any changes are made to the customization directory. + +Sometimes a `rake tmp:clear` and a rails restart is required to pick up a new stylesheet. diff --git a/config/initializers/customization.rb b/config/initializers/customization.rb new file mode 100644 index 0000000..a2f6f88 --- /dev/null +++ b/config/initializers/customization.rb @@ -0,0 +1,31 @@ +# +# When deploying, common customizations can be dropped in config/customizations. This initializer makes this work. +# +customization_directory = "#{Rails.root}/config/customization" + +# +# Set customization views as the first view path +# +# Rails.application.config.paths['app/views'].unshift "config/customization/views" +# (For some reason, this does not work here. See application.rb for where this is actually called.) + +# +# Set customization stylesheets as the first asset path +# +# (This cannot go in application.rb, because the default paths +# haven't been loaded yet, as far as I can tell) +# +Rails.application.config.assets.paths.unshift "#{customization_directory}/stylesheets" + +# +# Copy files to public +# +if Dir.exists?("#{customization_directory}/public") + require 'fileutils' + FileUtils.cp_r("#{customization_directory}/public/.", "#{Rails.root}/public") +end + +# +# Add I18n path +# +Rails.application.config.i18n.load_path += Dir["#{customization_directory}/locales/*.{rb,yml,yaml}"] -- cgit v1.2.3 From 108938615ff7490080f80ea2d6bd1cd8037cdd84 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 14 Nov 2013 02:19:57 -0800 Subject: minor improvements to the download button (proper localization, better image, better hooks for customization) --- core/app/helpers/download_helper.rb | 2 +- core/app/views/common/_download_for_os.html.haml | 4 ++-- core/app/views/common/_home_page_buttons.html.haml | 10 +++++++--- core/config/locales/en.yml | 4 ++-- public/leap-img/128/mask.png | Bin 10080 -> 3654 bytes 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/app/helpers/download_helper.rb b/core/app/helpers/download_helper.rb index f9c6c40..ee0fe73 100644 --- a/core/app/helpers/download_helper.rb +++ b/core/app/helpers/download_helper.rb @@ -2,7 +2,7 @@ module DownloadHelper def alternative_client_links(os = nil) alternative_clients(os).map do |client| - link_to(client.capitalize, client_download_url(client)) + link_to(I18n.t("os."+client), client_download_url(client)) end end diff --git a/core/app/views/common/_download_for_os.html.haml b/core/app/views/common/_download_for_os.html.haml index b7c88ba..4c096ce 100644 --- a/core/app/views/common/_download_for_os.html.haml +++ b/core/app/views/common/_download_for_os.html.haml @@ -8,8 +8,8 @@ %br/ %small= I18n.t("os.#{os}") %span.info - = t(:client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe - %br/ + %div= t(:client_info, :provider => content_tag(:b,APP_CONFIG[:domain])).html_safe + %div - if os == "other" = t(:all_downloads_info, :clients => alternative_client_links(os).to_sentence).html_safe - else diff --git a/core/app/views/common/_home_page_buttons.html.haml b/core/app/views/common/_home_page_buttons.html.haml index e10fd38..3be12e2 100644 --- a/core/app/views/common/_home_page_buttons.html.haml +++ b/core/app/views/common/_home_page_buttons.html.haml @@ -2,10 +2,14 @@ .home-buttons .row-fluid.first - .span3 - .download.span6 + .span2 + .download.span8 = render partial: 'common/download_for_os', collection: available_clients + ['other'] - .span3 + .span2 + - if local_assigns[:divider] + .row-fluid + .span12 + = render local_assigns[:divider] .row-fluid.second .login.span4 %span.link= link_to(icon('ok-sign', icon_color) + t(:login), login_path, :class => 'btn') diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml index 4710a16..4abf4e8 100644 --- a/core/config/locales/en.yml +++ b/core/config/locales/en.yml @@ -23,7 +23,7 @@ en: download_client: "Download Bitmask" 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}." + other_downloads_info: "Bitmask 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}." @@ -35,6 +35,6 @@ en: linux64: "Linux (64 bit)" windows: "Windows" android: "Android" - osx: "Mac OSX" + osx: "Mac OS" other: "(not available for your OS.)" diff --git a/public/leap-img/128/mask.png b/public/leap-img/128/mask.png index c7390eb..444a62c 100644 Binary files a/public/leap-img/128/mask.png and b/public/leap-img/128/mask.png differ -- cgit v1.2.3 From 84682ee6261967935d16fbeae1190af26420563e Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 14 Nov 2013 15:50:22 -0800 Subject: ensure that we only copy files when running restarting the app, not every time a rake task is run (especially since some rake tasks get run as root!) --- Rakefile | 2 ++ config/initializers/customization.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 8b58316..47b6c3f 100644 --- a/Rakefile +++ b/Rakefile @@ -2,6 +2,8 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. +RAKE=true # let environment initialization code know if we are running via rake or not. + require 'rake/packagetask' require 'rubygems/package_task' diff --git a/config/initializers/customization.rb b/config/initializers/customization.rb index a2f6f88..08da518 100644 --- a/config/initializers/customization.rb +++ b/config/initializers/customization.rb @@ -20,7 +20,7 @@ Rails.application.config.assets.paths.unshift "#{customization_directory}/styles # # Copy files to public # -if Dir.exists?("#{customization_directory}/public") +if !defined?(RAKE) && Dir.exists?("#{customization_directory}/public") require 'fileutils' FileUtils.cp_r("#{customization_directory}/public/.", "#{Rails.root}/public") end -- cgit v1.2.3 From 4193a94b4cc5b5cabbace8311562c0ca88a79f74 Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 15 Nov 2013 00:25:40 -0800 Subject: fix problem with custom scss files and precompiling assets in production mode. --- config/application.rb | 2 +- config/initializers/customization.rb | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/config/application.rb b/config/application.rb index 8cf7e30..2c9c55a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -78,7 +78,7 @@ module LeapWeb # Enable the asset pipeline config.assets.enabled = true - config.assets.initialize_on_precompile = false + config.assets.initialize_on_precompile = true # don't change this (see customization.rb) # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' diff --git a/config/initializers/customization.rb b/config/initializers/customization.rb index 08da518..bc9c834 100644 --- a/config/initializers/customization.rb +++ b/config/initializers/customization.rb @@ -12,8 +12,13 @@ customization_directory = "#{Rails.root}/config/customization" # # Set customization stylesheets as the first asset path # -# (This cannot go in application.rb, because the default paths -# haven't been loaded yet, as far as I can tell) +# Some notes: +# +# * This cannot go in application.rb, as far as I can tell. In application.rb, the default paths +# haven't been loaded yet, so the path we add will always end up at the end unless we add it here. +# +# * For this to work, config.assets.initialize_on_precompile MUST be set to true, otherwise +# this initializer will never get called in production mode when the assets are precompiled. # Rails.application.config.assets.paths.unshift "#{customization_directory}/stylesheets" -- cgit v1.2.3