diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .gitmodules | 4 | ||||
-rw-r--r-- | CUSTOM.md | 4 | ||||
-rw-r--r-- | DEVELOP.md | 46 | ||||
-rw-r--r-- | Gemfile | 81 | ||||
-rw-r--r-- | Gemfile.lock | 109 | ||||
-rw-r--r-- | app/assets/images/leap_web_users/.gitkeep (renamed from certs/app/assets/images/leap_web_certs/.gitkeep) | 0 | ||||
-rw-r--r-- | app/assets/javascripts/application.js | 2 | ||||
-rw-r--r-- | app/assets/javascripts/buttons.js | 39 | ||||
-rw-r--r-- | app/assets/javascripts/leap.js (renamed from core/app/assets/javascripts/leap.js) | 0 | ||||
-rw-r--r-- | app/assets/javascripts/platform.js (renamed from core/app/assets/javascripts/platform.js) | 0 | ||||
m--------- | app/assets/javascripts/srp (renamed from users/app/assets/javascripts/srp) | 0 | ||||
-rw-r--r-- | app/assets/javascripts/users.js (renamed from users/app/assets/javascripts/users.js) | 89 | ||||
-rw-r--r-- | app/assets/stylesheets/leap.scss | 63 | ||||
-rw-r--r-- | app/assets/stylesheets/leap_web_users/.gitkeep (renamed from certs/app/assets/javascripts/leap_web_certs/.gitkeep) | 0 | ||||
-rw-r--r-- | app/controllers/.gitkeep (renamed from certs/app/assets/stylesheets/leap_web_certs/.gitkeep) | 0 | ||||
-rw-r--r-- | app/controllers/account_settings_controller.rb (renamed from users/app/controllers/account_settings_controller.rb) | 0 | ||||
-rw-r--r-- | app/controllers/controller_extension/authentication.rb (renamed from users/app/controllers/controller_extension/authentication.rb) | 23 | ||||
-rw-r--r-- | app/controllers/controller_extension/token_authentication.rb | 27 | ||||
-rw-r--r-- | app/controllers/keys_controller.rb (renamed from users/app/controllers/keys_controller.rb) | 0 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb (renamed from users/app/controllers/sessions_controller.rb) | 3 | ||||
-rw-r--r-- | app/controllers/users_base_controller.rb (renamed from users/app/controllers/users_base_controller.rb) | 0 | ||||
-rw-r--r-- | app/controllers/users_controller.rb (renamed from users/app/controllers/users_controller.rb) | 5 | ||||
-rw-r--r-- | app/controllers/v1/certs_controller.rb | 20 | ||||
-rw-r--r-- | app/controllers/v1/messages_controller.rb | 24 | ||||
-rw-r--r-- | app/controllers/v1/services_controller.rb | 8 | ||||
-rw-r--r-- | app/controllers/v1/sessions_controller.rb (renamed from users/app/controllers/v1/sessions_controller.rb) | 3 | ||||
-rw-r--r-- | app/controllers/v1/users_controller.rb (renamed from users/app/controllers/v1/users_controller.rb) | 4 | ||||
-rw-r--r-- | app/controllers/webfinger_controller.rb (renamed from users/app/controllers/webfinger_controller.rb) | 0 | ||||
-rw-r--r-- | app/designs/message/by_user_ids_to_show.js | 7 | ||||
-rw-r--r-- | app/designs/message/by_user_ids_to_show_and_created_at.js | 9 | ||||
-rw-r--r-- | app/designs/user/by_created_at_and_one_month_warning_not_sent.js | 5 | ||||
-rw-r--r-- | app/helpers/.gitkeep (renamed from certs/app/controllers/.gitkeep) | 0 | ||||
-rw-r--r-- | app/helpers/core_helper.rb (renamed from core/app/helpers/core_helper.rb) | 4 | ||||
-rw-r--r-- | app/helpers/download_helper.rb (renamed from core/app/helpers/download_helper.rb) | 0 | ||||
-rw-r--r-- | app/helpers/email_aliases_helper.rb (renamed from users/app/helpers/email_aliases_helper.rb) | 0 | ||||
-rw-r--r-- | app/helpers/navigation_helper.rb (renamed from core/app/helpers/navigation_helper.rb) | 0 | ||||
-rw-r--r-- | app/helpers/sessions_helper.rb (renamed from users/app/helpers/sessions_helper.rb) | 0 | ||||
-rw-r--r-- | app/helpers/users_helper.rb (renamed from users/app/helpers/users_helper.rb) | 2 | ||||
-rw-r--r-- | app/models/account.rb (renamed from users/app/models/account.rb) | 0 | ||||
-rw-r--r-- | app/models/anonymous_service_level.rb | 30 | ||||
-rw-r--r-- | app/models/anonymous_user.rb | 31 | ||||
-rw-r--r-- | app/models/client_certificate.rb (renamed from certs/app/models/client_certificate.rb) | 0 | ||||
-rw-r--r-- | app/models/email.rb (renamed from users/app/models/email.rb) | 0 | ||||
-rw-r--r-- | app/models/identity.rb (renamed from users/app/models/identity.rb) | 6 | ||||
-rw-r--r-- | app/models/local_email.rb (renamed from users/app/models/local_email.rb) | 0 | ||||
-rw-r--r-- | app/models/login_format_validation.rb (renamed from users/app/models/login_format_validation.rb) | 0 | ||||
-rw-r--r-- | app/models/message.rb | 29 | ||||
-rw-r--r-- | app/models/pgp_key.rb (renamed from users/app/models/pgp_key.rb) | 0 | ||||
-rw-r--r-- | app/models/service_level.rb | 46 | ||||
-rw-r--r-- | app/models/session.rb (renamed from users/app/models/session.rb) | 0 | ||||
-rw-r--r-- | app/models/token.rb (renamed from users/app/models/token.rb) | 12 | ||||
-rw-r--r-- | app/models/user.rb (renamed from users/app/models/user.rb) | 45 | ||||
-rw-r--r-- | app/views/.gitkeep (renamed from certs/app/helpers/.gitkeep) | 0 | ||||
-rw-r--r-- | app/views/common/_action_buttons.html.haml | 11 | ||||
-rw-r--r-- | app/views/common/_download_button.html.haml | 8 | ||||
-rw-r--r-- | app/views/common/_home_page_buttons.html.haml | 8 | ||||
-rw-r--r-- | app/views/emails/_email.html.haml (renamed from users/app/views/emails/_email.html.haml) | 0 | ||||
-rw-r--r-- | app/views/home/_content.html.haml | 2 | ||||
-rw-r--r-- | app/views/kaminari/_first_page.html.haml (renamed from core/app/views/kaminari/_first_page.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_gap.html.haml (renamed from core/app/views/kaminari/_gap.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_last_page.html.haml (renamed from core/app/views/kaminari/_last_page.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_next_page.html.haml (renamed from core/app/views/kaminari/_next_page.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_page.html.haml (renamed from core/app/views/kaminari/_page.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_paginator.html.haml (renamed from core/app/views/kaminari/_paginator.html.haml) | 0 | ||||
-rw-r--r-- | app/views/kaminari/_prev_page.html.haml (renamed from core/app/views/kaminari/_prev_page.html.haml) | 0 | ||||
-rw-r--r-- | app/views/layouts/_footer.html.haml | 4 | ||||
-rw-r--r-- | app/views/layouts/_header.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/_masthead.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/application.html.haml | 3 | ||||
-rw-r--r-- | app/views/pages/pricing.html.haml | 6 | ||||
-rw-r--r-- | app/views/sessions/new.html.haml | 9 | ||||
-rw-r--r-- | app/views/sessions/new.json.erb (renamed from users/app/views/sessions/new.json.erb) | 0 | ||||
-rw-r--r-- | app/views/users/_change_password.html.haml (renamed from users/app/views/users/_change_password.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/_change_pgp_key.html.haml (renamed from users/app/views/users/_change_pgp_key.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/_change_service_level.html.haml (renamed from users/app/views/users/_change_service_level.html.haml) | 4 | ||||
-rw-r--r-- | app/views/users/_destroy_account.html.haml (renamed from users/app/views/users/_destroy_account.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/_edit.html.haml (renamed from users/app/views/users/_edit.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/_user.html.haml (renamed from users/app/views/users/_user.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/_warnings.html.haml (renamed from users/app/views/users/_warnings.html.haml) | 2 | ||||
-rw-r--r-- | app/views/users/edit.html.haml (renamed from users/app/views/users/edit.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/index.html.haml (renamed from users/app/views/users/index.html.haml) | 0 | ||||
-rw-r--r-- | app/views/users/new.html.haml (renamed from users/app/views/users/new.html.haml) | 16 | ||||
-rw-r--r-- | app/views/users/show.html.haml (renamed from users/app/views/users/show.html.haml) | 7 | ||||
-rw-r--r-- | app/views/v1/sessions/new.json.erb (renamed from users/app/views/v1/sessions/new.json.erb) | 0 | ||||
-rw-r--r-- | app/views/webfinger/host_meta.xml.erb (renamed from users/app/views/webfinger/host_meta.xml.erb) | 0 | ||||
-rw-r--r-- | app/views/webfinger/search.xml.erb (renamed from users/app/views/webfinger/search.xml.erb) | 0 | ||||
-rw-r--r-- | certs/Gemfile | 14 | ||||
-rw-r--r-- | certs/Rakefile | 44 | ||||
-rw-r--r-- | certs/Readme.md | 9 | ||||
-rw-r--r-- | certs/app/controllers/certs_controller.rb | 51 | ||||
-rw-r--r-- | certs/app/helpers/certs_helper.rb | 2 | ||||
-rw-r--r-- | certs/app/models/.gitkeep | 0 | ||||
-rw-r--r-- | certs/app/views/.gitkeep | 0 | ||||
-rw-r--r-- | certs/config/locales/en.yml | 2 | ||||
-rw-r--r-- | certs/config/routes.rb | 5 | ||||
-rw-r--r-- | certs/leap_web_certs.gemspec | 21 | ||||
-rw-r--r-- | certs/lib/leap_web_certs.rb | 4 | ||||
-rw-r--r-- | certs/lib/leap_web_certs/engine.rb | 7 | ||||
-rw-r--r-- | certs/lib/tasks/leap_web_certs_tasks.rake | 4 | ||||
-rwxr-xr-x | certs/script/rails | 8 | ||||
-rw-r--r-- | certs/test/functional/certs_controller_test.rb | 44 | ||||
-rw-r--r-- | certs/test/leap_web_certs_test.rb | 7 | ||||
-rw-r--r-- | certs/test/test_helper.rb | 10 | ||||
-rw-r--r-- | common_dependencies.rb | 22 | ||||
-rw-r--r-- | config/defaults.yml | 21 | ||||
-rw-r--r-- | config/initializers/add_controller_methods.rb (renamed from users/config/initializers/add_controller_methods.rb) | 0 | ||||
-rw-r--r-- | config/initializers/couchrest_model.rb (renamed from core/config/initializers/couchrest_model.rb) | 2 | ||||
-rw-r--r-- | config/initializers/error_constants.rb (renamed from users/config/initializers/error_constants.rb) | 2 | ||||
-rw-r--r-- | config/initializers/simple_form.rb (renamed from core/config/initializers/simple_form.rb) | 2 | ||||
-rw-r--r-- | config/initializers/simple_form_bootstrap.rb (renamed from core/config/initializers/simple_form_bootstrap.rb) | 0 | ||||
-rw-r--r-- | config/initializers/validations.rb (renamed from core/config/initializers/validations.rb) | 0 | ||||
-rw-r--r-- | config/initializers/warden.rb (renamed from users/config/initializers/warden.rb) | 3 | ||||
-rw-r--r-- | config/initializers/webfinger.rb | 1 | ||||
-rw-r--r-- | config/locales/en.yml | 42 | ||||
-rw-r--r-- | config/locales/simple_form.en.yml (renamed from core/config/locales/simple_form.en.yml) | 10 | ||||
-rw-r--r-- | config/locales/users.en.yml (renamed from users/config/locales/en.yml) | 5 | ||||
-rw-r--r-- | config/routes.rb | 30 | ||||
-rw-r--r-- | core/Gemfile | 17 | ||||
-rw-r--r-- | core/Rakefile | 44 | ||||
-rw-r--r-- | core/Readme.md | 6 | ||||
-rw-r--r-- | core/app/views/common/_download_for_os.html.haml | 17 | ||||
-rw-r--r-- | core/app/views/common/_home_page_buttons.html.haml | 23 | ||||
-rw-r--r-- | core/config/initializers/backtrace_silencers.rb | 7 | ||||
-rw-r--r-- | core/config/initializers/inflections.rb | 15 | ||||
-rw-r--r-- | core/config/initializers/mime_types.rb | 5 | ||||
-rw-r--r-- | core/config/initializers/wrap_parameters.rb | 10 | ||||
-rw-r--r-- | core/config/locales/en.yml | 41 | ||||
-rw-r--r-- | core/config/routes.rb | 2 | ||||
-rw-r--r-- | core/leap_web_core.gemspec | 25 | ||||
-rw-r--r-- | core/lib/extensions/testing.rb | 46 | ||||
-rw-r--r-- | core/lib/leap_web_core.rb | 14 | ||||
-rw-r--r-- | core/lib/leap_web_core/dependencies.rb | 40 | ||||
-rw-r--r-- | core/lib/leap_web_core/engine.rb | 9 | ||||
-rw-r--r-- | core/lib/leap_web_core/ui_dependencies.rb | 11 | ||||
-rwxr-xr-x | core/script/rails | 8 | ||||
-rw-r--r-- | engines/billing/Gemfile (renamed from billing/Gemfile) | 0 | ||||
-rw-r--r-- | engines/billing/README.md (renamed from billing/README.md) | 0 | ||||
-rw-r--r-- | engines/billing/Rakefile (renamed from billing/Rakefile) | 0 | ||||
-rw-r--r-- | engines/billing/app/controllers/billing_admin_controller.rb (renamed from billing/app/controllers/billing_admin_controller.rb) | 2 | ||||
-rw-r--r-- | engines/billing/app/controllers/billing_base_controller.rb (renamed from billing/app/controllers/billing_base_controller.rb) | 0 | ||||
-rw-r--r-- | engines/billing/app/controllers/credit_card_info_controller.rb (renamed from billing/app/controllers/credit_card_info_controller.rb) | 2 | ||||
-rw-r--r-- | engines/billing/app/controllers/customer_controller.rb (renamed from billing/app/controllers/customer_controller.rb) | 2 | ||||
-rw-r--r-- | engines/billing/app/controllers/payments_controller.rb (renamed from billing/app/controllers/payments_controller.rb) | 2 | ||||
-rw-r--r-- | engines/billing/app/controllers/subscriptions_controller.rb (renamed from billing/app/controllers/subscriptions_controller.rb) | 2 | ||||
-rw-r--r-- | engines/billing/app/helpers/billing_helper.rb (renamed from billing/app/helpers/billing_helper.rb) | 0 | ||||
-rw-r--r-- | engines/billing/app/helpers/braintree_form_helper.rb (renamed from billing/app/helpers/braintree_form_helper.rb) | 0 | ||||
-rw-r--r-- | engines/billing/app/helpers/braintree_helper.rb (renamed from billing/app/helpers/braintree_helper.rb) | 0 | ||||
-rw-r--r-- | engines/billing/app/models/customer.rb (renamed from billing/app/models/customer.rb) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/billing_admin/show.html.haml (renamed from billing/app/views/billing_admin/show.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/credit_card_info/confirm.html.haml (renamed from billing/app/views/credit_card_info/confirm.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/credit_card_info/edit.html.haml (renamed from billing/app/views/credit_card_info/edit.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/_customer_data.html.haml (renamed from billing/app/views/customer/_customer_data.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/_transaction.html.haml (renamed from billing/app/views/customer/_transaction.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/confirm.html.haml (renamed from billing/app/views/customer/confirm.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/edit.html.haml (renamed from billing/app/views/customer/edit.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/new.html.haml (renamed from billing/app/views/customer/new.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/customer/show.html.haml (renamed from billing/app/views/customer/show.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/payments/_non_customer_fields.html.haml (renamed from billing/app/views/payments/_non_customer_fields.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/payments/_transaction_details.html.haml (renamed from billing/app/views/payments/_transaction_details.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/payments/confirm.html.haml (renamed from billing/app/views/payments/confirm.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/payments/index.html.haml (renamed from billing/app/views/payments/index.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/payments/new.html.haml (renamed from billing/app/views/payments/new.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/_subscription_details.html.haml (renamed from billing/app/views/subscriptions/_subscription_details.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/create.html.haml (renamed from billing/app/views/subscriptions/create.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/destroy.html.haml (renamed from billing/app/views/subscriptions/destroy.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/index.html.haml (renamed from billing/app/views/subscriptions/index.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/new.html.haml (renamed from billing/app/views/subscriptions/new.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/app/views/subscriptions/show.html.haml (renamed from billing/app/views/subscriptions/show.html.haml) | 0 | ||||
-rw-r--r-- | engines/billing/config/initializers/braintree.rb (renamed from billing/config/initializers/braintree.rb) | 8 | ||||
-rw-r--r-- | engines/billing/config/locales/en.yml (renamed from billing/config/locales/en.yml) | 0 | ||||
-rw-r--r-- | engines/billing/config/routes.rb (renamed from billing/config/routes.rb) | 0 | ||||
-rw-r--r-- | engines/billing/leap_web_billing.gemspec (renamed from billing/leap_web_billing.gemspec) | 5 | ||||
-rw-r--r-- | engines/billing/lib/braintree_test_app.rb (renamed from billing/lib/braintree_test_app.rb) | 0 | ||||
-rw-r--r-- | engines/billing/lib/leap_web_billing.rb (renamed from billing/lib/leap_web_billing.rb) | 0 | ||||
-rw-r--r-- | engines/billing/lib/leap_web_billing/engine.rb (renamed from billing/lib/leap_web_billing/engine.rb) | 3 | ||||
-rwxr-xr-x | engines/billing/script/rails (renamed from billing/script/rails) | 0 | ||||
-rw-r--r-- | engines/billing/test/broken/admin_customer_test.rb (renamed from billing/test/integration/admin_customer_test.rb) | 11 | ||||
-rw-r--r-- | engines/billing/test/broken/customer_creation_test.rb (renamed from billing/test/integration/customer_creation_test.rb) | 7 | ||||
-rw-r--r-- | engines/billing/test/broken/subscription_test.rb (renamed from billing/test/integration/subscription_test.rb) | 6 | ||||
-rw-r--r-- | engines/billing/test/factories.rb (renamed from billing/test/factories.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/functional/customer_controller_test.rb (renamed from billing/test/functional/customer_controller_test.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/functional/customers_controller_test.rb (renamed from billing/test/functional/customers_controller_test.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/functional/payments_controller_test.rb (renamed from billing/test/functional/payments_controller_test.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/functional/subscriptions_controller_test.rb (renamed from billing/test/functional/subscriptions_controller_test.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/support/braintree_integration_test.rb | 18 | ||||
-rw-r--r-- | engines/billing/test/support/customer_test_helper.rb (renamed from billing/test/support/customer_test_helper.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/test_helper.rb (renamed from help/test/test_helper.rb) | 2 | ||||
-rw-r--r-- | engines/billing/test/unit/customer_test.rb (renamed from billing/test/unit/customer_test.rb) | 0 | ||||
-rw-r--r-- | engines/billing/test/unit/customer_with_payment_info_test.rb (renamed from billing/test/unit/customer_with_payment_info_test.rb) | 0 | ||||
-rw-r--r-- | engines/support/Gemfile (renamed from help/Gemfile) | 0 | ||||
-rw-r--r-- | engines/support/README.md (renamed from help/README.md) | 0 | ||||
-rw-r--r-- | engines/support/Rakefile (renamed from help/Rakefile) | 0 | ||||
-rw-r--r-- | engines/support/app/assets/javascripts/tickets.js (renamed from help/app/assets/javascripts/tickets.js) | 0 | ||||
-rw-r--r-- | engines/support/app/controllers/tickets_controller.rb (renamed from help/app/controllers/tickets_controller.rb) | 54 | ||||
-rw-r--r-- | engines/support/app/designs/ticket/by_includes_post_by.js (renamed from help/app/designs/ticket/by_includes_post_by.js) | 0 | ||||
-rw-r--r-- | engines/support/app/designs/ticket/by_includes_post_by_and_created_at.js (renamed from help/app/designs/ticket/by_includes_post_by_and_created_at.js) | 0 | ||||
-rw-r--r-- | engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js (renamed from help/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js) | 0 | ||||
-rw-r--r-- | engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js (renamed from help/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js) | 0 | ||||
-rw-r--r-- | engines/support/app/designs/ticket/by_includes_post_by_and_updated_at.js (renamed from help/app/designs/ticket/by_includes_post_by_and_updated_at.js) | 0 | ||||
-rw-r--r-- | engines/support/app/helpers/auto_tickets_path_helper.rb (renamed from help/app/helpers/auto_tickets_path_helper.rb) | 3 | ||||
-rw-r--r-- | engines/support/app/helpers/tickets_helper.rb (renamed from help/app/helpers/tickets_helper.rb) | 0 | ||||
-rw-r--r-- | engines/support/app/models/account_extension/tickets.rb (renamed from help/app/models/account_extension/tickets.rb) | 0 | ||||
-rw-r--r-- | engines/support/app/models/ticket.rb (renamed from help/app/models/ticket.rb) | 25 | ||||
-rw-r--r-- | engines/support/app/models/ticket_comment.rb (renamed from help/app/models/ticket_comment.rb) | 0 | ||||
-rw-r--r-- | engines/support/app/models/ticket_selection.rb (renamed from help/app/models/ticket_selection.rb) | 0 | ||||
-rw-r--r-- | engines/support/app/views/tickets/_comment.html.haml (renamed from help/app/views/tickets/_comment.html.haml) | 0 | ||||
-rw-r--r-- | engines/support/app/views/tickets/_edit_form.html.haml (renamed from help/app/views/tickets/_edit_form.html.haml) | 20 | ||||
-rw-r--r-- | engines/support/app/views/tickets/_new_comment_form.html.haml (renamed from help/app/views/tickets/_new_comment_form.html.haml) | 4 | ||||
-rw-r--r-- | engines/support/app/views/tickets/_tabs.html.haml (renamed from help/app/views/tickets/_tabs.html.haml) | 4 | ||||
-rw-r--r-- | engines/support/app/views/tickets/_ticket.html.haml (renamed from help/app/views/tickets/_ticket.html.haml) | 0 | ||||
-rw-r--r-- | engines/support/app/views/tickets/index.html.haml (renamed from help/app/views/tickets/index.html.haml) | 2 | ||||
-rw-r--r-- | engines/support/app/views/tickets/new.html.haml | 17 | ||||
-rw-r--r-- | engines/support/app/views/tickets/show.html.haml (renamed from help/app/views/tickets/show.html.haml) | 6 | ||||
-rw-r--r-- | engines/support/config/initializers/account_lifecycle.rb (renamed from help/config/initializers/account_lifecycle.rb) | 0 | ||||
-rw-r--r-- | engines/support/config/locales/en.yml (renamed from help/config/locales/en.yml) | 0 | ||||
-rw-r--r-- | engines/support/config/routes.rb (renamed from help/config/routes.rb) | 0 | ||||
-rw-r--r-- | engines/support/leap_web_help.gemspec (renamed from help/leap_web_help.gemspec) | 7 | ||||
-rw-r--r-- | engines/support/lib/leap_web_help.rb (renamed from help/lib/leap_web_help.rb) | 0 | ||||
-rw-r--r-- | engines/support/lib/leap_web_help/engine.rb | 4 | ||||
-rw-r--r-- | engines/support/lib/tasks/leap_web_help_tasks.rake (renamed from help/lib/tasks/leap_web_help_tasks.rake) | 0 | ||||
-rwxr-xr-x | engines/support/script/rails (renamed from help/script/rails) | 0 | ||||
-rw-r--r-- | engines/support/test/factories.rb (renamed from help/test/factories.rb) | 0 | ||||
-rw-r--r-- | engines/support/test/functional/tickets_controller_test.rb (renamed from help/test/functional/tickets_controller_test.rb) | 35 | ||||
-rw-r--r-- | engines/support/test/integration/create_ticket_test.rb | 64 | ||||
-rw-r--r-- | engines/support/test/integration/navigation_test.rb (renamed from certs/test/integration/navigation_test.rb) | 0 | ||||
-rw-r--r-- | engines/support/test/leap_web_help_test.rb (renamed from help/test/leap_web_help_test.rb) | 0 | ||||
-rw-r--r-- | engines/support/test/test_helper.rb (renamed from billing/test/test_helper.rb) | 2 | ||||
-rw-r--r-- | engines/support/test/unit/account_extension_test.rb (renamed from help/test/unit/account_extension_test.rb) | 0 | ||||
-rw-r--r-- | engines/support/test/unit/ticket_comment_test.rb (renamed from help/test/unit/ticket_comment_test.rb) | 0 | ||||
-rw-r--r-- | engines/support/test/unit/ticket_test.rb (renamed from help/test/unit/ticket_test.rb) | 4 | ||||
-rw-r--r-- | help/app/views/tickets/new.html.haml | 30 | ||||
-rw-r--r-- | help/lib/leap_web_help/engine.rb | 8 | ||||
-rw-r--r-- | leap_web.gemspec | 3 | ||||
-rw-r--r-- | lib/extensions/couchrest.rb (renamed from core/lib/extensions/couchrest.rb) | 2 | ||||
-rw-r--r-- | lib/extensions/simple_form.rb | 28 | ||||
-rw-r--r-- | lib/leap_web.rb | 4 | ||||
-rw-r--r-- | lib/tasks/leap_web_core_tasks.rake (renamed from core/lib/tasks/leap_web_core_tasks.rake) | 0 | ||||
-rw-r--r-- | lib/tasks/leap_web_users_tasks.rake | 10 | ||||
-rw-r--r-- | lib/tasks/test.rake | 19 | ||||
-rw-r--r-- | lib/warden/session_serializer.rb (renamed from users/lib/warden/session_serializer.rb) | 0 | ||||
-rw-r--r-- | lib/warden/strategies/secure_remote_password.rb (renamed from users/lib/warden/strategies/secure_remote_password.rb) | 0 | ||||
-rw-r--r-- | lib/webfinger.rb (renamed from users/lib/webfinger.rb) | 0 | ||||
-rw-r--r-- | lib/webfinger/host_meta_presenter.rb (renamed from users/lib/webfinger/host_meta_presenter.rb) | 0 | ||||
-rw-r--r-- | lib/webfinger/user_presenter.rb (renamed from users/lib/webfinger/user_presenter.rb) | 0 | ||||
-rw-r--r-- | test/factories.rb | 43 | ||||
-rw-r--r-- | test/files/ca.crt (renamed from certs/test/files/ca.crt) | 0 | ||||
-rw-r--r-- | test/files/ca.key (renamed from certs/test/files/ca.key) | 0 | ||||
-rw-r--r-- | test/functional/application_controller_test.rb (renamed from users/test/functional/application_controller_test.rb) | 12 | ||||
-rw-r--r-- | test/functional/helper_methods_test.rb (renamed from users/test/functional/helper_methods_test.rb) | 0 | ||||
-rw-r--r-- | test/functional/keys_controller_test.rb (renamed from users/test/functional/keys_controller_test.rb) | 0 | ||||
-rw-r--r-- | test/functional/sessions_controller_test.rb (renamed from users/test/functional/sessions_controller_test.rb) | 0 | ||||
-rw-r--r-- | test/functional/test_helpers_test.rb (renamed from users/test/functional/test_helpers_test.rb) | 0 | ||||
-rw-r--r-- | test/functional/users_controller_test.rb (renamed from users/test/functional/users_controller_test.rb) | 8 | ||||
-rw-r--r-- | test/functional/v1/certs_controller_test.rb | 46 | ||||
-rw-r--r-- | test/functional/v1/messages_controller_test.rb | 57 | ||||
-rw-r--r-- | test/functional/v1/services_controller_test.rb | 29 | ||||
-rw-r--r-- | test/functional/v1/sessions_controller_test.rb (renamed from users/test/functional/v1/sessions_controller_test.rb) | 2 | ||||
-rw-r--r-- | test/functional/v1/users_controller_test.rb (renamed from users/test/functional/v1/users_controller_test.rb) | 0 | ||||
-rw-r--r-- | test/functional/webfinger_controller_test.rb (renamed from users/test/functional/webfinger_controller_test.rb) | 0 | ||||
-rw-r--r-- | test/integration/api/Readme.md (renamed from users/test/integration/api/Readme.md) | 0 | ||||
-rw-r--r-- | test/integration/api/login_test.rb | 50 | ||||
-rw-r--r-- | test/integration/api/pgp_key_test.rb | 35 | ||||
-rwxr-xr-x | test/integration/api/python/flow_with_srp.py (renamed from users/test/integration/api/python/flow_with_srp.py) | 0 | ||||
-rwxr-xr-x | test/integration/api/python/login_wrong_username.py (renamed from users/test/integration/api/python/login_wrong_username.py) | 0 | ||||
-rwxr-xr-x | test/integration/api/python/signup.py (renamed from users/test/integration/api/python/signup.py) | 0 | ||||
-rwxr-xr-x | test/integration/api/python/signup_and_login.py (renamed from users/test/integration/api/python/signup_and_login.py) | 0 | ||||
-rwxr-xr-x | test/integration/api/python/signup_and_login_wrong_password.py (renamed from users/test/integration/api/python/signup_and_login_wrong_password.py) | 0 | ||||
-rwxr-xr-x | test/integration/api/python/umlauts.py (renamed from users/test/integration/api/python/umlauts.py) | 0 | ||||
-rw-r--r-- | test/integration/api/signup_test.rb | 20 | ||||
-rw-r--r-- | test/integration/api/srp_test.rb | 105 | ||||
-rw-r--r-- | test/integration/api/update_account_test.rb | 51 | ||||
-rw-r--r-- | test/integration/browser/account_test.rb (renamed from users/test/integration/browser/account_test.rb) | 45 | ||||
-rw-r--r-- | test/integration/browser/password_validation_test.rb | 31 | ||||
-rw-r--r-- | test/integration/browser/session_test.rb | 17 | ||||
-rw-r--r-- | test/integration/navigation_test.rb (renamed from help/test/integration/navigation_test.rb) | 0 | ||||
-rw-r--r-- | test/integration/os_detection_test.rb | 20 | ||||
-rw-r--r-- | test/leap_web_users_test.rb (renamed from users/test/leap_web_users_test.rb) | 0 | ||||
-rwxr-xr-x | test/nagios/soledad_sync.py | 95 | ||||
-rw-r--r-- | test/nagios/support/__init__.py (renamed from certs/app/mailers/.gitkeep) | 0 | ||||
-rw-r--r-- | test/nagios/support/api.py | 39 | ||||
-rw-r--r-- | test/nagios/support/config.py | 14 | ||||
-rw-r--r-- | test/nagios/support/nagios_report.py | 24 | ||||
-rw-r--r-- | test/nagios/support/nagios_test.py | 49 | ||||
-rw-r--r-- | test/nagios/support/user.py | 64 | ||||
-rwxr-xr-x | test/nagios/webapp_login.py | 90 | ||||
-rwxr-xr-x | test/nagios/webapp_signup.py | 19 | ||||
-rw-r--r-- | test/support/assert_responses.rb | 46 | ||||
-rw-r--r-- | test/support/auth_test_helper.rb (renamed from users/test/support/auth_test_helper.rb) | 0 | ||||
-rw-r--r-- | test/support/browser_integration_test.rb | 98 | ||||
-rw-r--r-- | test/support/rack_test.rb | 38 | ||||
-rw-r--r-- | test/support/stub_record_helper.rb (renamed from users/test/support/stub_record_helper.rb) | 0 | ||||
-rw-r--r-- | test/support/time_test_helper.rb (renamed from users/test/support/time_test_helper.rb) | 0 | ||||
-rw-r--r-- | test/support/with_config_helper.rb (renamed from core/test/support/with_config_helper.rb) | 0 | ||||
-rw-r--r-- | test/test_helper.rb | 78 | ||||
-rw-r--r-- | test/unit/account_test.rb (renamed from users/test/unit/account_test.rb) | 2 | ||||
-rw-r--r-- | test/unit/anonymous_user_test.rb | 23 | ||||
-rw-r--r-- | test/unit/client_certificate_test.rb (renamed from certs/test/unit/client_certificate_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/helpers/session_helper_test.rb (renamed from users/test/unit/helpers/session_helper_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/helpers/users_helper_test.rb (renamed from users/test/unit/helpers/users_helper_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/identity_test.rb (renamed from users/test/unit/identity_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/local_email_test.rb (renamed from users/test/unit/local_email_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/token_test.rb (renamed from users/test/unit/token_test.rb) | 8 | ||||
-rw-r--r-- | test/unit/user_test.rb (renamed from users/test/unit/user_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/warden_strategy_secure_remote_password_test.rb (renamed from users/test/unit/warden_strategy_secure_remote_password_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/webfinger/host_meta_presenter_test.rb (renamed from users/test/unit/webfinger/host_meta_presenter_test.rb) | 0 | ||||
-rw-r--r-- | test/unit/webfinger/user_presenter_test.rb (renamed from users/test/unit/webfinger/user_presenter_test.rb) | 0 | ||||
-rw-r--r-- | ui_dependencies.rb | 28 | ||||
-rw-r--r-- | users/Gemfile | 15 | ||||
-rw-r--r-- | users/Rakefile | 44 | ||||
-rw-r--r-- | users/app/assets/images/leap_web_users/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/assets/javascripts/leap_web_users/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/assets/stylesheets/leap_web_users/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/controllers/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/controllers/controller_extension/token_authentication.rb | 23 | ||||
-rw-r--r-- | users/app/helpers/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/mailers/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/models/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/models/service_level.rb | 19 | ||||
-rw-r--r-- | users/app/models/unauthenticated_user.rb | 6 | ||||
-rw-r--r-- | users/app/views/.gitkeep | 0 | ||||
-rw-r--r-- | users/app/views/sessions/new.html.haml | 10 | ||||
-rw-r--r-- | users/config/routes.rb | 28 | ||||
-rw-r--r-- | users/leap_web_users.gemspec | 22 | ||||
-rw-r--r-- | users/lib/leap_web_users.rb | 4 | ||||
-rw-r--r-- | users/lib/leap_web_users/engine.rb | 16 | ||||
-rw-r--r-- | users/lib/tasks/leap_web_users_tasks.rake | 4 | ||||
-rwxr-xr-x | users/script/rails | 8 | ||||
-rw-r--r-- | users/test/factories.rb | 34 | ||||
-rw-r--r-- | users/test/fixtures/.gitkeep | 0 | ||||
-rw-r--r-- | users/test/functional/.gitkeep | 0 | ||||
-rw-r--r-- | users/test/integration/.gitkeep | 0 | ||||
-rw-r--r-- | users/test/integration/api/account_flow_test.rb | 136 | ||||
-rw-r--r-- | users/test/integration/api/login_test.rb | 16 | ||||
-rw-r--r-- | users/test/integration/api/rack_test.rb | 9 | ||||
-rw-r--r-- | users/test/integration/browser/session_test.rb | 27 | ||||
-rw-r--r-- | users/test/integration/navigation_test.rb | 9 | ||||
-rw-r--r-- | users/test/support/integration_test_helper.rb | 12 | ||||
-rw-r--r-- | users/test/test_helper.rb | 9 | ||||
-rw-r--r-- | users/test/unit/.gitkeep | 0 | ||||
-rw-r--r-- | users/test/unit/email_test.rb | 19 | ||||
-rw-r--r-- | users/test/unit/unauthorized_user_test.rb | 7 |
342 files changed, 1992 insertions, 1773 deletions
@@ -22,6 +22,7 @@ bin */Gemfile.lock test/dummy/log/* test/dummy/tmp/* +*.pyc # ignore all deploy specific configuration config/couchdb.yml diff --git a/.gitmodules b/.gitmodules index 7884a42..0c28cd5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "users/app/assets/javascripts/srp"] - path = users/app/assets/javascripts/srp +[submodule "app/assets/javascripts/srp"] + path = app/assets/javascripts/srp url = https://leap.se/git/srp_js @@ -9,6 +9,6 @@ See config/customization/README.md Engines --------------------- -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. +Leap Web includes some Engines. All things in `app` will overwrite the engine behaviour. You can clone the leap web repository and add your customizations to the `app` directory. Including leap_web as a gem is currently not supported. It should not require too much work though and we would be happy to include the changes required. -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. +If you have no use for one of the engines you can remove it from the Gemfile. Engines should really be plugins - no other engines should depend upon them. If you need functionality in different engines it should probably go into the toplevel. The 'users' engine will soon become part of the main webapp for that reason. @@ -5,21 +5,21 @@ Some tips on modifying the views: * Many of the forms use [simple_form gem](https://github.com/plataformatec/simple_form) +* We still use client_side_validations for the validation code but since it is not maintained anymore we want to drop it asap. ## Engines ## -Leap Web consists of different Engines. They live in their own subdirectory and are included through bundler via their path. This way changes to the engines immediately affect the server as if they were in the main `app` directory. +Leap Web contains some. They live in their own subdirectory and are included through bundler via their path. This way changes to the engines immediately affect the server as if they were in the main `app` directory. -Currently Leap Web consists of 5 Engines: +Currently Leap Web includes 2 Engines: -* [core](https://github.com/leapcode/leap_web/blob/master/core) - ships some dependencies that are used accross all engines. This might be removed at some point. -* [users](https://github.com/leapcode/leap_web/blob/master/users) - user registration and authorization -* [certs](https://github.com/leapcode/leap_web/blob/master/certs) - Cert distribution for the EIP client -* [help](https://github.com/leapcode/leap_web/blob/master/help) - Help ticket management -* [billing](https://github.com/leapcode/leap_web/blob/master/billing) - Billing System +* [support](https://github.com/leapcode/leap_web/blob/master/engines/support) - Help ticket management +* [billing](https://github.com/leapcode/leap_web/blob/master/engines/billing) - Billing System ## Creating a new engine ## +If you want to add functionality to the webapp but keep it easy to remove you might consider adding an engine. This only makes sense if your engine really is a plugin - so no other pieces of code depend on it. + ### Rails plugin new ### Create the basic tree structure for an engine using @@ -32,28 +32,10 @@ rails plugin new ENGINE_NAME -O --full See http://guides.rubyonrails.org/engines.html for more general info about engines. -### Require Leap Web Core and dependencies ### - -Leap Web Core provides a common set of dependencies for the engines with CouchRest Model etc. -It also comes with an optional set of UI gems like haml, sass, coffeescript, uglifier, bootstrap-sass, jquery and simple_form. +You need to require engine specific gems in lib/my_engine/engine.rb: -In order to use the core dependencies you need to add leap_web_core to your .gemspec: ```ruby -# make sure LeapWeb::VERSION is available -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) -# ... - Gem::Specification.new do |s| - # ... - s.add_dependency "rails" - s.add_dependency "leap_web_core", LeapWeb::Version - end -``` - -You also need to require it before you define your engine in lib/my_engine/engine.rb: -```ruby -require "leap_web_core" -# uncomment if you want the ui gems: -# require "leap_web_core/ui_dependencies" +require "my_dependency" module MyEngine class Engine < ::Rails::Engine @@ -62,17 +44,9 @@ module MyEngine end ``` -Some development and UI dependencies can not be loaded via leap_web_core. To make them available add the following lines to your engines Gemfile - -```ruby - eval(File.read(File.dirname(__FILE__) + '/../common_dependencies.rb')) - # uncomment if you want the ui gems: - # eval(File.read(File.dirname(__FILE__) + '/../ui_dependencies.rb')) -``` - ## Creating Models ## -You can use the normal rails generators to create models. Since you required the leap_web_core gem you will be using CouchRest::Model. So your models inherit from CouchRest::Model::Base. +You can use the normal rails generators to create models. You probably want to require couchrest_model so your models inherit from CouchRest::Model::Base. http://www.couchrest.info/model/definition.html has some good first steps for setting up the model. CouchRest Model behaved strangely when using a model without a design block. So make sure to define an initial view: http://www.couchrest.info/model/view_objects.html . @@ -1,16 +1,17 @@ source 'https://rubygems.org' -eval(File.read(File.dirname(__FILE__) + '/common_dependencies.rb')) -eval(File.read(File.dirname(__FILE__) + '/ui_dependencies.rb')) - -# EITHER fetch all of the leap_web gems in one go -# gem 'leap_web' -# OR use the local versions for development instead: -gem "leap_web_core", :path => 'core' -gem 'leap_web_users', :path => 'users' -gem 'leap_web_certs', :path => 'certs' -gem 'leap_web_help', :path => 'help' -gem 'leap_web_billing', :path => 'billing' +gem "rails", "~> 3.2.18" +gem "couchrest", "~> 1.1.3" +gem "couchrest_model", "~> 2.0.0" +gem "couchrest_session_store", "~> 0.2.4" +gem "json" + +# user management +gem "ruby-srp", "~> 0.2.1" +gem "rails_warden" + +gem 'leap_web_help', :path => 'engines/support' +gem 'leap_web_billing', :path => 'engines/billing' gem 'http_accept_language' @@ -19,12 +20,62 @@ gem 'debugger', :platforms => :mri_19 # ruby 1.8 is not supported anymore # gem 'ruby-debug', :platforms => :mri_18 +gem "haml", "~> 3.1.7" +gem "bootstrap-sass", "= 2.3.2.2" +gem "jquery-rails" +gem "simple_form" +gem 'client_side_validations' +gem 'client_side_validations-simple_form' +gem "bootswatch-rails", "~> 0.5.0" + +gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be + # issues with 0.14.0 when using couchrest + +gem 'rails-i18n' # locale files for built-in validation messages and times + # https://github.com/svenfuchs/rails-i18n + # for a list of keys: + # https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml + +gem 'rdiscount' # for rendering .md templates + group :test do - gem 'fake_braintree', require: false + + # integration testing gem 'capybara', require: false - gem 'launchy' # so save_and_open_page works in integration tests - gem 'phantomjs-binaries' - gem 'minitest-stub-const' + gem 'poltergeist' # headless js + gem 'launchy' # save_and_open_page + gem 'phantomjs-binaries' # binaries specific to the os + + # moching and stubbing + gem 'mocha', '~> 0.13.0', :require => false + gem 'minitest-stub-const' # why? + + # generating test data + gem 'factory_girl_rails' # test data factories + gem 'faker' # names and numbers for test data + + # billing tests + gem 'fake_braintree', require: false +end + +group :test, :development do + gem 'thin' +end + +group :assets do + gem "haml-rails", "~> 0.3.4" + gem "sass-rails", "~> 3.2.5" + gem "coffee-rails", "~> 3.2.2" + gem "uglifier", "~> 1.2.7" + + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + gem 'therubyracer', "~> 0.10.2", :platforms => :ruby + gem 'quiet_assets' # stops logging all the asset requests +end + + +group :production do + gem 'SyslogLogger', '~> 2.0' end # unreleased so far ... but leap_web_certs need it diff --git a/Gemfile.lock b/Gemfile.lock index 0c7486f..67c04de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,53 +6,26 @@ GIT activemodel (>= 3.0.6) PATH - remote: billing + remote: engines/billing specs: leap_web_billing (0.5.0) braintree - leap_web_core (= 0.5.0) PATH - remote: certs - specs: - leap_web_certs (0.5.0) - certificate_authority (>= 0.2.0) - leap_web_core (= 0.5.0) - -PATH - remote: core - specs: - leap_web_core (0.5.0) - couchrest (~> 1.1.3) - couchrest_model (~> 2.0.0) - couchrest_session_store (~> 0.2.4) - json - rails (~> 3.2.11) - -PATH - remote: help + remote: engines/support specs: leap_web_help (0.5.0) - leap_web_core (= 0.5.0) - -PATH - remote: users - specs: - leap_web_users (0.5.0) - leap_web_core (= 0.5.0) - rails_warden - ruby-srp (~> 0.2.1) GEM remote: https://rubygems.org/ specs: SyslogLogger (2.0) - actionmailer (3.2.16) - actionpack (= 3.2.16) + actionmailer (3.2.18) + actionpack (= 3.2.18) mail (~> 2.5.4) - actionpack (3.2.16) - activemodel (= 3.2.16) - activesupport (= 3.2.16) + actionpack (3.2.18) + activemodel (= 3.2.18) + activesupport (= 3.2.18) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -60,18 +33,18 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.16) - activesupport (= 3.2.16) + activemodel (3.2.18) + activesupport (= 3.2.18) builder (~> 3.0.0) - activerecord (3.2.16) - activemodel (= 3.2.16) - activesupport (= 3.2.16) + activerecord (3.2.18) + activemodel (= 3.2.18) + activesupport (= 3.2.18) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.16) - activemodel (= 3.2.16) - activesupport (= 3.2.16) - activesupport (3.2.16) + activeresource (3.2.18) + activemodel (= 3.2.18) + activesupport (= 3.2.18) + activesupport (3.2.18) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) addressable (2.3.5) @@ -101,7 +74,7 @@ GEM coffee-script-source execjs coffee-script-source (1.6.3) - columnize (0.3.6) + columnize (0.8.9) couchrest (1.1.3) mime-types (~> 1.15) multi_json (~> 1.0) @@ -116,12 +89,12 @@ GEM couchrest couchrest_model daemons (1.1.9) - debugger (1.6.3) + debugger (1.6.6) columnize (>= 0.3.1) debugger-linecache (~> 1.2.0) - debugger-ruby_core_source (~> 1.2.4) + debugger-ruby_core_source (~> 1.3.2) debugger-linecache (1.2.0) - debugger-ruby_core_source (1.2.4) + debugger-ruby_core_source (1.3.2) erubis (2.7.0) eventmachine (1.0.3) execjs (2.0.2) @@ -170,7 +143,7 @@ GEM minitest-stub-const (0.1) mocha (0.13.3) metaclass (~> 0.0.1) - multi_json (1.8.2) + multi_json (1.10.0) nokogiri (1.6.1) mini_portile (~> 0.5.0) phantomjs-binaries (1.9.2.3) @@ -180,7 +153,7 @@ GEM cliver (~> 0.3.1) multi_json (~> 1.0) websocket-driver (>= 0.2.0) - polyglot (0.3.3) + polyglot (0.3.4) quiet_assets (1.0.2) railties (>= 3.1, < 5.0) rack (1.4.5) @@ -188,31 +161,31 @@ GEM rack (>= 0.4) rack-protection (1.5.1) rack - rack-ssl (1.3.3) + rack-ssl (1.3.4) rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.16) - actionmailer (= 3.2.16) - actionpack (= 3.2.16) - activerecord (= 3.2.16) - activeresource (= 3.2.16) - activesupport (= 3.2.16) + rails (3.2.18) + actionmailer (= 3.2.18) + actionpack (= 3.2.18) + activerecord (= 3.2.18) + activeresource (= 3.2.18) + activesupport (= 3.2.18) bundler (~> 1.0) - railties (= 3.2.16) + railties (= 3.2.18) rails-i18n (3.0.0) i18n (~> 0.5) rails (>= 3.0.0, < 4.0.0) rails_warden (0.5.7) warden (>= 1.0.0) - railties (3.2.16) - actionpack (= 3.2.16) - activesupport (= 3.2.16) + railties (3.2.18) + actionpack (= 3.2.18) + activesupport (= 3.2.18) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (10.1.1) + rake (10.3.1) rdiscount (2.0.7) rdoc (3.12.2) json (~> 1.4) @@ -244,12 +217,12 @@ GEM daemons (>= 1.0.9) eventmachine (>= 1.0.0) rack (>= 1.0.0) - thor (0.18.1) + thor (0.19.1) tilt (1.4.1) treetop (1.4.15) polyglot polyglot (>= 0.3.1) - tzinfo (0.3.38) + tzinfo (0.3.39) uglifier (1.2.7) execjs (>= 0.3.0) multi_json (~> 1.3) @@ -271,6 +244,9 @@ DEPENDENCIES client_side_validations client_side_validations-simple_form coffee-rails (~> 3.2.2) + couchrest (~> 1.1.3) + couchrest_model (~> 2.0.0) + couchrest_session_store (~> 0.2.4) debugger factory_girl_rails fake_braintree @@ -279,20 +255,21 @@ DEPENDENCIES haml-rails (~> 0.3.4) http_accept_language jquery-rails + json kaminari (= 0.13.0) launchy leap_web_billing! - leap_web_certs! - leap_web_core! leap_web_help! - leap_web_users! minitest-stub-const mocha (~> 0.13.0) phantomjs-binaries poltergeist quiet_assets + rails (~> 3.2.18) rails-i18n + rails_warden rdiscount + ruby-srp (~> 0.2.1) sass-rails (~> 3.2.5) simple_form therubyracer (~> 0.10.2) diff --git a/certs/app/assets/images/leap_web_certs/.gitkeep b/app/assets/images/leap_web_users/.gitkeep index e69de29..e69de29 100644 --- a/certs/app/assets/images/leap_web_certs/.gitkeep +++ b/app/assets/images/leap_web_users/.gitkeep diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 03a40da..9af373d 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -20,4 +20,4 @@ //= require platform //= require tickets //= require users -//= require_tree . +//= require buttons diff --git a/app/assets/javascripts/buttons.js b/app/assets/javascripts/buttons.js new file mode 100644 index 0000000..7142957 --- /dev/null +++ b/app/assets/javascripts/buttons.js @@ -0,0 +1,39 @@ +/* + * Buttons.js + * + * Use bootstrap loading state after submitting a form. + * + * Some form inputs are validaded before the submission + * so triggering loading state on click events is not a + * good idea. If the validation fails the errors will + * be displayed but the button would be in loading state. + * + * We used to trigger it based on form submission but + * we have a few forms that contain multiple buttons. + * So now we mark the buttons as clicked on click and + * put the clicked button into loading state on submit. + * + */ + +(function() { + markAsClicked = function () { + var btn = $(this) + btn.addClass('clicked') + setTimeout(function () { + btn.removeClass('clicked') + }, 1000) + }; + + markAsLoading = function(submitEvent) { + var form = submitEvent.target; + $(form).addClass('submitted') + // bootstrap loading state: + $(form).find('.btn.clicked[type="submit"]').button('loading'); + }; + + $(document).ready(function() { + $('form').submit(markAsLoading); + $('.btn[type="submit"]').click(markAsClicked); + }); + +}).call(this); diff --git a/core/app/assets/javascripts/leap.js b/app/assets/javascripts/leap.js index 94e602d..94e602d 100644 --- a/core/app/assets/javascripts/leap.js +++ b/app/assets/javascripts/leap.js diff --git a/core/app/assets/javascripts/platform.js b/app/assets/javascripts/platform.js index 108c162..108c162 100644 --- a/core/app/assets/javascripts/platform.js +++ b/app/assets/javascripts/platform.js diff --git a/users/app/assets/javascripts/srp b/app/assets/javascripts/srp -Subproject 8f33d32d40b1e21ae7fb9a92c78a275422af421 +Subproject 8f33d32d40b1e21ae7fb9a92c78a275422af421 diff --git a/users/app/assets/javascripts/users.js b/app/assets/javascripts/users.js index 8486756..e6c2fcc 100644 --- a/users/app/assets/javascripts/users.js +++ b/app/assets/javascripts/users.js @@ -1,13 +1,24 @@ (function() { + + + var settings = { + "error_class":"help-inline", + "error_tag":"span", + "wrapper_error_class":"error", + "wrapper_tag":"div", + "wrapper_class":"control-group" + } + // // LOCAL FUNCTIONS // - var poll_users, - prevent_default, - form_failed, - form_passed, + var poll_users, + prevent_default, clear_errors, + clear_field_errors, + validate_password_confirmation, + validate_password_length, update_user; prevent_default = function(event) { @@ -24,6 +35,10 @@ return $('#messages').empty(); }; + clear_field_errors = function() { + return $(settings.error_tag + '.' + settings.error_class).remove(); + }; + update_user = function(submitEvent) { var form = submitEvent.target; var token = form.dataset.token; @@ -35,22 +50,35 @@ data: $(form).serialize() }); req.done( function() { - $(form).find('input[type="submit"]').button('reset'); + $(form).find('.btn[type="submit"]').button('reset'); }); }; - markAsSubmitted = function(submitEvent) { + validate_password_confirmation = function(submitEvent) { var form = submitEvent.target; - $(form).addClass('submitted') - // bootstrap loading state: - $(form).find('input[type="submit"]').button('loading'); + var password = $(form).find('input#srp_password').val(); + var confirmation = $(form).find('input#srp_password_confirmation').val(); + if (password === confirmation) { + return true; + } + else { + displayFieldError("password_confirmation", "does not match."); + submitEvent.stopImmediatePropagation() + return false; + } }; - resetButtons = function(submitEvent) { - var form = $('form.submitted') - // bootstrap loading state: - $(form).find('input[type="submit"]').button('reset'); - $(form).removeClass('submitted') + validate_password_length = function(submitEvent) { + var form = submitEvent.target; + var password = $(form).find('input#srp_password').val(); + if (password.length > 7) { + return true; + } + else { + displayFieldError("password", "needs to be at least 8 characters long."); + submitEvent.stopImmediatePropagation() + return false; + } }; // @@ -79,7 +107,7 @@ clear_errors(); var errors = extractErrors(message); displayErrors(errors); - resetButtons(); + $('.btn[type="submit"]').button('reset'); } function extractErrors(message) { @@ -104,19 +132,40 @@ } function displayFieldError(field, error) { + var message = $.isArray(error) ? error[0] : error; var element = $('form input[name$="[' + field + ']"]'); if (element) { - element.trigger('element:validate:fail.ClientSideValidations', error).data('valid', false); + addError(element, settings, message); } }; - // - // INIT - // + function addError(element, settings, message) { + var errorElement, wrapper; + + errorElement = element.parent().find("" + settings.error_tag + "." + settings.error_class); + wrapper = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class); + if (errorElement[0] == null) { + errorElement = $("<" + settings.error_tag + "/>", { + "class": settings.error_class, + text: message + }); + element.after(errorElement); + } + wrapper.addClass(settings.wrapper_error_class); + return errorElement.text(message); + } + +// +// INIT +// $(document).ready(function() { - $('form').submit(markAsSubmitted); + $('.hidden.js-show').removeClass('hidden'); + $('.js-show').show(); $('#new_user').submit(prevent_default); + $('#new_user').submit(clear_field_errors); + $('#new_user').submit(validate_password_length); + $('#new_user').submit(validate_password_confirmation); $('#new_user').submit(srp.signup); $('#new_session').submit(prevent_default); $('#new_session').submit(srp.login); diff --git a/app/assets/stylesheets/leap.scss b/app/assets/stylesheets/leap.scss index 4c0dfe3..77104e5 100644 --- a/app/assets/stylesheets/leap.scss +++ b/app/assets/stylesheets/leap.scss @@ -44,65 +44,6 @@ } // -// OS specific -// - -.os-android { - display: none !important; -} - -html.android .os-android { - display: inherit !important; -} - -.os-linux { - display: none !important; -} - -html.linux .os-linux { - display: inherit !important; -} - -// .os-linux32 { -// display: none !important; -// } -// html.linux32 .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-osx { - display: none !important; -} - -html.osx .os-osx { - display: inherit !important; -} - -.os-other { - display: none !important; -} - -html.oldmac, html.oldwin, html.ios, html.fxos, html.other { - .os-other { - display: inherit !important; - } -} - -// // ICONS // @@ -230,14 +171,14 @@ input, textarea { } .download { a.btn { - width: 14em; + width: 15em; + font-weight: bold; small { font-weight: normal; } } } a.btn { - font-weight: bold; width: 11em; margin: 10px auto; display: block; diff --git a/certs/app/assets/javascripts/leap_web_certs/.gitkeep b/app/assets/stylesheets/leap_web_users/.gitkeep index e69de29..e69de29 100644 --- a/certs/app/assets/javascripts/leap_web_certs/.gitkeep +++ b/app/assets/stylesheets/leap_web_users/.gitkeep diff --git a/certs/app/assets/stylesheets/leap_web_certs/.gitkeep b/app/controllers/.gitkeep index e69de29..e69de29 100644 --- a/certs/app/assets/stylesheets/leap_web_certs/.gitkeep +++ b/app/controllers/.gitkeep diff --git a/users/app/controllers/account_settings_controller.rb b/app/controllers/account_settings_controller.rb index e69de29..e69de29 100644 --- a/users/app/controllers/account_settings_controller.rb +++ b/app/controllers/account_settings_controller.rb diff --git a/users/app/controllers/controller_extension/authentication.rb b/app/controllers/controller_extension/authentication.rb index d831fbe..1f73f38 100644 --- a/users/app/controllers/controller_extension/authentication.rb +++ b/app/controllers/controller_extension/authentication.rb @@ -8,17 +8,24 @@ module ControllerExtension::Authentication end def current_user - @current_user ||= token_authenticate || warden.user + @current_user ||= token_authenticate || warden.user || anonymous end def logged_in? - !!current_user + current_user.is_a? User end - def authorize + def require_login access_denied unless logged_in? end + # some actions only make sense if you are not logged in yet. + # (login, signup). If a user tries to perform these they will + # be redirected to their dashboard. + def redirect_if_logged_in + redirect_to home_url if logged_in? + end + def access_denied respond_to do |format| format.html do @@ -35,10 +42,10 @@ module ControllerExtension::Authentication end def admin? - current_user && current_user.is_admin? + current_user.is_admin? end - def authorize_admin + def require_admin access_denied unless admin? end @@ -65,4 +72,10 @@ module ControllerExtension::Authentication request.env['warden.options'] && request.env['warden.options'][:attempted_path] end + + protected + + def anonymous + AnonymousUser.new + end end diff --git a/app/controllers/controller_extension/token_authentication.rb b/app/controllers/controller_extension/token_authentication.rb new file mode 100644 index 0000000..6e0a6ce --- /dev/null +++ b/app/controllers/controller_extension/token_authentication.rb @@ -0,0 +1,27 @@ +module ControllerExtension::TokenAuthentication + extend ActiveSupport::Concern + + def token + @token ||= authenticate_with_http_token do |token_id, options| + Token.find(token_id) + end + end + + def token_authenticate + @token_authenticated ||= token.authenticate if token + end + + def require_token + access_denied unless token_authenticate + end + + def logout + super + clear_token + end + + def clear_token + token.destroy if token + end +end + diff --git a/users/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb index fb28901..fb28901 100644 --- a/users/app/controllers/keys_controller.rb +++ b/app/controllers/keys_controller.rb diff --git a/users/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 0195f30..8919a4d 100644 --- a/users/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,7 +1,8 @@ class SessionsController < ApplicationController + before_filter :redirect_if_logged_in, :only => [:new] + def new - redirect_to home_url if logged_in? @session = Session.new if authentication_errors @errors = authentication_errors diff --git a/users/app/controllers/users_base_controller.rb b/app/controllers/users_base_controller.rb index 9becf0d..9becf0d 100644 --- a/users/app/controllers/users_base_controller.rb +++ b/app/controllers/users_base_controller.rb diff --git a/users/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a5461cd..c8e09b6 100644 --- a/users/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,9 +4,10 @@ class UsersController < UsersBaseController - before_filter :authorize, :only => [:show, :edit, :update, :destroy] + before_filter :require_login, :except => [:new] + before_filter :redirect_if_logged_in, :only => [:new] + before_filter :require_admin, :only => [:index, :deactivate, :enable] before_filter :fetch_user, :only => [:show, :edit, :update, :destroy, :deactivate, :enable] - before_filter :authorize_admin, :only => [:index, :deactivate, :enable] respond_to :html diff --git a/app/controllers/v1/certs_controller.rb b/app/controllers/v1/certs_controller.rb new file mode 100644 index 0000000..73409ef --- /dev/null +++ b/app/controllers/v1/certs_controller.rb @@ -0,0 +1,20 @@ +class V1::CertsController < ApplicationController + + before_filter :require_login, :unless => :anonymous_certs_allowed? + + # GET /cert + def show + @cert = ClientCertificate.new(:prefix => service_level.cert_prefix) + render text: @cert.to_s, content_type: 'text/plain' + end + + protected + + def anonymous_certs_allowed? + APP_CONFIG[:allow_anonymous_certs] + end + + def service_level + current_user.effective_service_level + end +end diff --git a/app/controllers/v1/messages_controller.rb b/app/controllers/v1/messages_controller.rb new file mode 100644 index 0000000..85156b7 --- /dev/null +++ b/app/controllers/v1/messages_controller.rb @@ -0,0 +1,24 @@ +module V1 + class MessagesController < ApplicationController + + skip_before_filter :verify_authenticity_token + before_filter :require_token + + respond_to :json + + def index + render json: current_user.messages + end + + def update + if message = Message.find(params[:id]) + message.mark_as_read_by(current_user) + message.save + render json: true + else + render json: false + end + end + + end +end diff --git a/app/controllers/v1/services_controller.rb b/app/controllers/v1/services_controller.rb new file mode 100644 index 0000000..594940e --- /dev/null +++ b/app/controllers/v1/services_controller.rb @@ -0,0 +1,8 @@ +class V1::ServicesController < ApplicationController + + respond_to :json + + def show + respond_with current_user.effective_service_level + end +end diff --git a/users/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb index eb6c322..d88fcdc 100644 --- a/users/app/controllers/v1/sessions_controller.rb +++ b/app/controllers/v1/sessions_controller.rb @@ -2,6 +2,7 @@ module V1 class SessionsController < ApplicationController skip_before_filter :verify_authenticity_token + before_filter :require_token, only: :destroy def new @session = Session.new @@ -37,7 +38,7 @@ module V1 def login_response handshake = session.delete(:handshake) || {} - handshake.to_hash.merge(:id => current_user.id, :token => @token.id) + handshake.to_hash.merge(:id => current_user.id, :token => @token.to_s) end end diff --git a/users/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index 0903888..8897d01 100644 --- a/users/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -3,8 +3,8 @@ module V1 skip_before_filter :verify_authenticity_token before_filter :fetch_user, :only => [:update] - before_filter :authorize, :only => [:update] - before_filter :authorize_admin, :only => [:index] + before_filter :require_admin, :only => [:index] + before_filter :require_token, :only => [:update] respond_to :json diff --git a/users/app/controllers/webfinger_controller.rb b/app/controllers/webfinger_controller.rb index 8872802..8872802 100644 --- a/users/app/controllers/webfinger_controller.rb +++ b/app/controllers/webfinger_controller.rb diff --git a/app/designs/message/by_user_ids_to_show.js b/app/designs/message/by_user_ids_to_show.js new file mode 100644 index 0000000..e33566b --- /dev/null +++ b/app/designs/message/by_user_ids_to_show.js @@ -0,0 +1,7 @@ +function (doc) { + if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) { + doc.user_ids_to_show.forEach(function (userId) { + emit(userId, 1); + }); + } +} diff --git a/app/designs/message/by_user_ids_to_show_and_created_at.js b/app/designs/message/by_user_ids_to_show_and_created_at.js new file mode 100644 index 0000000..54e4604 --- /dev/null +++ b/app/designs/message/by_user_ids_to_show_and_created_at.js @@ -0,0 +1,9 @@ +// not using at moment +// call with something like Message.by_user_ids_to_show_and_created_at.startkey([user_id, start_date]).endkey([user_id,end_date]) +function (doc) { + if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) { + doc.user_ids_to_show.forEach(function (userId) { + emit([userId, doc.created_at], 1); + }); + } +} diff --git a/app/designs/user/by_created_at_and_one_month_warning_not_sent.js b/app/designs/user/by_created_at_and_one_month_warning_not_sent.js new file mode 100644 index 0000000..53a95de --- /dev/null +++ b/app/designs/user/by_created_at_and_one_month_warning_not_sent.js @@ -0,0 +1,5 @@ +function (doc) { + if ((doc['type'] == 'User') && (doc['created_at'] != null) && (doc['one_month_warning_sent'] == null)) { + emit(doc['created_at'], 1); + } +} diff --git a/certs/app/controllers/.gitkeep b/app/helpers/.gitkeep index e69de29..e69de29 100644 --- a/certs/app/controllers/.gitkeep +++ b/app/helpers/.gitkeep diff --git a/core/app/helpers/core_helper.rb b/app/helpers/core_helper.rb index a6c7479..4126906 100644 --- a/core/app/helpers/core_helper.rb +++ b/app/helpers/core_helper.rb @@ -6,8 +6,8 @@ module CoreHelper # # insert common buttons (download, login, etc) # - def home_page_buttons(on_user_page = false) - render 'common/home_page_buttons', {:on_user_page => on_user_page} + def home_page_buttons + render 'common/home_page_buttons' end end diff --git a/core/app/helpers/download_helper.rb b/app/helpers/download_helper.rb index ee0fe73..ee0fe73 100644 --- a/core/app/helpers/download_helper.rb +++ b/app/helpers/download_helper.rb diff --git a/users/app/helpers/email_aliases_helper.rb b/app/helpers/email_aliases_helper.rb index b56b068..b56b068 100644 --- a/users/app/helpers/email_aliases_helper.rb +++ b/app/helpers/email_aliases_helper.rb diff --git a/core/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb index 19cb934..19cb934 100644 --- a/core/app/helpers/navigation_helper.rb +++ b/app/helpers/navigation_helper.rb diff --git a/users/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index 309f8b2..309f8b2 100644 --- a/users/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb diff --git a/users/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index f56faab..1b2dc5d 100644 --- a/users/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -1,7 +1,7 @@ module UsersHelper def user_form_class(*classes) - (classes + ['user', 'form', (@user.new_record? ? 'new' : 'edit')]).compact.join(' ') + (classes + ['user', 'hidden', 'js-show', (@user.new_record? ? 'new' : 'edit')]).compact.join(' ') end def wrapped(item, options = {}) diff --git a/users/app/models/account.rb b/app/models/account.rb index cf998e4..cf998e4 100644 --- a/users/app/models/account.rb +++ b/app/models/account.rb diff --git a/app/models/anonymous_service_level.rb b/app/models/anonymous_service_level.rb new file mode 100644 index 0000000..4366a4a --- /dev/null +++ b/app/models/anonymous_service_level.rb @@ -0,0 +1,30 @@ +class AnonymousServiceLevel + + delegate :to_json, to: :config_hash + + def cert_prefix + if APP_CONFIG[:allow_limited_certs] + APP_CONFIG[:limited_cert_prefix] + elsif APP_CONFIG[:allow_unlimited_certs] + APP_CONFIG[:unlimited_cert_prefix] + end + end + + def description + if APP_CONFIG[:allow_anonymous_certs] + "anonymous access to the VPN" + else + "please login to access our services" + end + end + + protected + + def config_hash + { name: "anonymous", + description: description, + eip_rate_limit: APP_CONFIG[:allow_limited_certs] + } + end + +end diff --git a/app/models/anonymous_user.rb b/app/models/anonymous_user.rb new file mode 100644 index 0000000..87239eb --- /dev/null +++ b/app/models/anonymous_user.rb @@ -0,0 +1,31 @@ +# The nil object for the user class +class AnonymousUser < Object + + def effective_service_level + AnonymousServiceLevel.new + end + + def is_admin? + false + end + + def id + nil + end + + def email + nil + end + + def email_address + nil + end + + def login + nil + end + + def messages + [] + end +end diff --git a/certs/app/models/client_certificate.rb b/app/models/client_certificate.rb index 76b07a2..76b07a2 100644 --- a/certs/app/models/client_certificate.rb +++ b/app/models/client_certificate.rb diff --git a/users/app/models/email.rb b/app/models/email.rb index a9a503f..a9a503f 100644 --- a/users/app/models/email.rb +++ b/app/models/email.rb diff --git a/users/app/models/identity.rb b/app/models/identity.rb index 9b97b51..ad8c01e 100644 --- a/users/app/models/identity.rb +++ b/app/models/identity.rb @@ -70,6 +70,12 @@ class Identity < CouchRest::Model::Base end end + def self.destroy_all_for(user) + Identity.by_user_id.key(user.id).each do |identity| + identity.destroy + end + end + def self.destroy_all_disabled Identity.disabled.each do |identity| identity.destroy diff --git a/users/app/models/local_email.rb b/app/models/local_email.rb index 2b4c65e..2b4c65e 100644 --- a/users/app/models/local_email.rb +++ b/app/models/local_email.rb diff --git a/users/app/models/login_format_validation.rb b/app/models/login_format_validation.rb index c1fcf70..c1fcf70 100644 --- a/users/app/models/login_format_validation.rb +++ b/app/models/login_format_validation.rb diff --git a/app/models/message.rb b/app/models/message.rb new file mode 100644 index 0000000..424f094 --- /dev/null +++ b/app/models/message.rb @@ -0,0 +1,29 @@ +class Message < CouchRest::Model::Base + + use_database :messages + + property :text, String + property :user_ids_to_show, [String] + property :user_ids_have_shown, [String] # is this necessary to store? + + timestamps! + + design do + own_path = Pathname.new(File.dirname(__FILE__)) + load_views(own_path.join('..', 'designs', 'message')) + end + + def mark_as_read_by(user) + user_ids_to_show.delete(user.id) + # is it necessary to keep track of what users have already seen it? + user_ids_have_shown << user.id unless read_by?(user) + end + + def read_by?(user) + user_ids_have_shown.include?(user.id) + end + + def unread_by?(user) + user_ids_to_show.include?(user.id) + end +end diff --git a/users/app/models/pgp_key.rb b/app/models/pgp_key.rb index 66f8660..66f8660 100644 --- a/users/app/models/pgp_key.rb +++ b/app/models/pgp_key.rb diff --git a/app/models/service_level.rb b/app/models/service_level.rb new file mode 100644 index 0000000..a8df55b --- /dev/null +++ b/app/models/service_level.rb @@ -0,0 +1,46 @@ +class ServiceLevel + + def initialize(attributes = {}) + @id = attributes[:id] || APP_CONFIG[:default_service_level] + end + + def self.select_options + APP_CONFIG[:service_levels].map do |id,config_hash| + [config_hash[:description], id] + end + end + + def id + @id + end + + delegate :to_json, to: :config_hash + + def cert_prefix + if limited_cert? + APP_CONFIG[:limited_cert_prefix] + elsif APP_CONFIG[:allow_unlimited_certs] + APP_CONFIG[:unlimited_cert_prefix] + end + end + + def provides?(service) + services.include? service + end + + def services + config_hash[:services] || [] + end + + protected + + def limited_cert? + APP_CONFIG[:allow_limited_certs] && + (!APP_CONFIG[:allow_unlimited_certs] || config_hash[:eip_rate_limit]) + end + + def config_hash + @config_hash || APP_CONFIG[:service_levels][@id].with_indifferent_access + end + +end diff --git a/users/app/models/session.rb b/app/models/session.rb index 0d7e10e..0d7e10e 100644 --- a/users/app/models/session.rb +++ b/app/models/session.rb diff --git a/users/app/models/token.rb b/app/models/token.rb index 001eb40..e759ee3 100644 --- a/users/app/models/token.rb +++ b/app/models/token.rb @@ -30,6 +30,10 @@ class Token < CouchRest::Model::Base end end + def to_s + id + end + def authenticate if expired? destroy @@ -40,6 +44,14 @@ class Token < CouchRest::Model::Base end end + # Tokens can be cleaned up in different ways. + # So let's make sure we don't crash if they disappeared + def destroy_with_rescue + destroy_without_rescue + rescue RestClient::ResourceNotFound + end + alias_method_chain :destroy, :rescue + def touch self.last_seen_at = Time.now save diff --git a/users/app/models/user.rb b/app/models/user.rb index 720f5a9..6678de6 100644 --- a/users/app/models/user.rb +++ b/app/models/user.rb @@ -13,6 +13,8 @@ class User < CouchRest::Model::Base property :desired_service_level_code, Integer, :accessible => true property :effective_service_level_code, Integer, :accessible => true + property :one_month_warning_sent, TrueClass + before_save :update_effective_service_level validates :login, :password_salt, :password_verifier, @@ -59,6 +61,15 @@ class User < CouchRest::Model::Base login end + # use this if you want to get a working email address only. + def email + if effective_service_level.provides?('email') + email_address + end + end + + # use this if you want the email address associated with a + # user no matter if the user actually has a local email account def email_address LocalEmail.new(login) end @@ -72,6 +83,14 @@ class User < CouchRest::Model::Base Ticket.for_user(self).limit(count).all #defaults to having most recent updated first end + def messages(unseen = true) + #TODO for now this only shows unseen messages. Will we ever want seen ones? Is it necessary to store? + + # we don't want to emit all the userids associated with a message, so only emit id and text. + Message.by_user_ids_to_show.key(self.id).map { |message| [message.id, message.text] } + + end + # DEPRECATED # # Please set the key on the identity directly @@ -110,6 +129,32 @@ class User < CouchRest::Model::Base ServiceLevel.new({id: code}) end + + def self.send_one_month_warnings + + # To determine warnings to send, need to get all users where one_month_warning_sent is not set, and where it was created greater than or equal to 1 month ago. + # TODO: might want to further limit to enabled accounts, and, based on provider's service level configuration, for particular service levels. + users_to_warn = User.by_created_at_and_one_month_warning_not_sent.endkey(Time.now-1.month) + + users_to_warn.each do |user| + # instead of loop could use something like: + # message.user_ids_to_show = users_to_warn.map(&:id) + # but would still need to loop through users to store one_month_warning_sent + + if !@message + # create a message for today's date + # only want to create once, and only if it will be used. + @message = Message.new(:text => I18n.t(:payment_one_month_warning, :date_in_one_month => (Time.now+1.month).strftime("%Y-%d-%m"))) + end + + @message.user_ids_to_show << user.id + user.one_month_warning_sent = true + user.save + end + @message.save if @message + + end + protected ## diff --git a/certs/app/helpers/.gitkeep b/app/views/.gitkeep index e69de29..e69de29 100644 --- a/certs/app/helpers/.gitkeep +++ b/app/views/.gitkeep diff --git a/app/views/common/_action_buttons.html.haml b/app/views/common/_action_buttons.html.haml new file mode 100644 index 0000000..c74fcd1 --- /dev/null +++ b/app/views/common/_action_buttons.html.haml @@ -0,0 +1,11 @@ +.home-buttons + .row-fluid.second + .login.span4 + %span.link= link_to(icon('ok-sign', icon_color) + t(:login), login_path, :class => 'btn') + %span.info= t(:login_info) + .signup.span4 + %span.link= link_to(icon('user', icon_color) + t(:signup), signup_path, :class => 'btn') + %span.info= t(:signup_info) + .help.span4 + %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), new_ticket_path, :class => 'btn') + %span.info= t(:help_info) diff --git a/app/views/common/_download_button.html.haml b/app/views/common/_download_button.html.haml new file mode 100644 index 0000000..e57c56b --- /dev/null +++ b/app/views/common/_download_button.html.haml @@ -0,0 +1,8 @@ +.home-buttons + .row-fluid.first + .span2 + .download.span8 + = link_to client_download_url, class: "btn btn-large btn-primary" do + = big_icon('download') + = t(:download_client) + .span2 diff --git a/app/views/common/_home_page_buttons.html.haml b/app/views/common/_home_page_buttons.html.haml new file mode 100644 index 0000000..8c47983 --- /dev/null +++ b/app/views/common/_home_page_buttons.html.haml @@ -0,0 +1,8 @@ +- icon_color = :black + += render 'common/download_button' +- if local_assigns[:divider] + .row-fluid + .span12 + = render local_assigns[:divider] += render 'common/action_buttons', icon_color: icon_color diff --git a/users/app/views/emails/_email.html.haml b/app/views/emails/_email.html.haml index ea59cec..ea59cec 100644 --- a/users/app/views/emails/_email.html.haml +++ b/app/views/emails/_email.html.haml diff --git a/app/views/home/_content.html.haml b/app/views/home/_content.html.haml index 3d351e9..e47fdaf 100644 --- a/app/views/home/_content.html.haml +++ b/app/views/home/_content.html.haml @@ -9,6 +9,4 @@ .row-fluid %hr %p - = link_to "fetch a cert", cert_path - %p = link_to "make donation", new_payment_path if APP_CONFIG[:payment].present? diff --git a/core/app/views/kaminari/_first_page.html.haml b/app/views/kaminari/_first_page.html.haml index 34436e3..34436e3 100644 --- a/core/app/views/kaminari/_first_page.html.haml +++ b/app/views/kaminari/_first_page.html.haml diff --git a/core/app/views/kaminari/_gap.html.haml b/app/views/kaminari/_gap.html.haml index 51de678..51de678 100644 --- a/core/app/views/kaminari/_gap.html.haml +++ b/app/views/kaminari/_gap.html.haml diff --git a/core/app/views/kaminari/_last_page.html.haml b/app/views/kaminari/_last_page.html.haml index c90433c..c90433c 100644 --- a/core/app/views/kaminari/_last_page.html.haml +++ b/app/views/kaminari/_last_page.html.haml diff --git a/core/app/views/kaminari/_next_page.html.haml b/app/views/kaminari/_next_page.html.haml index ea6cab2..ea6cab2 100644 --- a/core/app/views/kaminari/_next_page.html.haml +++ b/app/views/kaminari/_next_page.html.haml diff --git a/core/app/views/kaminari/_page.html.haml b/app/views/kaminari/_page.html.haml index 2f2f142..2f2f142 100644 --- a/core/app/views/kaminari/_page.html.haml +++ b/app/views/kaminari/_page.html.haml diff --git a/core/app/views/kaminari/_paginator.html.haml b/app/views/kaminari/_paginator.html.haml index 79c5b92..79c5b92 100644 --- a/core/app/views/kaminari/_paginator.html.haml +++ b/app/views/kaminari/_paginator.html.haml diff --git a/core/app/views/kaminari/_prev_page.html.haml b/app/views/kaminari/_prev_page.html.haml index d274bf4..d274bf4 100644 --- a/core/app/views/kaminari/_prev_page.html.haml +++ b/app/views/kaminari/_prev_page.html.haml diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index 5909bdd..340d36c 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -6,5 +6,5 @@ = link_to icon('info-sign') + t(:about), about_path - if lookup_context.exists?('pages/contact') = link_to icon('comment') + t(:contact), contact_path - - if APP_CONFIG[:service_levels] - = link_to icon('shopping-cart') + t(:pricing), pricing_path
\ No newline at end of file + - if APP_CONFIG[:service_levels].present? + = link_to icon('shopping-cart') + t(:pricing), pricing_path diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 157f1df..a1dd47a 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -8,5 +8,5 @@ %li = link_to t(:logout), logout_path, :method => :delete - if @user && @show_navigation - .user_heading + .lead = @user.email_address diff --git a/app/views/layouts/_masthead.html.haml b/app/views/layouts/_masthead.html.haml index 35225a1..fde5915 100644 --- a/app/views/layouts/_masthead.html.haml +++ b/app/views/layouts/_masthead.html.haml @@ -2,5 +2,3 @@ .title %span.sitename %a{:href => home_path}= APP_CONFIG[:domain] - - if @show_navigation - = t(:user_control_panel)
\ No newline at end of file diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 1cd4ec3..d213fe1 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -14,6 +14,9 @@ = render 'layouts/masthead' #main .container-fluid + - if @show_navigation + .row-fluid + %h1= t(:user_control_panel) - if logged_in? .row-fluid .span12 diff --git a/app/views/pages/pricing.html.haml b/app/views/pages/pricing.html.haml index 77699d8..e339d27 100644 --- a/app/views/pages/pricing.html.haml +++ b/app/views/pages/pricing.html.haml @@ -13,9 +13,9 @@ %td= level[:name] %td= level[:description] %td - - if level[:cost].nil? || level[:cost] == 0 + - if level[:rate].nil? || level[:rate] == 0 = t(:free) - else - = level[:cost].map{|currency,cost| "#{cost} #{currency}"}.join(', ') + = level[:rate].collect{|currency, price| "#{currency} #{price}"}.join(', ') - else - No service levels are configured.
\ No newline at end of file + No service levels are configured. diff --git a/app/views/sessions/new.html.haml b/app/views/sessions/new.html.haml new file mode 100644 index 0000000..bb7e4bd --- /dev/null +++ b/app/views/sessions/new.html.haml @@ -0,0 +1,9 @@ +.span1 +.span9 + %h2=t :login + .lead=t :login_info + = render :partial => 'users/warnings' + = simple_form_for [:api, @session], validate: true, html: { id: :new_session, class: 'form-horizontal hidden js-show', style: "display:none;" } do |f| + = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } + = f.input :password, :required => false, :input_html => { :id => :srp_password } + = f.button :wrapped, value: t(:login), cancel: home_path diff --git a/users/app/views/sessions/new.json.erb b/app/views/sessions/new.json.erb index 36154b8..36154b8 100644 --- a/users/app/views/sessions/new.json.erb +++ b/app/views/sessions/new.json.erb diff --git a/users/app/views/users/_change_password.html.haml b/app/views/users/_change_password.html.haml index 425e3ee..425e3ee 100644 --- a/users/app/views/users/_change_password.html.haml +++ b/app/views/users/_change_password.html.haml diff --git a/users/app/views/users/_change_pgp_key.html.haml b/app/views/users/_change_pgp_key.html.haml index e465125..e465125 100644 --- a/users/app/views/users/_change_pgp_key.html.haml +++ b/app/views/users/_change_pgp_key.html.haml diff --git a/users/app/views/users/_change_service_level.html.haml b/app/views/users/_change_service_level.html.haml index 61e67d9..42315a2 100644 --- a/users/app/views/users/_change_service_level.html.haml +++ b/app/views/users/_change_service_level.html.haml @@ -8,11 +8,11 @@ %legend= t(:service_level) - if @user != current_user = t(:desired_service_level) - = f.select :desired_service_level_code, ServiceLevel.authenticated_select_options, :selected => @user.desired_service_level.id + = f.select :desired_service_level_code, ServiceLevel.select_options, :selected => @user.desired_service_level.id - if @user != current_user %p = t(:effective_service_level) - = f.select :effective_service_level_code, ServiceLevel.authenticated_select_options, :selected => @user.effective_service_level.id + = f.select :effective_service_level_code, ServiceLevel.select_options, :selected => @user.effective_service_level.id .control-group .controls = f.submit t(:save), :class => 'btn', :data => {"loading-text" => "Saving..."} diff --git a/users/app/views/users/_destroy_account.html.haml b/app/views/users/_destroy_account.html.haml index 445f3c4..445f3c4 100644 --- a/users/app/views/users/_destroy_account.html.haml +++ b/app/views/users/_destroy_account.html.haml diff --git a/users/app/views/users/_edit.html.haml b/app/views/users/_edit.html.haml index 1d2b68a..1d2b68a 100644 --- a/users/app/views/users/_edit.html.haml +++ b/app/views/users/_edit.html.haml diff --git a/users/app/views/users/_user.html.haml b/app/views/users/_user.html.haml index 583d22f..583d22f 100644 --- a/users/app/views/users/_user.html.haml +++ b/app/views/users/_user.html.haml diff --git a/users/app/views/users/_warnings.html.haml b/app/views/users/_warnings.html.haml index 79ab103..baf80a4 100644 --- a/users/app/views/users/_warnings.html.haml +++ b/app/views/users/_warnings.html.haml @@ -9,4 +9,4 @@ document.getElementById('cookie_warning').style.display = 'block'; } else { document.getElementById('cookie_warning').style.display = 'none'; - }
\ No newline at end of file + } diff --git a/users/app/views/users/edit.html.haml b/app/views/users/edit.html.haml index 434c025..434c025 100644 --- a/users/app/views/users/edit.html.haml +++ b/app/views/users/edit.html.haml diff --git a/users/app/views/users/index.html.haml b/app/views/users/index.html.haml index fc1001e..fc1001e 100644 --- a/users/app/views/users/index.html.haml +++ b/app/views/users/index.html.haml diff --git a/users/app/views/users/new.html.haml b/app/views/users/new.html.haml index aecf831..bc36068 100644 --- a/users/app/views/users/new.html.haml +++ b/app/views/users/new.html.haml @@ -1,19 +1,21 @@ -# --# This form is handled entirely by javascript, so take care when changing element ids. +-# This form is handled entirely by javascript +-# Please take care when changing element ids. +-# +-# The form is hidden when no js is available +-# to prevent submission in the clear. -# -- form_options = {:url => '/not-used', :html => {:id => 'new_user', :class => user_form_class('form-horizontal')}, :validate => true} +- form_options = {url: '/not-used', html: {id: 'new_user', class: user_form_class('form-horizontal'), style: 'display:none'}, validate: true} .span1 .span9 - = render :partial => 'warnings' %h2=t :signup + .lead=t :signup_info + = render :partial => 'warnings' = simple_form_for(@user, form_options) do |f| - %legend= t(:signup_message) = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } - .form-actions - = f.button :submit, :value => t(:signup), :class => 'btn btn-primary' - = link_to t(:cancel), home_path, :class => 'btn' + = f.button :wrapped, value: t(:signup), cancel: home_path diff --git a/users/app/views/users/show.html.haml b/app/views/users/show.html.haml index c587017..ddc33ab 100644 --- a/users/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -20,6 +20,11 @@ - # %li= icon('envelope') + link_to(t(:overview_email), {insert path for user identities, presuambly} %li= icon('question-sign') + link_to(t(:overview_tickets), user_tickets_path(@user)) %li= icon('shopping-cart') + link_to(t(:overview_billing), billing_top_link(@user)) if APP_CONFIG[:billing] + + .container-fluid .row-fluid - = home_page_buttons(true)
\ No newline at end of file + %h4 To use bitmask services: + = link_to client_download_url, class: "btn btn-primary" do + %i.icon-arrow-down.icon-white + = t(:download_client) diff --git a/users/app/views/v1/sessions/new.json.erb b/app/views/v1/sessions/new.json.erb index 36154b8..36154b8 100644 --- a/users/app/views/v1/sessions/new.json.erb +++ b/app/views/v1/sessions/new.json.erb diff --git a/users/app/views/webfinger/host_meta.xml.erb b/app/views/webfinger/host_meta.xml.erb index cfcbcc0..cfcbcc0 100644 --- a/users/app/views/webfinger/host_meta.xml.erb +++ b/app/views/webfinger/host_meta.xml.erb diff --git a/users/app/views/webfinger/search.xml.erb b/app/views/webfinger/search.xml.erb index 7328552..7328552 100644 --- a/users/app/views/webfinger/search.xml.erb +++ b/app/views/webfinger/search.xml.erb diff --git a/certs/Gemfile b/certs/Gemfile deleted file mode 100644 index 992f236..0000000 --- a/certs/Gemfile +++ /dev/null @@ -1,14 +0,0 @@ -source "https://rubygems.org" - -eval(File.read(File.dirname(__FILE__) + '/../common_dependencies.rb')) - -# We require leap_web_core from here so we can use the path option. -gem "leap_web_core", :path => '../core' - -# Declare your gem's dependencies in leap_web_users.gemspec. -# Bundler will treat runtime dependencies like base dependencies, and -# development dependencies will be added by default to the :development group. -gemspec - -# To use debugger -# gem 'ruby-debug' diff --git a/certs/Rakefile b/certs/Rakefile deleted file mode 100644 index 54ed86d..0000000 --- a/certs/Rakefile +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env rake - -require 'rake/packagetask' -require 'rubygems/package_task' - -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' -end -begin - require 'rdoc/task' -rescue LoadError - require 'rdoc/rdoc' - require 'rake/rdoctask' - RDoc::Task = Rake::RDocTask -end - -RDoc::Task.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'LeapWebCerts' - rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -spec = eval(File.read('leap_web_certs.gemspec')) -Gem::PackageTask.new(spec) do |p| - p.gem_spec = spec -end - -Bundler::GemHelper.install_tasks - -require 'rake/testtask' - -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.libs << 'test' - t.pattern = 'test/**/*_test.rb' - t.verbose = false -end - - -task :default => :test diff --git a/certs/Readme.md b/certs/Readme.md deleted file mode 100644 index 4ea8d9d..0000000 --- a/certs/Readme.md +++ /dev/null @@ -1,9 +0,0 @@ -LeapWebCerts -========= - - -Configuration -------------- - - -Currently LeapWebCerts falls back to handing out a cert in /config/cert if the cert pool is empty. You need to add that file in the application that includes this engine. diff --git a/certs/app/controllers/certs_controller.rb b/certs/app/controllers/certs_controller.rb deleted file mode 100644 index 62ef3fd..0000000 --- a/certs/app/controllers/certs_controller.rb +++ /dev/null @@ -1,51 +0,0 @@ -class CertsController < ApplicationController - - before_filter :login_if_required - - # GET /cert - def show - @cert = ClientCertificate.new(:prefix => certificate_prefix) - render text: @cert.to_s, content_type: 'text/plain' - end - - protected - - def login_if_required - authorize unless APP_CONFIG[:allow_anonymous_certs] - end - - # - # this is some temporary logic until we store the service level in the user db. - # - # better logic might look like this: - # - # if logged_in? - # service_level = user.service_level - # elsif allow_anonymous? - # service_level = service_levels[:anonymous] - # else - # service_level = nil - # end - # - # if service_level.bandwidth == 'limited' && allow_limited? - # prefix = limited - # elsif allow_unlimited? - # prefix = unlimited - # else - # prefix = nil - # end - # - def certificate_prefix - if logged_in? - if APP_CONFIG[:allow_unlimited_certs] - APP_CONFIG[:unlimited_cert_prefix] - elsif APP_CONFIG[:allow_limited_certs] - APP_CONFIG[:limited_cert_prefix] - end - elsif !APP_CONFIG[:allow_limited_certs] - APP_CONFIG[:unlimited_cert_prefix] - else - APP_CONFIG[:limited_cert_prefix] - end - end -end diff --git a/certs/app/helpers/certs_helper.rb b/certs/app/helpers/certs_helper.rb deleted file mode 100644 index 94e76b8..0000000 --- a/certs/app/helpers/certs_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module CertsHelper -end diff --git a/certs/app/models/.gitkeep b/certs/app/models/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/certs/app/models/.gitkeep +++ /dev/null diff --git a/certs/app/views/.gitkeep b/certs/app/views/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/certs/app/views/.gitkeep +++ /dev/null diff --git a/certs/config/locales/en.yml b/certs/config/locales/en.yml deleted file mode 100644 index 18e4f47..0000000 --- a/certs/config/locales/en.yml +++ /dev/null @@ -1,2 +0,0 @@ -en: - cert_pool_empty: "Sorry the Cert pool is empty, please check back later." diff --git a/certs/config/routes.rb b/certs/config/routes.rb deleted file mode 100644 index cb97757..0000000 --- a/certs/config/routes.rb +++ /dev/null @@ -1,5 +0,0 @@ -Rails.application.routes.draw do - scope '/1' do - resource :cert, :only => [:show] - end -end diff --git a/certs/leap_web_certs.gemspec b/certs/leap_web_certs.gemspec deleted file mode 100644 index 21be09d..0000000 --- a/certs/leap_web_certs.gemspec +++ /dev/null @@ -1,21 +0,0 @@ -$:.push File.expand_path("../lib", __FILE__) - -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) - -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "leap_web_certs" - s.version = LeapWeb::VERSION - s.authors = ["Azul"] - s.email = ["azul@leap.se"] - s.homepage = "http://www.leap.se" - s.summary = "Cert distribution for the leap platform" - s.description = "This plugin for the leap platform distributes certs for the EIP client. It fetches the certs from a pool in CouchDB that is filled by leap-ca." - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] - s.test_files = Dir["test/**/*"] - - s.add_dependency "leap_web_core", LeapWeb::VERSION - s.add_dependency "certificate_authority", [">= 0.2.0"] - -end diff --git a/certs/lib/leap_web_certs.rb b/certs/lib/leap_web_certs.rb deleted file mode 100644 index beb683d..0000000 --- a/certs/lib/leap_web_certs.rb +++ /dev/null @@ -1,4 +0,0 @@ -require "leap_web_certs/engine" - -module LeapWebCerts -end diff --git a/certs/lib/leap_web_certs/engine.rb b/certs/lib/leap_web_certs/engine.rb deleted file mode 100644 index 3c8948a..0000000 --- a/certs/lib/leap_web_certs/engine.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "leap_web_core" - -module LeapWebCerts - class Engine < ::Rails::Engine - - end -end diff --git a/certs/lib/tasks/leap_web_certs_tasks.rake b/certs/lib/tasks/leap_web_certs_tasks.rake deleted file mode 100644 index e8fb7ff..0000000 --- a/certs/lib/tasks/leap_web_certs_tasks.rake +++ /dev/null @@ -1,4 +0,0 @@ -# desc "Explaining what the task does" -# task :leap_web_certs do -# # Task goes here -# end diff --git a/certs/script/rails b/certs/script/rails deleted file mode 100755 index 616d3c9..0000000 --- a/certs/script/rails +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby1.8 -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -ENGINE_ROOT = File.expand_path('../..', __FILE__) -ENGINE_PATH = File.expand_path('../../lib/leap_web_certs/engine', __FILE__) - -require 'rails/all' -require 'rails/engine/commands' diff --git a/certs/test/functional/certs_controller_test.rb b/certs/test/functional/certs_controller_test.rb deleted file mode 100644 index 503e74b..0000000 --- a/certs/test/functional/certs_controller_test.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'test_helper' - -class CertsControllerTest < ActionController::TestCase - - test "send limited cert without login" do - with_config allow_limited_certs: true, allow_anonymous_certs: true do - cert = stub :to_s => "limited cert" - ClientCertificate.expects(:new).with(:prefix => APP_CONFIG[:limited_cert_prefix]).returns(cert) - get :show - assert_response :success - assert_equal cert.to_s, @response.body - end - end - - test "send unlimited cert" do - with_config allow_unlimited_certs: true do - login - cert = stub :to_s => "unlimited cert" - ClientCertificate.expects(:new).with(:prefix => APP_CONFIG[:unlimited_cert_prefix]).returns(cert) - get :show - assert_response :success - assert_equal cert.to_s, @response.body - end - end - - test "login required if anonymous certs disabled" do - with_config allow_anonymous_certs: false do - get :show - assert_response :redirect - end - end - - test "send limited cert" do - with_config allow_limited_certs: true, allow_unlimited_certs: false do - login - cert = stub :to_s => "real cert" - ClientCertificate.expects(:new).with(:prefix => APP_CONFIG[:limited_cert_prefix]).returns(cert) - get :show - assert_response :success - assert_equal cert.to_s, @response.body - end - end - -end diff --git a/certs/test/leap_web_certs_test.rb b/certs/test/leap_web_certs_test.rb deleted file mode 100644 index ee2058b..0000000 --- a/certs/test/leap_web_certs_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'test_helper' - -class LeapWebCertsTest < ActiveSupport::TestCase - test "truth" do - assert_kind_of Module, LeapWebCerts - end -end diff --git a/certs/test/test_helper.rb b/certs/test/test_helper.rb deleted file mode 100644 index f6b4eb8..0000000 --- a/certs/test/test_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -ENV["RAILS_ENV"] = "test" -require File.expand_path('../../../test/dummy/config/environment', __FILE__) -require 'rails/test_help' -require 'mocha/setup' - -Rails.backtrace_cleaner.remove_silencers! - -# Load support files -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } - diff --git a/common_dependencies.rb b/common_dependencies.rb deleted file mode 100644 index 2225613..0000000 --- a/common_dependencies.rb +++ /dev/null @@ -1,22 +0,0 @@ -group :test do - # moching and stubing - gem 'mocha', '~> 0.13.0', :require => false - # integration testing - gem 'capybara' - # headless js integration testing - gem 'poltergeist' - # required for save_and_open_page in integration tests - # gem 'launchy' - gem 'fake_braintree' #depends on rspec? - gem 'faker' - gem 'factory_girl_rails' -end - -group :test, :development do - gem 'thin' - gem 'quiet_assets' -end - -group :production do - gem 'SyslogLogger', '~> 2.0' -end diff --git a/config/defaults.yml b/config/defaults.yml index cb18795..1c7e694 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -1,6 +1,6 @@ dev_ca: &dev_ca - client_ca_key: "./certs/test/files/ca.key" - client_ca_cert: "./certs/test/files/ca.crt" + client_ca_key: "./test/files/ca.key" + client_ca_cert: "./test/files/ca.crt" ca_key_password: nil cert_options: &cert_options @@ -49,23 +49,22 @@ common: &common service_levels: &service_levels service_levels: - 0: - name: anonymous - cert_prefix: "LIMITED" - description: "anonymous account, with rate limited VPN" 1: name: free - cert_prefix: "LIMITED" description: "free account, with rate limited VPN" - cost: 0 - quota: 100 + eip_rate_limit: true + storage: 100 + services: + - eip 2: name: premium - cert_prefix: "UNLIMITED" description: "premium account, with unlimited vpn" - cost: + rate: USD: 10 EUR: 10 + services: + - eip + - email default_service_level: 1 development: diff --git a/users/config/initializers/add_controller_methods.rb b/config/initializers/add_controller_methods.rb index f572ecb..f572ecb 100644 --- a/users/config/initializers/add_controller_methods.rb +++ b/config/initializers/add_controller_methods.rb diff --git a/core/config/initializers/couchrest_model.rb b/config/initializers/couchrest_model.rb index ce4f41a..1a3e921 100644 --- a/core/config/initializers/couchrest_model.rb +++ b/config/initializers/couchrest_model.rb @@ -1,3 +1,5 @@ +require 'extensions/couchrest' + CouchRest::Model::Base.configure do |config| config.auto_update_design_doc = false end diff --git a/users/config/initializers/error_constants.rb b/config/initializers/error_constants.rb index d4a0f52..fdd3624 100644 --- a/users/config/initializers/error_constants.rb +++ b/config/initializers/error_constants.rb @@ -1 +1,3 @@ +require 'ruby-srp' + WRONG_PASSWORD = SRP::WrongPassword diff --git a/core/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index e3f8d09..710dacc 100644 --- a/core/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -1,3 +1,5 @@ +require 'extensions/simple_form' + # Use this setup block to configure all options available in SimpleForm. SimpleForm.setup do |config| # Wrappers are used by the form builder to generate a diff --git a/core/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb index c949f5e..c949f5e 100644 --- a/core/config/initializers/simple_form_bootstrap.rb +++ b/config/initializers/simple_form_bootstrap.rb diff --git a/core/config/initializers/validations.rb b/config/initializers/validations.rb index e8acfbe..e8acfbe 100644 --- a/core/config/initializers/validations.rb +++ b/config/initializers/validations.rb diff --git a/users/config/initializers/warden.rb b/config/initializers/warden.rb index 45feb6c..22892b3 100644 --- a/users/config/initializers/warden.rb +++ b/config/initializers/warden.rb @@ -1,3 +1,6 @@ +require "warden/session_serializer" +require "warden/strategies/secure_remote_password" + Rails.configuration.middleware.use RailsWarden::Manager do |config| config.default_strategies :secure_remote_password config.failure_app = SessionsController diff --git a/config/initializers/webfinger.rb b/config/initializers/webfinger.rb new file mode 100644 index 0000000..197062c --- /dev/null +++ b/config/initializers/webfinger.rb @@ -0,0 +1 @@ +require 'webfinger' diff --git a/config/locales/en.yml b/config/locales/en.yml index 96c47ca..cebf075 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,4 +3,44 @@ en: terms_of_service: Terms of Service pricing: Pricing about: About Us - contact: Contact
\ No newline at end of file + contact: Contact + no_such_thing: "No such %{thing}." + thing_was_successfully_created: "%{thing} was successfully created." + create_thing: "Create %{thing}" + + overview: "Overview" + user_control_panel: "user control panel" + + created: "Created" + created_by_on: "Created by %{user} on %{time}" + updated: "Updated" + + none: "None" + unknown: "Unknown" + admin: "Admin" + anonymous: "Anonymous" + save: "Save" + add: "Add" + remove: "Remove" + changes_saved: "Changes saved successfully." + are_you_sure: "Are you sure? This change cannot be undone." + + 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: "Bitmask is also available for %{clients}." + login_info: "Log in to change your account settings, create support tickets, and manage payments." + signup_info: "Get a user account via this website. We recommend registering via the Bitmask application instead unless you are only using Bitmask for Android." + 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)" + linux: "GNU/Linux" + windows: "Windows" + android: "Android" + osx: "Mac OS" + other: "(not available for your OS)" + diff --git a/core/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 0df11fe..5d0c675 100644 --- a/core/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -10,6 +10,9 @@ en: # html: '<abbr title="required">*</abbr>' error_notification: default_message: "Please review the problems below:" + buttons: + cancel: 'Cancel' + loading: 'Loading...' # Labels and hints examples # labels: # defaults: @@ -23,4 +26,11 @@ en: # defaults: # username: 'User name to sign in.' # password: 'No special characters, please.' + helpers: + submit: + user: + create: "Sign up" + update: "Save" + session: + create: "Log in" diff --git a/users/config/locales/en.yml b/config/locales/users.en.yml index e597164..0ca5a73 100644 --- a/users/config/locales/en.yml +++ b/config/locales/users.en.yml @@ -3,13 +3,11 @@ en: logout: "Logout" none: "None" signup: "Sign Up" - signup_message: "Please create an account." cancel: "Cancel" login: "Log In" username: "Username" password: "Password" change_password: "Change Password" - login_message: "Please log in with your account." invalid_user_pass: "Not a valid username/password combination" invalid_ephemeral: "Invalid random key used. This looked like an attempt to hack the site to us. If it wasn't please contact support so we can look into the issue." all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)." @@ -37,6 +35,7 @@ en: enable_description: "This will restore the account to full functionality" deactivate_account: "Deactivate the account %{username}" deactivate_description: "This will temporarily deactivate some account functionality." #todo detail exact functionality. can receive email but not send or renew client certificate? + payment_one_month_warning: "We hope you have been enjoying this service this past month. Please sign up to pay within the next month, by %{date_in_one_month}. Directions for payment are available at INSERT_URL" bye: "Goodbye!" bye_message: "So long and thanks for all the fish." @@ -47,7 +46,7 @@ en: overview_intro: "From this user control panel, you can:" overview_tickets: "Create and check support tickets." overview_email: "Modify email settings." - overview_account: "Delete your account." + overview_account: "Destroy your account." # # rails diff --git a/config/routes.rb b/config/routes.rb index f8bb8fb..745b97d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,4 +16,34 @@ LeapWeb::Application.routes.draw do end get '/provider.json' => 'static_config#provider' + + namespace "api", { module: "v1", + path: "/1/", + defaults: {format: 'json'} } do + resources :sessions, :only => [:new, :create, :update], + :constraints => { :id => /[^\/]+(?=\.json\z)|[^\/]+/ } + delete "logout" => "sessions#destroy", :as => "logout" + resources :users, :only => [:create, :update, :destroy, :index] + resources :messages, :only => [:index, :update] + resource :cert, :only => [:show] + resource :service, :only => [:show] + end + + scope "(:locale)", :locale => MATCH_LOCALE do + get "login" => "sessions#new", :as => "login" + delete "logout" => "sessions#destroy", :as => "logout" + + get "signup" => "users#new", :as => "signup" + resources :users, :except => [:create, :update] do + # resource :email_settings, :only => [:edit, :update] + # resources :email_aliases, :only => [:destroy], :id => /.*/ + post 'deactivate', on: :member + post 'enable', on: :member + end + end + + get "/.well-known/host-meta" => 'webfinger#host_meta' + get "/webfinger" => 'webfinger#search' + get "/key/:login" => 'keys#show' + end diff --git a/core/Gemfile b/core/Gemfile deleted file mode 100644 index b552dc5..0000000 --- a/core/Gemfile +++ /dev/null @@ -1,17 +0,0 @@ -source "https://rubygems.org" - -# Declare your gem's dependencies in leap_web_core.gemspec. -# Bundler will treat runtime dependencies like base dependencies, and -# development dependencies will be added by default to the :development group. -gemspec - -# jquery-rails is used by the dummy application -gem "jquery-rails" - -# Declare any dependencies that are still in development here instead of in -# your gemspec. These might include edge Rails or gems from your path or -# Git. Remember to move these dependencies to your gemspec before releasing -# your gem to rubygems.org. - -# To use debugger -# gem 'ruby-debug' diff --git a/core/Rakefile b/core/Rakefile deleted file mode 100644 index 3c6539c..0000000 --- a/core/Rakefile +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env rake - -require 'rake/packagetask' -require 'rubygems/package_task' - -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' -end -begin - require 'rdoc/task' -rescue LoadError - require 'rdoc/rdoc' - require 'rake/rdoctask' - RDoc::Task = Rake::RDocTask -end - -RDoc::Task.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'LeapWebCore' - rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -spec = eval(File.read('leap_web_core.gemspec')) -Gem::PackageTask.new(spec) do |p| - p.gem_spec = spec -end - -Bundler::GemHelper.install_tasks - -require 'rake/testtask' - -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.libs << 'test' - t.pattern = 'test/**/*_test.rb' - t.verbose = false -end - - -task :default => :test diff --git a/core/Readme.md b/core/Readme.md deleted file mode 100644 index 795c0a4..0000000 --- a/core/Readme.md +++ /dev/null @@ -1,6 +0,0 @@ -Leap Web Core -=== - -[Leap](http://www.leap.se) is the Leap Encryption Access Project and this is the rails app for its web interface. - -This is the its core gem. Currently it only serves to load shared dependencies. diff --git a/core/app/views/common/_download_for_os.html.haml b/core/app/views/common/_download_for_os.html.haml deleted file mode 100644 index 3a11d10..0000000 --- a/core/app/views/common/_download_for_os.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- 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 - = big_icon('download') - .pull-right - = t(:download_client) - %br/ - %small= I18n.t("os.#{os}") - %span.info - %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 - = 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 deleted file mode 100644 index c9ea7a2..0000000 --- a/core/app/views/common/_home_page_buttons.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -- icon_color = :black - -.home-buttons - .row-fluid.first - .span2 - .download.span8 - = render partial: 'common/download_for_os', collection: available_clients + ['other'] - .span2 - - if local_assigns[:divider] - .row-fluid - .span12 - = render local_assigns[:divider] - - if !local_assigns[:on_user_page] - .row-fluid.second - .login.span4 - %span.link= link_to(icon('ok-sign', icon_color) + t(:login), login_path, :class => 'btn') - %span.info= t(:login_info) - .signup.span4 - %span.link= link_to(icon('user', icon_color) + t(:signup), signup_path, :class => 'btn') - %span.info= t(:signup_info) - .help.span4 - %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), new_ticket_path, :class => 'btn') - %span.info= t(:help_info) diff --git a/core/config/initializers/backtrace_silencers.rb b/core/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cd..0000000 --- a/core/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/core/config/initializers/inflections.rb b/core/config/initializers/inflections.rb deleted file mode 100644 index 5d8d9be..0000000 --- a/core/config/initializers/inflections.rb +++ /dev/null @@ -1,15 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format -# (all these examples are active by default): -# ActiveSupport::Inflector.inflections do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end -# -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections do |inflect| -# inflect.acronym 'RESTful' -# end diff --git a/core/config/initializers/mime_types.rb b/core/config/initializers/mime_types.rb deleted file mode 100644 index 72aca7e..0000000 --- a/core/config/initializers/mime_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/core/config/initializers/wrap_parameters.rb b/core/config/initializers/wrap_parameters.rb deleted file mode 100644 index 5fe232e..0000000 --- a/core/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,10 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters :format => [:json] -end - diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml deleted file mode 100644 index bb510d4..0000000 --- a/core/config/locales/en.yml +++ /dev/null @@ -1,41 +0,0 @@ -en: - no_such_thing: "No such %{thing}." - thing_was_successfully_created: "%{thing} was successfully created." - create_thing: "Create %{thing}" - - overview: "Overview" - user_control_panel: "user control panel" - - created: "Created" - created_by_on: "Created by %{user} on %{time}" - updated: "Updated" - - none: "None" - unknown: "Unknown" - admin: "Admin" - anonymous: "Anonymous" - save: "Save" - add: "Add" - remove: "Remove" - changes_saved: "Changes saved successfully." - are_you_sure: "Are you sure? This change cannot be undone." - - 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: "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}." - 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)" - linux: "GNU/Linux" - windows: "Windows" - android: "Android" - osx: "Mac OS" - other: "(not available for your OS)" - diff --git a/core/config/routes.rb b/core/config/routes.rb deleted file mode 100644 index 1daf9a4..0000000 --- a/core/config/routes.rb +++ /dev/null @@ -1,2 +0,0 @@ -Rails.application.routes.draw do -end diff --git a/core/leap_web_core.gemspec b/core/leap_web_core.gemspec deleted file mode 100644 index 7ca4d90..0000000 --- a/core/leap_web_core.gemspec +++ /dev/null @@ -1,25 +0,0 @@ -$:.push File.expand_path("../lib", __FILE__) - -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) - -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "leap_web_core" - s.version = LeapWeb::VERSION - s.authors = ["Azul"] - s.email = ["azul@leap.se"] - s.homepage = "http://www.leap.se" - s.summary = "Web interface to the leap platform - core engine" - s.description = "This web interface provides various administrative tools for the leap platform through plugins. Currently it manages user accounts and certificates." - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"] - s.test_files = Dir["test/**/*"] - - s.add_dependency "rails", "~> 3.2.11" - - s.add_dependency "couchrest", "~> 1.1.3" - s.add_dependency "couchrest_model", "~> 2.0.0" - s.add_dependency "couchrest_session_store", "~> 0.2.4" - - s.add_dependency "json" -end diff --git a/core/lib/extensions/testing.rb b/core/lib/extensions/testing.rb deleted file mode 100644 index aad7fc1..0000000 --- a/core/lib/extensions/testing.rb +++ /dev/null @@ -1,46 +0,0 @@ -module LeapWebCore - module AssertResponses - - # response that works with different TestCases: - # ActionController::TestCase has @response - # ActionDispatch::IntegrationTest has @response - # Rack::Test::Methods defines last_response - def get_response - @response || last_response - end - - def assert_attachement_filename(name) - assert_equal %Q(attachment; filename="#{name}"), - get_response.headers["Content-Disposition"] - end - - def json_response - response = JSON.parse(get_response.body) - response.respond_to?(:with_indifferent_access) ? - response.with_indifferent_access : - response - end - - def assert_json_response(object) - if object.is_a? Hash - object.stringify_keys! if object.respond_to? :stringify_keys! - assert_equal object, json_response - else - assert_equal object.to_json, get_response.body - end - end - - def assert_json_error(object) - object.stringify_keys! if object.respond_to? :stringify_keys! - assert_json_response :errors => object - end - end -end - -class ::ActionController::TestCase - include LeapWebCore::AssertResponses -end - -class ::ActionDispatch::IntegrationTest - include LeapWebCore::AssertResponses -end diff --git a/core/lib/leap_web_core.rb b/core/lib/leap_web_core.rb deleted file mode 100644 index a58d140..0000000 --- a/core/lib/leap_web_core.rb +++ /dev/null @@ -1,14 +0,0 @@ -require "rails" - -require "couchrest" -require "couchrest_model" -require "couchrest_session_store" - -require "json" - -require "extensions/testing" -require "extensions/couchrest" -require "leap_web_core/engine" - -module LeapWebCore -end diff --git a/core/lib/leap_web_core/dependencies.rb b/core/lib/leap_web_core/dependencies.rb deleted file mode 100644 index 877e3d1..0000000 --- a/core/lib/leap_web_core/dependencies.rb +++ /dev/null @@ -1,40 +0,0 @@ -module LeapWebCore - class Dependencies - UI_DEV = { - "haml-rails" => "~> 0.3.4", - "sass-rails" => "~> 3.2.5", - "coffee-rails" => "~> 3.2.2", - "uglifier" => "~> 1.2.7" - } - - UI = { - "haml" => "~> 3.1.7", - "jquery-rails" => nil, - "simple_form" => nil, - "bootswatch-rails", "~> 0.5.0" - } - - def self.require_ui_gems - UI.keys.each {|dep| require dep} - if Rails.env == "development" - # This will be run in the app including plugins that run it. - # However not all development_dependencies might be present. - # So we better only require those that are. - available = Bundler.definition.specs.map(&:name) - gems_to_require = available & UI_DEV.keys - gems_to_require.each {|dep| require dep} - end - end - - def self.add_ui_gems_to_spec(spec) - UI.each do |dep, version| - spec.add_dependency dep, version - end - - UI_DEV.each do |dep, version| - spec.add_development_dependency dep, version - end - end - - end -end diff --git a/core/lib/leap_web_core/engine.rb b/core/lib/leap_web_core/engine.rb deleted file mode 100644 index 940b5e2..0000000 --- a/core/lib/leap_web_core/engine.rb +++ /dev/null @@ -1,9 +0,0 @@ -# thou shall require all your dependencies in an engine. -require "couchrest" -require "couchrest_model" - -module LeapWebCore - class Engine < ::Rails::Engine - - end -end diff --git a/core/lib/leap_web_core/ui_dependencies.rb b/core/lib/leap_web_core/ui_dependencies.rb deleted file mode 100644 index 2daee37..0000000 --- a/core/lib/leap_web_core/ui_dependencies.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "haml" -require "jquery-rails" -require "simple_form" -require "bootswatch-rails" - -if Rails.env == "development" - require "haml-rails" - require "sass-rails" - require "coffee-rails" - require "uglifier" -end diff --git a/core/script/rails b/core/script/rails deleted file mode 100755 index c2ad538..0000000 --- a/core/script/rails +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby1.8 -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -ENGINE_ROOT = File.expand_path('../..', __FILE__) -ENGINE_PATH = File.expand_path('../../lib/leap_web_core/engine', __FILE__) - -require 'rails/all' -require 'rails/engine/commands' diff --git a/billing/Gemfile b/engines/billing/Gemfile index 30e9669..30e9669 100644 --- a/billing/Gemfile +++ b/engines/billing/Gemfile diff --git a/billing/README.md b/engines/billing/README.md index 3ef6153..3ef6153 100644 --- a/billing/README.md +++ b/engines/billing/README.md diff --git a/billing/Rakefile b/engines/billing/Rakefile index 52929c4..52929c4 100644 --- a/billing/Rakefile +++ b/engines/billing/Rakefile diff --git a/billing/app/controllers/billing_admin_controller.rb b/engines/billing/app/controllers/billing_admin_controller.rb index cd6149f..e11d4ee 100644 --- a/billing/app/controllers/billing_admin_controller.rb +++ b/engines/billing/app/controllers/billing_admin_controller.rb @@ -1,5 +1,5 @@ class BillingAdminController < BillingBaseController - before_filter :authorize_admin + before_filter :require_admin def show diff --git a/billing/app/controllers/billing_base_controller.rb b/engines/billing/app/controllers/billing_base_controller.rb index 0453677..0453677 100644 --- a/billing/app/controllers/billing_base_controller.rb +++ b/engines/billing/app/controllers/billing_base_controller.rb diff --git a/billing/app/controllers/credit_card_info_controller.rb b/engines/billing/app/controllers/credit_card_info_controller.rb index 717fa18..fbaa6f1 100644 --- a/billing/app/controllers/credit_card_info_controller.rb +++ b/engines/billing/app/controllers/credit_card_info_controller.rb @@ -1,5 +1,5 @@ class CreditCardInfoController < ApplicationController - before_filter :authorize, :set_user + before_filter :require_login, :set_user def edit @credit_card = Braintree::CreditCard.find(params[:id]) diff --git a/billing/app/controllers/customer_controller.rb b/engines/billing/app/controllers/customer_controller.rb index 901cb34..6cbcb44 100644 --- a/billing/app/controllers/customer_controller.rb +++ b/engines/billing/app/controllers/customer_controller.rb @@ -1,5 +1,5 @@ class CustomerController < BillingBaseController - before_filter :authorize, :fetch_customer + before_filter :require_login, :fetch_customer def show if @customer diff --git a/billing/app/controllers/payments_controller.rb b/engines/billing/app/controllers/payments_controller.rb index 0b5abe7..fce6570 100644 --- a/billing/app/controllers/payments_controller.rb +++ b/engines/billing/app/controllers/payments_controller.rb @@ -1,5 +1,5 @@ class PaymentsController < BillingBaseController - before_filter :authorize, :only => [:index] + before_filter :require_login, :only => [:index] def new fetch_transparent_redirect diff --git a/billing/app/controllers/subscriptions_controller.rb b/engines/billing/app/controllers/subscriptions_controller.rb index 01aaab4..f066b3c 100644 --- a/billing/app/controllers/subscriptions_controller.rb +++ b/engines/billing/app/controllers/subscriptions_controller.rb @@ -1,5 +1,5 @@ class SubscriptionsController < BillingBaseController - before_filter :authorize + before_filter :require_login before_filter :fetch_subscription, :only => [:show, :destroy] before_filter :confirm_cancel_subscription, :only => [:destroy] before_filter :confirm_self_or_admin, :only => [:index] diff --git a/billing/app/helpers/billing_helper.rb b/engines/billing/app/helpers/billing_helper.rb index b9e5e2e..b9e5e2e 100644 --- a/billing/app/helpers/billing_helper.rb +++ b/engines/billing/app/helpers/billing_helper.rb diff --git a/billing/app/helpers/braintree_form_helper.rb b/engines/billing/app/helpers/braintree_form_helper.rb index cb322fa..cb322fa 100644 --- a/billing/app/helpers/braintree_form_helper.rb +++ b/engines/billing/app/helpers/braintree_form_helper.rb diff --git a/billing/app/helpers/braintree_helper.rb b/engines/billing/app/helpers/braintree_helper.rb index 2d18b6c..2d18b6c 100644 --- a/billing/app/helpers/braintree_helper.rb +++ b/engines/billing/app/helpers/braintree_helper.rb diff --git a/billing/app/models/customer.rb b/engines/billing/app/models/customer.rb index 1acc7a5..1acc7a5 100644 --- a/billing/app/models/customer.rb +++ b/engines/billing/app/models/customer.rb diff --git a/billing/app/views/billing_admin/show.html.haml b/engines/billing/app/views/billing_admin/show.html.haml index 0382cf0..0382cf0 100644 --- a/billing/app/views/billing_admin/show.html.haml +++ b/engines/billing/app/views/billing_admin/show.html.haml diff --git a/billing/app/views/credit_card_info/confirm.html.haml b/engines/billing/app/views/credit_card_info/confirm.html.haml index 9dd8176..9dd8176 100644 --- a/billing/app/views/credit_card_info/confirm.html.haml +++ b/engines/billing/app/views/credit_card_info/confirm.html.haml diff --git a/billing/app/views/credit_card_info/edit.html.haml b/engines/billing/app/views/credit_card_info/edit.html.haml index bd86a4c..bd86a4c 100644 --- a/billing/app/views/credit_card_info/edit.html.haml +++ b/engines/billing/app/views/credit_card_info/edit.html.haml diff --git a/billing/app/views/customer/_customer_data.html.haml b/engines/billing/app/views/customer/_customer_data.html.haml index e9df040..e9df040 100644 --- a/billing/app/views/customer/_customer_data.html.haml +++ b/engines/billing/app/views/customer/_customer_data.html.haml diff --git a/billing/app/views/customer/_transaction.html.haml b/engines/billing/app/views/customer/_transaction.html.haml index e69de29..e69de29 100644 --- a/billing/app/views/customer/_transaction.html.haml +++ b/engines/billing/app/views/customer/_transaction.html.haml diff --git a/billing/app/views/customer/confirm.html.haml b/engines/billing/app/views/customer/confirm.html.haml index 877a8ac..877a8ac 100644 --- a/billing/app/views/customer/confirm.html.haml +++ b/engines/billing/app/views/customer/confirm.html.haml diff --git a/billing/app/views/customer/edit.html.haml b/engines/billing/app/views/customer/edit.html.haml index e882d53..e882d53 100644 --- a/billing/app/views/customer/edit.html.haml +++ b/engines/billing/app/views/customer/edit.html.haml diff --git a/billing/app/views/customer/new.html.haml b/engines/billing/app/views/customer/new.html.haml index e1f5ba9..e1f5ba9 100644 --- a/billing/app/views/customer/new.html.haml +++ b/engines/billing/app/views/customer/new.html.haml diff --git a/billing/app/views/customer/show.html.haml b/engines/billing/app/views/customer/show.html.haml index ec1779c..ec1779c 100644 --- a/billing/app/views/customer/show.html.haml +++ b/engines/billing/app/views/customer/show.html.haml diff --git a/billing/app/views/payments/_non_customer_fields.html.haml b/engines/billing/app/views/payments/_non_customer_fields.html.haml index 77cfe95..77cfe95 100644 --- a/billing/app/views/payments/_non_customer_fields.html.haml +++ b/engines/billing/app/views/payments/_non_customer_fields.html.haml diff --git a/billing/app/views/payments/_transaction_details.html.haml b/engines/billing/app/views/payments/_transaction_details.html.haml index 85e4f6a..85e4f6a 100644 --- a/billing/app/views/payments/_transaction_details.html.haml +++ b/engines/billing/app/views/payments/_transaction_details.html.haml diff --git a/billing/app/views/payments/confirm.html.haml b/engines/billing/app/views/payments/confirm.html.haml index 45af3c9..45af3c9 100644 --- a/billing/app/views/payments/confirm.html.haml +++ b/engines/billing/app/views/payments/confirm.html.haml diff --git a/billing/app/views/payments/index.html.haml b/engines/billing/app/views/payments/index.html.haml index 7a89917..7a89917 100644 --- a/billing/app/views/payments/index.html.haml +++ b/engines/billing/app/views/payments/index.html.haml diff --git a/billing/app/views/payments/new.html.haml b/engines/billing/app/views/payments/new.html.haml index e9a8273..e9a8273 100644 --- a/billing/app/views/payments/new.html.haml +++ b/engines/billing/app/views/payments/new.html.haml diff --git a/billing/app/views/subscriptions/_subscription_details.html.haml b/engines/billing/app/views/subscriptions/_subscription_details.html.haml index 6145c95..6145c95 100644 --- a/billing/app/views/subscriptions/_subscription_details.html.haml +++ b/engines/billing/app/views/subscriptions/_subscription_details.html.haml diff --git a/billing/app/views/subscriptions/create.html.haml b/engines/billing/app/views/subscriptions/create.html.haml index 2b6c5e9..2b6c5e9 100644 --- a/billing/app/views/subscriptions/create.html.haml +++ b/engines/billing/app/views/subscriptions/create.html.haml diff --git a/billing/app/views/subscriptions/destroy.html.haml b/engines/billing/app/views/subscriptions/destroy.html.haml index 44b4333..44b4333 100644 --- a/billing/app/views/subscriptions/destroy.html.haml +++ b/engines/billing/app/views/subscriptions/destroy.html.haml diff --git a/billing/app/views/subscriptions/index.html.haml b/engines/billing/app/views/subscriptions/index.html.haml index 3d4e8fd..3d4e8fd 100644 --- a/billing/app/views/subscriptions/index.html.haml +++ b/engines/billing/app/views/subscriptions/index.html.haml diff --git a/billing/app/views/subscriptions/new.html.haml b/engines/billing/app/views/subscriptions/new.html.haml index 4183458..4183458 100644 --- a/billing/app/views/subscriptions/new.html.haml +++ b/engines/billing/app/views/subscriptions/new.html.haml diff --git a/billing/app/views/subscriptions/show.html.haml b/engines/billing/app/views/subscriptions/show.html.haml index 2699db9..2699db9 100644 --- a/billing/app/views/subscriptions/show.html.haml +++ b/engines/billing/app/views/subscriptions/show.html.haml diff --git a/billing/config/initializers/braintree.rb b/engines/billing/config/initializers/braintree.rb index c0c89e2..3d87f4c 100644 --- a/billing/config/initializers/braintree.rb +++ b/engines/billing/config/initializers/braintree.rb @@ -9,14 +9,6 @@ else end # -# we use fake braintree in tests -# -if Rails.env.test? - require 'braintree_test_app' - Rails.application.config.middleware.use BraintreeTestApp -end - -# # You can set these per environment in config/config.yml: # # Environment must be one of: :development, :qa, :sandbox, :production diff --git a/billing/config/locales/en.yml b/engines/billing/config/locales/en.yml index 1300958..1300958 100644 --- a/billing/config/locales/en.yml +++ b/engines/billing/config/locales/en.yml diff --git a/billing/config/routes.rb b/engines/billing/config/routes.rb index 7263dff..7263dff 100644 --- a/billing/config/routes.rb +++ b/engines/billing/config/routes.rb diff --git a/billing/leap_web_billing.gemspec b/engines/billing/leap_web_billing.gemspec index 94d92e0..ff11c98 100644 --- a/billing/leap_web_billing.gemspec +++ b/engines/billing/leap_web_billing.gemspec @@ -1,6 +1,6 @@ $:.push File.expand_path("../lib", __FILE__) -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) +require File.expand_path('../../../lib/leap_web/version.rb', __FILE__) # Describe your gem and declare its dependencies: Gem::Specification.new do |s| @@ -12,10 +12,9 @@ Gem::Specification.new do |s| s.summary = "Billing for LeapWeb" s.description = "Billing System for a Leap provider" - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"] + s.files = Dir["{app,config,lib}/**/*"] + ["Rakefile", "README.md"] s.test_files = Dir["test/**/*"] - s.add_dependency "leap_web_core", LeapWeb::VERSION # s.add_dependency "braintree-rails", "~> 0.4.5" s.add_dependency "braintree" #s.add_dependency "carmen-rails" diff --git a/billing/lib/braintree_test_app.rb b/engines/billing/lib/braintree_test_app.rb index 41c327d..41c327d 100644 --- a/billing/lib/braintree_test_app.rb +++ b/engines/billing/lib/braintree_test_app.rb diff --git a/billing/lib/leap_web_billing.rb b/engines/billing/lib/leap_web_billing.rb index 288d846..288d846 100644 --- a/billing/lib/leap_web_billing.rb +++ b/engines/billing/lib/leap_web_billing.rb diff --git a/billing/lib/leap_web_billing/engine.rb b/engines/billing/lib/leap_web_billing/engine.rb index 6d76add..ab574f2 100644 --- a/billing/lib/leap_web_billing/engine.rb +++ b/engines/billing/lib/leap_web_billing/engine.rb @@ -1,7 +1,4 @@ # thou shall require all your dependencies in an engine. -require "leap_web_core" -require "leap_web_core/ui_dependencies" - #require "braintree-rails" require "braintree" #require "carmen-rails" diff --git a/billing/script/rails b/engines/billing/script/rails index 8bd9c0a..8bd9c0a 100755 --- a/billing/script/rails +++ b/engines/billing/script/rails diff --git a/billing/test/integration/admin_customer_test.rb b/engines/billing/test/broken/admin_customer_test.rb index 58a7557..df92a0d 100644 --- a/billing/test/integration/admin_customer_test.rb +++ b/engines/billing/test/broken/admin_customer_test.rb @@ -1,21 +1,16 @@ require 'test_helper' require 'fake_braintree' -require 'capybara/rails' -class AdminCustomerTest < ActionDispatch::IntegrationTest - include Warden::Test::Helpers - include Capybara::DSL +class AdminCustomerTest < BraintreeIntegrationTest setup do - Warden.test_mode! @admin = User.find_by_login('admin') || FactoryGirl.create(:user, login: 'admin') @user = FactoryGirl.create(:user) end teardown do - Warden.test_reset! - @user.destroy - @admin.destroy + @user.destroy if @user + @admin.destroy if @admin end test "check non customer as admin" do diff --git a/billing/test/integration/customer_creation_test.rb b/engines/billing/test/broken/customer_creation_test.rb index aabd9b6..90319a9 100644 --- a/billing/test/integration/customer_creation_test.rb +++ b/engines/billing/test/broken/customer_creation_test.rb @@ -1,20 +1,15 @@ require 'test_helper' require 'fake_braintree' -require 'capybara/rails' -class CustomerCreationTest < ActionDispatch::IntegrationTest - include Warden::Test::Helpers - include Capybara::DSL +class CustomerCreationTest < BraintreeIntegrationTest setup do - Warden.test_mode! @user = FactoryGirl.create(:user) login_as @user end teardown do @user.destroy - Warden.test_reset! end # Let's test both steps together with capybara diff --git a/billing/test/integration/subscription_test.rb b/engines/billing/test/broken/subscription_test.rb index 1473eb0..cd010bd 100644 --- a/billing/test/integration/subscription_test.rb +++ b/engines/billing/test/broken/subscription_test.rb @@ -1,14 +1,11 @@ require 'test_helper' require 'fake_braintree' -require 'capybara/rails' -class SubscriptionTest < BrowserIntegrationTest - include Warden::Test::Helpers +class SubscriptionTest < BraintreeIntegrationTest include CustomerTestHelper include StubRecordHelper setup do - Warden.test_mode! @admin = User.find_by_login('admin') || FactoryGirl.create(:user, login: 'admin') @customer = stub_customer @braintree_customer = @customer.braintree_customer @@ -19,7 +16,6 @@ class SubscriptionTest < BrowserIntegrationTest end teardown do - Warden.test_reset! @admin.destroy end diff --git a/billing/test/factories.rb b/engines/billing/test/factories.rb index 87543b2..87543b2 100644 --- a/billing/test/factories.rb +++ b/engines/billing/test/factories.rb diff --git a/billing/test/functional/customer_controller_test.rb b/engines/billing/test/functional/customer_controller_test.rb index d943e23..d943e23 100644 --- a/billing/test/functional/customer_controller_test.rb +++ b/engines/billing/test/functional/customer_controller_test.rb diff --git a/billing/test/functional/customers_controller_test.rb b/engines/billing/test/functional/customers_controller_test.rb index 46c33c9..46c33c9 100644 --- a/billing/test/functional/customers_controller_test.rb +++ b/engines/billing/test/functional/customers_controller_test.rb diff --git a/billing/test/functional/payments_controller_test.rb b/engines/billing/test/functional/payments_controller_test.rb index 90b7582..90b7582 100644 --- a/billing/test/functional/payments_controller_test.rb +++ b/engines/billing/test/functional/payments_controller_test.rb diff --git a/billing/test/functional/subscriptions_controller_test.rb b/engines/billing/test/functional/subscriptions_controller_test.rb index a6a1057..a6a1057 100644 --- a/billing/test/functional/subscriptions_controller_test.rb +++ b/engines/billing/test/functional/subscriptions_controller_test.rb diff --git a/engines/billing/test/support/braintree_integration_test.rb b/engines/billing/test/support/braintree_integration_test.rb new file mode 100644 index 0000000..976c5a2 --- /dev/null +++ b/engines/billing/test/support/braintree_integration_test.rb @@ -0,0 +1,18 @@ +require 'capybara/rails' +# require 'fake_braintree' - messes up other integration tests +require 'braintree_test_app' + +class BraintreeIntegrationTest < BrowserIntegrationTest + include Warden::Test::Helpers + + setup do + Warden.test_mode! + Rails.application.config.middleware.use BraintreeTestApp + end + + teardown do + Warden.test_reset! + Rails.application.config.middleware.delete "BraintreeTestApp" + end + +end diff --git a/billing/test/support/customer_test_helper.rb b/engines/billing/test/support/customer_test_helper.rb index adac00a..adac00a 100644 --- a/billing/test/support/customer_test_helper.rb +++ b/engines/billing/test/support/customer_test_helper.rb diff --git a/help/test/test_helper.rb b/engines/billing/test/test_helper.rb index 3381f44..7ad3869 100644 --- a/help/test/test_helper.rb +++ b/engines/billing/test/test_helper.rb @@ -1,7 +1,7 @@ # Configure Rails Environment ENV["RAILS_ENV"] = "test" -require File.expand_path('../../../test/dummy/config/environment', __FILE__) +require File.expand_path("../../../../dummy/config/environment.rb", __FILE__) require "rails/test_help" Rails.backtrace_cleaner.remove_silencers! diff --git a/billing/test/unit/customer_test.rb b/engines/billing/test/unit/customer_test.rb index 6156f87..6156f87 100644 --- a/billing/test/unit/customer_test.rb +++ b/engines/billing/test/unit/customer_test.rb diff --git a/billing/test/unit/customer_with_payment_info_test.rb b/engines/billing/test/unit/customer_with_payment_info_test.rb index 0589a59..0589a59 100644 --- a/billing/test/unit/customer_with_payment_info_test.rb +++ b/engines/billing/test/unit/customer_with_payment_info_test.rb diff --git a/help/Gemfile b/engines/support/Gemfile index ad7d29b..ad7d29b 100644 --- a/help/Gemfile +++ b/engines/support/Gemfile diff --git a/help/README.md b/engines/support/README.md index c9573e6..c9573e6 100644 --- a/help/README.md +++ b/engines/support/README.md diff --git a/help/Rakefile b/engines/support/Rakefile index 0e73163..0e73163 100644 --- a/help/Rakefile +++ b/engines/support/Rakefile diff --git a/help/app/assets/javascripts/tickets.js b/engines/support/app/assets/javascripts/tickets.js index 18537aa..18537aa 100644 --- a/help/app/assets/javascripts/tickets.js +++ b/engines/support/app/assets/javascripts/tickets.js diff --git a/help/app/controllers/tickets_controller.rb b/engines/support/app/controllers/tickets_controller.rb index c193ff4..99357ab 100644 --- a/help/app/controllers/tickets_controller.rb +++ b/engines/support/app/controllers/tickets_controller.rb @@ -4,31 +4,30 @@ class TicketsController < ApplicationController respond_to :html, :json #has_scope :open, :type => boolean - before_filter :authorize, :only => [:index] - before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method + before_filter :require_login, :only => [:index] + before_filter :fetch_ticket, :only => [:show, :update, :destroy] + before_filter :require_ticket_access, :only => [:show, :update, :destroy] before_filter :fetch_user before_filter :set_title def new @ticket = Ticket.new + @ticket.created_by = current_user.id @ticket.comments.build end def create @ticket = Ticket.new(params[:ticket]) - @ticket.comments.last.posted_by = (logged_in? ? current_user.id : nil) #protecting posted_by isn't working, so this should protect it. + #protecting posted_by isn't working, so this should protect it: + @ticket.comments.last.posted_by = current_user.id @ticket.comments.last.private = false unless admin? - @ticket.created_by = current_user.id if logged_in? - @ticket.email = current_user.email_address if logged_in? and current_user.email_address - + @ticket.created_by = current_user.id if @ticket.save flash[:notice] = t(:thing_was_successfully_created, :thing => t(:ticket)) - end - - # cannot set this until ticket has been saved, as @ticket.id will not be set - if !logged_in? and flash[:notice] - flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) + if !logged_in? + flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) + end end respond_with(@ticket, :location => auto_ticket_path(@ticket)) end @@ -42,23 +41,23 @@ class TicketsController < ApplicationController end def update - if params[:commit] == 'close' + if params[:button] == 'close' @ticket.is_open = false @ticket.save redirect_to_tickets - elsif params[:commit] == 'open' + elsif params[:button] == 'open' @ticket.is_open = true @ticket.save redirect_to auto_ticket_path(@ticket) else @ticket.attributes = cleanup_ticket_params(params[:ticket]) - if params[:commit] == 'reply_and_close' + if params[:button] == 'reply_and_close' @ticket.close end if @ticket.comments_changed? - @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) + @ticket.comments.last.posted_by = current_user.id @ticket.comments.last.private = false unless admin? end @@ -97,7 +96,7 @@ class TicketsController < ApplicationController # def redirect_to_tickets if logged_in? - if params[:commit] == t(:reply_and_close) + if params[:button] == t(:reply_and_close) redirect_to auto_tickets_path else redirect_to auto_ticket_path(@ticket) @@ -120,19 +119,28 @@ class TicketsController < ApplicationController return ticket end - def ticket_access? - @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by)) - end - def fetch_ticket @ticket = Ticket.find(params[:id]) - if !@ticket and admin? - redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => 'ticket') - return + if !@ticket + if admin? + redirect_to auto_tickets_path, + alert: t(:no_such_thing, thing: 'ticket') + else + access_denied + end end + end + + def require_ticket_access access_denied unless ticket_access? end + def ticket_access? + admin? or + @ticket.created_by.blank? or + current_user.id == @ticket.created_by + end + def fetch_user if params[:user_id] @user = User.find(params[:user_id]) diff --git a/help/app/designs/ticket/by_includes_post_by.js b/engines/support/app/designs/ticket/by_includes_post_by.js index 2eeac89..2eeac89 100644 --- a/help/app/designs/ticket/by_includes_post_by.js +++ b/engines/support/app/designs/ticket/by_includes_post_by.js diff --git a/help/app/designs/ticket/by_includes_post_by_and_created_at.js b/engines/support/app/designs/ticket/by_includes_post_by_and_created_at.js index 72169b0..72169b0 100644 --- a/help/app/designs/ticket/by_includes_post_by_and_created_at.js +++ b/engines/support/app/designs/ticket/by_includes_post_by_and_created_at.js diff --git a/help/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js b/engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js index 33dfe0b..33dfe0b 100644 --- a/help/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js +++ b/engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_created_at.js diff --git a/help/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js b/engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js index 3bd2a74..3bd2a74 100644 --- a/help/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js +++ b/engines/support/app/designs/ticket/by_includes_post_by_and_is_open_and_updated_at.js diff --git a/help/app/designs/ticket/by_includes_post_by_and_updated_at.js b/engines/support/app/designs/ticket/by_includes_post_by_and_updated_at.js index 2b4304f..2b4304f 100644 --- a/help/app/designs/ticket/by_includes_post_by_and_updated_at.js +++ b/engines/support/app/designs/ticket/by_includes_post_by_and_updated_at.js diff --git a/help/app/helpers/auto_tickets_path_helper.rb b/engines/support/app/helpers/auto_tickets_path_helper.rb index 93f3cb9..5638222 100644 --- a/help/app/helpers/auto_tickets_path_helper.rb +++ b/engines/support/app/helpers/auto_tickets_path_helper.rb @@ -23,6 +23,7 @@ module AutoTicketsPathHelper end def auto_ticket_path(ticket, options={}) + return unless ticket.persisted? options = ticket_view_options.merge options if @user user_ticket_path(@user, ticket, options) @@ -50,4 +51,4 @@ module AutoTicketsPathHelper hsh end -end
\ No newline at end of file +end diff --git a/help/app/helpers/tickets_helper.rb b/engines/support/app/helpers/tickets_helper.rb index 7af50d6..7af50d6 100644 --- a/help/app/helpers/tickets_helper.rb +++ b/engines/support/app/helpers/tickets_helper.rb diff --git a/help/app/models/account_extension/tickets.rb b/engines/support/app/models/account_extension/tickets.rb index f898b56..f898b56 100644 --- a/help/app/models/account_extension/tickets.rb +++ b/engines/support/app/models/account_extension/tickets.rb diff --git a/help/app/models/ticket.rb b/engines/support/app/models/ticket.rb index cd22758..bf5df53 100644 --- a/help/app/models/ticket.rb +++ b/engines/support/app/models/ticket.rb @@ -19,8 +19,6 @@ class Ticket < CouchRest::Model::Base timestamps! - before_validation :set_email, :set_regarding_user, :on => :create - design do view :by_updated_at view :by_created_at @@ -34,7 +32,12 @@ class Ticket < CouchRest::Model::Base end validates :subject, :presence => true - validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ + + # email can have three states: + # * nil - prefilled with created_by's email + # * "" - cleared + # * valid email address + validates :email, :allow_blank => true, :format => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/ def self.search(options = {}) @selection = TicketSelection.new(options) @@ -48,15 +51,15 @@ class Ticket < CouchRest::Model::Base end def is_creator_validated? - !!created_by + created_by_user.is_a? User end - def set_email - self.email = nil if self.email == "" + def email + read_attribute(:email) || created_by_user.email end - def set_regarding_user - self.regarding_user = nil if self.regarding_user == "" + def regarding_user + read_attribute(:regarding_user) || created_by_user.login end def close @@ -95,7 +98,11 @@ class Ticket < CouchRest::Model::Base end def created_by_user - User.find(self.created_by) + if self.created_by + User.find(self.created_by) || AnonymousUser.new + else + AnonymousUser.new + end end def regarding_user_actual_user diff --git a/help/app/models/ticket_comment.rb b/engines/support/app/models/ticket_comment.rb index bed5237..bed5237 100644 --- a/help/app/models/ticket_comment.rb +++ b/engines/support/app/models/ticket_comment.rb diff --git a/help/app/models/ticket_selection.rb b/engines/support/app/models/ticket_selection.rb index 74d5b78..74d5b78 100644 --- a/help/app/models/ticket_selection.rb +++ b/engines/support/app/models/ticket_selection.rb diff --git a/help/app/views/tickets/_comment.html.haml b/engines/support/app/views/tickets/_comment.html.haml index 778ca13..778ca13 100644 --- a/help/app/views/tickets/_comment.html.haml +++ b/engines/support/app/views/tickets/_comment.html.haml diff --git a/help/app/views/tickets/_edit_form.html.haml b/engines/support/app/views/tickets/_edit_form.html.haml index 714f8ff..b8da779 100644 --- a/help/app/views/tickets/_edit_form.html.haml +++ b/engines/support/app/views/tickets/_edit_form.html.haml @@ -1,6 +1,6 @@ :ruby # created by user link - if @ticket.created_by_user + if @ticket.is_creator_validated? created_by = link_to @ticket.created_by_user.login, @ticket.created_by_user else created_by = t(:anonymous) @@ -17,14 +17,20 @@ regarding_user_link = '' end -= form_for @ticket do |f| += simple_form_for @ticket do |f| = hidden_ticket_fields %p.first - if @ticket.is_open? - %span.label.label-info= t(:open) + %span.label.label-info + %b{style: 'padding:10px'}= t(:open) + = f.button :loading, t(:close), value: 'close', class: 'btn-mini' - else - %span.label.label-success= t(:closed) + %span.label.label-success + %b{style: 'padding:10px'}= t(:closed) + = f.button :loading, t(:open), value: 'open', class: 'btn-mini' %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe += simple_form_for @ticket do |f| + = hidden_ticket_fields %div= t(:subject) = f.text_field :subject, :class => 'large full-width' .row-fluid @@ -39,10 +45,6 @@ = t(:regarding_account) = regarding_user_link = f.text_field :regarding_user - = f.button t(:save), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'save' - - if @ticket.is_open? - = f.button t(:close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'close' - - else - = f.button t(:open), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'open' + = f.button :loading, t(:save), :value => 'save' - if admin? = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn' diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/engines/support/app/views/tickets/_new_comment_form.html.haml index 8418e01..40c737f 100644 --- a/help/app/views/tickets/_new_comment_form.html.haml +++ b/engines/support/app/views/tickets/_new_comment_form.html.haml @@ -7,7 +7,7 @@ = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5} - if admin? = c.input :private, :as => :boolean, :label => false, :inline_label => true - = f.button :button, t(:post_reply), :name => 'commit', :class => 'btn-primary', :type => 'submit', :value => 'post_reply' + = f.button :loading, t(:post_reply), class: 'btn-primary', value: 'post_reply' - if logged_in? && @ticket.is_open - = f.button :button, t(:reply_and_close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'reply_and_close' + = f.button :loading, t(:reply_and_close), value: 'reply_and_close' = link_to t(:cancel), auto_tickets_path, :class => :btn diff --git a/help/app/views/tickets/_tabs.html.haml b/engines/support/app/views/tickets/_tabs.html.haml index b7b5d3a..445a909 100644 --- a/help/app/views/tickets/_tabs.html.haml +++ b/engines/support/app/views/tickets/_tabs.html.haml @@ -1,7 +1,7 @@ -# -# SORT ORDER TABS -# -- unless action?(:new) +- unless action?(:new) or action?(:create) %ul.nav.nav-pills.pull-right.slim %li{:class=> ("active" if search_order.start_with? 'created_at')} = link_to_order('created') @@ -19,5 +19,5 @@ = link_to_status 'closed' %li{:class => ("active" if search_status == 'all')} = link_to_status 'all' - %li{:class => ("active" if action?(:new))} + %li{:class => ("active" if action?(:new) || action?(:create))} = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path diff --git a/help/app/views/tickets/_ticket.html.haml b/engines/support/app/views/tickets/_ticket.html.haml index 5bc33c8..5bc33c8 100644 --- a/help/app/views/tickets/_ticket.html.haml +++ b/engines/support/app/views/tickets/_ticket.html.haml diff --git a/help/app/views/tickets/index.html.haml b/engines/support/app/views/tickets/index.html.haml index c02a326..a4df6e3 100644 --- a/help/app/views/tickets/index.html.haml +++ b/engines/support/app/views/tickets/index.html.haml @@ -1,4 +1,4 @@ -- @show_navigation = !params[:user_id].nil? +- @show_navigation = params[:user_id].present? = render 'tickets/tabs' diff --git a/engines/support/app/views/tickets/new.html.haml b/engines/support/app/views/tickets/new.html.haml new file mode 100644 index 0000000..3de5fe9 --- /dev/null +++ b/engines/support/app/views/tickets/new.html.haml @@ -0,0 +1,17 @@ +- @show_navigation = params[:user_id].present? + += render 'tickets/tabs' + +- user = @user if admin? +- user ||= current_user + += simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| + = hidden_ticket_fields + = f.input :subject + = f.input :email + = f.input :regarding_user + = f.simple_fields_for :comments, @comment do |c| + = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5} + - if admin? + = c.input :private, :as => :boolean, :label => false, :inline_label => true + = f.button :wrapped, cancel: (logged_in? ? auto_tickets_path : home_path) diff --git a/help/app/views/tickets/show.html.haml b/engines/support/app/views/tickets/show.html.haml index bfdb773..4f3c127 100644 --- a/help/app/views/tickets/show.html.haml +++ b/engines/support/app/views/tickets/show.html.haml @@ -1,4 +1,4 @@ -- @show_navigation = !params[:user_id].nil? +- @show_navigation = params[:user_id].present? .ticket = render 'tickets/edit_form' @@ -7,6 +7,6 @@ = render :partial => 'tickets/comment', :collection => @ticket.comments %tr %td.user - = logged_in? ? current_user.login : t(:anonymous) + = current_user.login || t(:anonymous) %td.comment - = render 'tickets/new_comment_form'
\ No newline at end of file + = render 'tickets/new_comment_form' diff --git a/help/config/initializers/account_lifecycle.rb b/engines/support/config/initializers/account_lifecycle.rb index d9f04c1..d9f04c1 100644 --- a/help/config/initializers/account_lifecycle.rb +++ b/engines/support/config/initializers/account_lifecycle.rb diff --git a/help/config/locales/en.yml b/engines/support/config/locales/en.yml index 342adea..342adea 100644 --- a/help/config/locales/en.yml +++ b/engines/support/config/locales/en.yml diff --git a/help/config/routes.rb b/engines/support/config/routes.rb index 23e0c11..23e0c11 100644 --- a/help/config/routes.rb +++ b/engines/support/config/routes.rb diff --git a/help/leap_web_help.gemspec b/engines/support/leap_web_help.gemspec index 4914694..7b668d5 100644 --- a/help/leap_web_help.gemspec +++ b/engines/support/leap_web_help.gemspec @@ -1,6 +1,6 @@ -$:.push File.expand_path("../lib", __FILE__) +$:.push File.expand_path("../../lib", __FILE__) -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) +require File.expand_path('../../../lib/leap_web/version.rb', __FILE__) # Describe your gem and declare its dependencies: Gem::Specification.new do |s| @@ -12,8 +12,7 @@ Gem::Specification.new do |s| s.summary = "Help Desk for LeapWeb" s.description = "Managing Tickets for a Leap provider" - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"] + s.files = Dir["{app,config,lib}/**/*"] + ["Rakefile", "README.md"] s.test_files = Dir["test/**/*"] - s.add_dependency "leap_web_core", LeapWeb::VERSION end diff --git a/help/lib/leap_web_help.rb b/engines/support/lib/leap_web_help.rb index f5b04aa..f5b04aa 100644 --- a/help/lib/leap_web_help.rb +++ b/engines/support/lib/leap_web_help.rb diff --git a/engines/support/lib/leap_web_help/engine.rb b/engines/support/lib/leap_web_help/engine.rb new file mode 100644 index 0000000..dfa763f --- /dev/null +++ b/engines/support/lib/leap_web_help/engine.rb @@ -0,0 +1,4 @@ +module LeapWebHelp + class Engine < ::Rails::Engine + end +end diff --git a/help/lib/tasks/leap_web_help_tasks.rake b/engines/support/lib/tasks/leap_web_help_tasks.rake index 1f38982..1f38982 100644 --- a/help/lib/tasks/leap_web_help_tasks.rake +++ b/engines/support/lib/tasks/leap_web_help_tasks.rake diff --git a/help/script/rails b/engines/support/script/rails index 5676ab9..5676ab9 100755 --- a/help/script/rails +++ b/engines/support/script/rails diff --git a/help/test/factories.rb b/engines/support/test/factories.rb index be04f15..be04f15 100644 --- a/help/test/factories.rb +++ b/engines/support/test/factories.rb diff --git a/help/test/functional/tickets_controller_test.rb b/engines/support/test/functional/tickets_controller_test.rb index 2530ba1..fc4a6f8 100644 --- a/help/test/functional/tickets_controller_test.rb +++ b/engines/support/test/functional/tickets_controller_test.rb @@ -2,6 +2,11 @@ require 'test_helper' class TicketsControllerTest < ActionController::TestCase + teardown do + # destroy all tickets that were created during the test + Ticket.all.each{|t| t.destroy} + end + test "should get index if logged in" do login get :index @@ -64,13 +69,23 @@ class TicketsControllerTest < ActionController::TestCase assert_equal 1, assigns(:ticket).comments.count assert_nil assigns(:ticket).comments.first.posted_by - assigns(:ticket).destroy # destroys without checking permission. is that okay? end + test "handle invalid ticket" do + params = {:subject => "unauth ticket test subject", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}, :email => 'a'} + + assert_no_difference('Ticket.count') do + post :create, :ticket => params + end + + assert_template :new + assert_equal params[:subject], assigns(:ticket).subject + end + test "should create authenticated ticket" do - params = {:subject => "auth ticket test subject", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}} + params = {:subject => "auth ticket test subject",:email => "", :comments_attributes => {"0" => {"body" =>"body of test ticket"}}} login @@ -82,12 +97,11 @@ class TicketsControllerTest < ActionController::TestCase assert_not_nil assigns(:ticket).created_by assert_equal assigns(:ticket).created_by, @current_user.id - assert_equal assigns(:ticket).email, @current_user.email_address + assert_equal "", assigns(:ticket).email assert_equal 1, assigns(:ticket).comments.count assert_not_nil assigns(:ticket).comments.first.posted_by assert_equal assigns(:ticket).comments.first.posted_by, @current_user.id - assigns(:ticket).destroy end test "add comment to unauthenticated ticket" do @@ -101,7 +115,6 @@ class TicketsControllerTest < ActionController::TestCase assert_equal ticket, assigns(:ticket) # still same ticket, with different comments assert_not_equal ticket.comments, assigns(:ticket).comments # ticket == assigns(:ticket), but they have different comments (which we want) - assigns(:ticket).destroy end @@ -118,7 +131,6 @@ class TicketsControllerTest < ActionController::TestCase assert_not_equal ticket.comments, assigns(:ticket).comments assert_not_nil assigns(:ticket).comments.last.posted_by assert_equal assigns(:ticket).comments.last.posted_by, @current_user.id - assigns(:ticket).destroy end @@ -153,12 +165,9 @@ class TicketsControllerTest < ActionController::TestCase assert_not_equal ticket.comments, assigns(:ticket).comments assert_not_nil assigns(:ticket).comments.last.posted_by assert_equal assigns(:ticket).comments.last.posted_by, @current_user.id - - assigns(:ticket).destroy end test "tickets by admin" do - begin other_user = find_record :user ticket = FactoryGirl.create :ticket, :created_by => other_user.id @@ -173,9 +182,6 @@ class TicketsControllerTest < ActionController::TestCase assigns(:tickets).first.save get :index, {:admin_status => "all", :open_status => "open"} end - ensure - ticket.reload.destroy if ticket - end end @@ -188,7 +194,6 @@ class TicketsControllerTest < ActionController::TestCase assert assigns(:all_tickets).include?(testticket) get :index, {:user_id => user.id, :open_status => "open"} assert !assigns(:all_tickets).include?(testticket) - testticket.destroy end test "commenting on a ticket adds to tickets that are mine" do @@ -204,8 +209,6 @@ class TicketsControllerTest < ActionController::TestCase assert assigns(:all_tickets).include?(assigns(:ticket)) assert_not_nil assigns(:ticket).comments.last.posted_by assert_equal assigns(:ticket).comments.last.posted_by, @current_user.id - - assigns(:ticket).destroy end test "admin ticket ordering" do @@ -228,7 +231,6 @@ class TicketsControllerTest < ActionController::TestCase assert_not_equal first_tick, assigns(:all_tickets).first assert_not_equal last_tick, assigns(:all_tickets).last - tickets.each {|ticket| ticket.destroy} end test "tickets for regular user" do @@ -275,7 +277,6 @@ class TicketsControllerTest < ActionController::TestCase assert assigns(:all_tickets).include?(other_ticket) assert_equal assigns(:all_tickets).count, number_closed_tickets + number_open_tickets - assigns(:all_tickets).each {|t| t.destroy} end diff --git a/engines/support/test/integration/create_ticket_test.rb b/engines/support/test/integration/create_ticket_test.rb new file mode 100644 index 0000000..0f8453c --- /dev/null +++ b/engines/support/test/integration/create_ticket_test.rb @@ -0,0 +1,64 @@ +require 'test_helper' + +class CreateTicketTest < BrowserIntegrationTest + + test "can submit ticket anonymously" do + visit '/' + click_on 'Get Help' + fill_in 'Subject', with: 'test ticket' + fill_in 'Description', with: 'description of the problem goes here' + click_on 'Create Ticket' + assert page.has_content?("Ticket was successfully created.") + assert page.has_content?("You can later access this ticket at the URL") + assert page.has_content?(current_url) + assert ticket = Ticket.last + ticket.destroy + end + + test "get help when creating ticket with invalid email" do + visit '/' + click_on 'Get Help' + fill_in 'Subject', with: 'test ticket' + fill_in 'Email', with: 'invalid data' + fill_in 'Regarding user', with: 'some user' + fill_in 'Description', with: 'description of the problem goes here' + click_on 'Create Ticket' + assert page.has_content?("is invalid") + assert_equal 'invalid data', find_field('Email').value + assert_equal 'some user', find_field('Regarding user').value + end + + test "prefills fields" do + login FactoryGirl.create(:premium_user) + visit '/' + click_on "Support Tickets" + click_on "New Ticket" + email = "#{@user.login}@#{APP_CONFIG[:domain]}" + assert_equal email, find_field('Email').value + assert_equal @user.login, find_field('Regarding user').value + end + + test "no prefill of email without email service" do + login + visit '/' + click_on "Support Tickets" + click_on "New Ticket" + assert_equal "", find_field('Email').value + assert_equal @user.login, find_field('Regarding user').value + end + + test "cleared email field should remain clear" do + login FactoryGirl.create(:premium_user) + visit '/' + click_on "Support Tickets" + click_on "New Ticket" + fill_in 'Subject', with: 'test ticket' + fill_in 'Email', with: '' + fill_in 'Description', with: 'description of the problem goes here' + click_on 'Create Ticket' + ticket = Ticket.last + assert_equal "", ticket.email + ticket.destroy + end + +end diff --git a/certs/test/integration/navigation_test.rb b/engines/support/test/integration/navigation_test.rb index eec8c0e..eec8c0e 100644 --- a/certs/test/integration/navigation_test.rb +++ b/engines/support/test/integration/navigation_test.rb diff --git a/help/test/leap_web_help_test.rb b/engines/support/test/leap_web_help_test.rb index d74c087..d74c087 100644 --- a/help/test/leap_web_help_test.rb +++ b/engines/support/test/leap_web_help_test.rb diff --git a/billing/test/test_helper.rb b/engines/support/test/test_helper.rb index 1e26a31..fff9173 100644 --- a/billing/test/test_helper.rb +++ b/engines/support/test/test_helper.rb @@ -1,7 +1,7 @@ # Configure Rails Environment ENV["RAILS_ENV"] = "test" -require File.expand_path("../dummy/config/environment.rb", __FILE__) +require File.expand_path('../../../../test/dummy/config/environment', __FILE__) require "rails/test_help" Rails.backtrace_cleaner.remove_silencers! diff --git a/help/test/unit/account_extension_test.rb b/engines/support/test/unit/account_extension_test.rb index aba162c..aba162c 100644 --- a/help/test/unit/account_extension_test.rb +++ b/engines/support/test/unit/account_extension_test.rb diff --git a/help/test/unit/ticket_comment_test.rb b/engines/support/test/unit/ticket_comment_test.rb index fe8cc95..fe8cc95 100644 --- a/help/test/unit/ticket_comment_test.rb +++ b/engines/support/test/unit/ticket_comment_test.rb diff --git a/help/test/unit/ticket_test.rb b/engines/support/test/unit/ticket_test.rb index f5e6ea7..678d8dc 100644 --- a/help/test/unit/ticket_test.rb +++ b/engines/support/test/unit/ticket_test.rb @@ -27,10 +27,10 @@ class TicketTest < ActiveSupport::TestCase end test "creation validated" do + user = FactoryGirl.create :user @sample = Ticket.new assert !@sample.is_creator_validated? - #p current_user - @sample.created_by = 22 #current_user + @sample.created_by = user.id assert @sample.is_creator_validated? end diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml deleted file mode 100644 index 8f217a5..0000000 --- a/help/app/views/tickets/new.html.haml +++ /dev/null @@ -1,30 +0,0 @@ -- @show_navigation = !params[:user_id].nil? - -= render 'tickets/tabs' - -- if admin? && @user - - email = @user.email_address - - regarding = @user.login -- elsif logged_in? - - email = current_user.email_address - - regarding = current_user.login - -= simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f| - = hidden_ticket_fields - = f.input :subject - - if logged_in? - = f.input :email, input_html: {value: email} - = f.input :regarding_user, input_html: {value: regarding} - - else - = f.input :email - = f.input :regarding_user - = f.simple_fields_for :comments, @comment do |c| - = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5} - - if admin? - = c.input :private, :as => :boolean, :label => false, :inline_label => true - .form-actions - = f.button :submit, :class => 'btn-primary', :value => t(:create_thing, :thing => t(:ticket)) - - if logged_in? - = link_to t(:cancel), auto_tickets_path, :class => :btn - - else - = link_to t(:cancel), home_path, :class => 'btn'
\ No newline at end of file diff --git a/help/lib/leap_web_help/engine.rb b/help/lib/leap_web_help/engine.rb deleted file mode 100644 index 4146dfc..0000000 --- a/help/lib/leap_web_help/engine.rb +++ /dev/null @@ -1,8 +0,0 @@ -# thou shall require all your dependencies in an engine. -require "leap_web_core" -require "leap_web_core/ui_dependencies" - -module LeapWebHelp - class Engine < ::Rails::Engine - end -end diff --git a/leap_web.gemspec b/leap_web.gemspec index 44a30e0..125c930 100644 --- a/leap_web.gemspec +++ b/leap_web.gemspec @@ -19,7 +19,4 @@ Gem::Specification.new do |s| s.email = 'azul@leap.se' s.homepage = 'http://leap.se' - # s.add_dependency 'leap_web_core' - s.add_dependency 'leap_web_certs', LeapWeb::VERSION - s.add_dependency 'leap_web_users', LeapWeb::VERSION end diff --git a/core/lib/extensions/couchrest.rb b/lib/extensions/couchrest.rb index a9a195e..95f5d92 100644 --- a/core/lib/extensions/couchrest.rb +++ b/lib/extensions/couchrest.rb @@ -45,7 +45,7 @@ module CouchRest def self.load_all_models_with_engines self.load_all_models_without_engines return unless defined?(Rails) - Dir[Rails.root + '*/app/models/**/*.rb'].each do |path| + Dir[Rails.root + 'engines/*/app/models/**/*.rb'].each do |path| require path end end diff --git a/lib/extensions/simple_form.rb b/lib/extensions/simple_form.rb new file mode 100644 index 0000000..f28e18f --- /dev/null +++ b/lib/extensions/simple_form.rb @@ -0,0 +1,28 @@ +module WrappedButton + def wrapped_button(*args, &block) + template.content_tag :div, :class => "form-actions" do + options = args.extract_options! + options[:class] = ['btn-primary', options[:class]].compact + args.unshift :loading + args << options + if cancel = options.delete(:cancel) + cancel_link = template.link_to I18n.t('simple_form.buttons.cancel'), + cancel, class: :btn + button(*args, &block) + ' ' + cancel_link + else + button(*args, &block) + end + end + end +end +SimpleForm::FormBuilder.send :include, WrappedButton + +module LoadingButton + def loading_button(*args, &block) + options = args.extract_options! + options[:"data-loading-text"] = I18n.t('simple_form.buttons.loading') + args << options + button_button(*args, &block) + end +end +SimpleForm::FormBuilder.send :include, LoadingButton diff --git a/lib/leap_web.rb b/lib/leap_web.rb deleted file mode 100644 index 9495fc6..0000000 --- a/lib/leap_web.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'leap_web_core' -require 'leap_web_certs' -require 'leap_web_users' -# do we want billing and help here? diff --git a/core/lib/tasks/leap_web_core_tasks.rake b/lib/tasks/leap_web_core_tasks.rake index ec6abac..ec6abac 100644 --- a/core/lib/tasks/leap_web_core_tasks.rake +++ b/lib/tasks/leap_web_core_tasks.rake diff --git a/lib/tasks/leap_web_users_tasks.rake b/lib/tasks/leap_web_users_tasks.rake new file mode 100644 index 0000000..62bcbe9 --- /dev/null +++ b/lib/tasks/leap_web_users_tasks.rake @@ -0,0 +1,10 @@ +# desc "Explaining what the task does" +# task :leap_web_users do +# # Task goes here +# end + +# recommended that for our setup, we should have this triggered from a cron job in puppet rather than using whenever gem +desc "Send one month warning messages" +task :leap_web_users do + User.send_one_month_warnings +end diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake index 3c87b45..d96b625 100644 --- a/lib/tasks/test.rake +++ b/lib/tasks/test.rake @@ -1,18 +1,11 @@ namespace :test do - Rails::SubTestTask.new(:units => "test:prepare") do |t| - t.libs << "test" - t.pattern = '*/test/unit/**/*_test.rb' - end - - Rails::SubTestTask.new(:functionals => "test:prepare") do |t| - t.libs << "test" - t.pattern = '*/test/functional/**/*_test.rb' - end - - Rails::SubTestTask.new(:integration => "test:prepare") do |t| - t.libs << "test" - t.pattern = '*/test/integration/**/*_test.rb' + [:units, :functionals, :integration].each do |type| + Rails::SubTestTask.new(type => "test:prepare") do |t| + t.libs << "test" + subdir = type.to_s.singularize + t.pattern = "engines/*/test/#{subdir}/**/*_test.rb" + end end end diff --git a/users/lib/warden/session_serializer.rb b/lib/warden/session_serializer.rb index 81d7076..81d7076 100644 --- a/users/lib/warden/session_serializer.rb +++ b/lib/warden/session_serializer.rb diff --git a/users/lib/warden/strategies/secure_remote_password.rb b/lib/warden/strategies/secure_remote_password.rb index 2c334c6..2c334c6 100644 --- a/users/lib/warden/strategies/secure_remote_password.rb +++ b/lib/warden/strategies/secure_remote_password.rb diff --git a/users/lib/webfinger.rb b/lib/webfinger.rb index dd49b41..dd49b41 100644 --- a/users/lib/webfinger.rb +++ b/lib/webfinger.rb diff --git a/users/lib/webfinger/host_meta_presenter.rb b/lib/webfinger/host_meta_presenter.rb index 84ab7a9..84ab7a9 100644 --- a/users/lib/webfinger/host_meta_presenter.rb +++ b/lib/webfinger/host_meta_presenter.rb diff --git a/users/lib/webfinger/user_presenter.rb b/lib/webfinger/user_presenter.rb index 329f477..329f477 100644 --- a/users/lib/webfinger/user_presenter.rb +++ b/lib/webfinger/user_presenter.rb diff --git a/test/factories.rb b/test/factories.rb index 6c671f8..bebda5c 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -1,3 +1,44 @@ -Dir.glob(Rails.root.join('**','test','factories.rb')) do |factory_file| +ENGINE_FACTORY_FILES = Rails.root.join('engines','*','test','factories.rb') +Dir.glob(ENGINE_FACTORY_FILES) do |factory_file| require factory_file end + +FactoryGirl.define do + + factory :user do + login { Faker::Internet.user_name } + password_verifier "1234ABCD" + password_salt "4321AB" + + factory :user_with_settings do + email_forward { Faker::Internet.email } + email_aliases_attributes do + {:a => Faker::Internet.user_name + '@' + APP_CONFIG[:domain]} + end + end + + factory :admin_user do + after(:build) do |admin| + admin.stubs(:is_admin?).returns(true) + end + end + + factory :premium_user do + effective_service_level_code 2 + end + + end + + factory :token do + user + end + + factory :pgp_key do + keyblock <<-EOPGP +-----BEGIN PGP PUBLIC KEY BLOCK----- ++Dummy+PGP+KEY+++Dummy+PGP+KEY+++Dummy+PGP+KEY+++Dummy+PGP+KEY+ +#{SecureRandom.base64(4032)} +-----END PGP PUBLIC KEY BLOCK----- + EOPGP + end +end diff --git a/certs/test/files/ca.crt b/test/files/ca.crt index 8393eee..8393eee 100644 --- a/certs/test/files/ca.crt +++ b/test/files/ca.crt diff --git a/certs/test/files/ca.key b/test/files/ca.key index 125997f..125997f 100644 --- a/certs/test/files/ca.key +++ b/test/files/ca.key diff --git a/users/test/functional/application_controller_test.rb b/test/functional/application_controller_test.rb index 94b77bd..c4c922b 100644 --- a/users/test/functional/application_controller_test.rb +++ b/test/functional/application_controller_test.rb @@ -7,21 +7,21 @@ class ApplicationControllerTest < ActionController::TestCase @controller.response = @response end - def test_authorize_redirect - @controller.send(:authorize) + def test_require_login_redirect + @controller.send(:require_login) assert_access_denied(true, false) end - def test_authorized + def test_require_login login - @controller.send(:authorize) + @controller.send(:require_login) assert_access_denied(false) end - def test_authorize_admin + def test_require_admin login @current_user.expects(:is_admin?).returns(false) - @controller.send(:authorize_admin) + @controller.send(:require_admin) assert_access_denied end diff --git a/users/test/functional/helper_methods_test.rb b/test/functional/helper_methods_test.rb index 44226ae..44226ae 100644 --- a/users/test/functional/helper_methods_test.rb +++ b/test/functional/helper_methods_test.rb diff --git a/users/test/functional/keys_controller_test.rb b/test/functional/keys_controller_test.rb index 863be93..863be93 100644 --- a/users/test/functional/keys_controller_test.rb +++ b/test/functional/keys_controller_test.rb diff --git a/users/test/functional/sessions_controller_test.rb b/test/functional/sessions_controller_test.rb index fe7903f..fe7903f 100644 --- a/users/test/functional/sessions_controller_test.rb +++ b/test/functional/sessions_controller_test.rb diff --git a/users/test/functional/test_helpers_test.rb b/test/functional/test_helpers_test.rb index 845e516..845e516 100644 --- a/users/test/functional/test_helpers_test.rb +++ b/test/functional/test_helpers_test.rb diff --git a/users/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 57ae94d..0713836 100644 --- a/users/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -4,11 +4,17 @@ class UsersControllerTest < ActionController::TestCase test "should get new" do get :new - assert_equal User, assigns(:user).class assert_response :success end + test "new should redirect logged in users" do + login + get :new + assert_response :redirect + assert_redirected_to home_path + end + test "failed show without login" do user = find_record :user get :show, :id => user.id diff --git a/test/functional/v1/certs_controller_test.rb b/test/functional/v1/certs_controller_test.rb new file mode 100644 index 0000000..fb8e9c4 --- /dev/null +++ b/test/functional/v1/certs_controller_test.rb @@ -0,0 +1,46 @@ +require 'test_helper' + +class V1::CertsControllerTest < ActionController::TestCase + + test "send unlimited cert without login" do + with_config allow_anonymous_certs: true do + cert = expect_cert('UNLIMITED') + get :show + assert_response :success + assert_equal cert.to_s, @response.body + end + end + + test "send limited cert" do + with_config allow_limited_certs: true do + login + cert = expect_cert('LIMITED') + get :show + assert_response :success + assert_equal cert.to_s, @response.body + end + end + + test "send unlimited cert" do + login effective_service_level: ServiceLevel.new(id: 2) + cert = expect_cert('UNLIMITED') + get :show + assert_response :success + assert_equal cert.to_s, @response.body + end + + test "redirect if no eip service offered" do + get :show + assert_response :redirect + end + + protected + + def expect_cert(prefix) + cert = stub :to_s => "#{prefix.downcase} cert" + ClientCertificate.expects(:new). + with(:prefix => prefix). + returns(cert) + return cert + end +end diff --git a/test/functional/v1/messages_controller_test.rb b/test/functional/v1/messages_controller_test.rb new file mode 100644 index 0000000..24a5b1f --- /dev/null +++ b/test/functional/v1/messages_controller_test.rb @@ -0,0 +1,57 @@ +require 'test_helper' + +class V1::MessagesControllerTest < ActionController::TestCase + + setup do + @user = FactoryGirl.build(:user) + @user.save + @message = Message.new(:text => 'a test message') + @message.user_ids_to_show << @user.id + @message.save + end + + teardown do + @message.destroy + @user.destroy + end + + test "get messages for user" do + login @user + get :index + assert response.body.include? @message.text + assert response.body.include? @message.id + end + + test "mark message read for user" do + login @user + assert @message.user_ids_to_show.include?(@user.id) + assert !@message.user_ids_have_shown.include?(@user.id) + put :update, :id => @message.id + @message.reload + assert !@message.user_ids_to_show.include?(@user.id) + assert @message.user_ids_have_shown.include?(@user.id) + assert_json_response true + end + + test "do not get seen messages" do + login @user + put :update, :id => @message.id + @message.reload + get :index + assert !(response.body.include? @message.text) + assert !(response.body.include? @message.id) + end + + + test "mark read responds even with bad inputs" do + login @user + put :update, :id => 'more nonsense' + assert_json_response false + end + + test "fails if not authenticated" do + get :index, :format => :json + assert_access_denied + end + +end diff --git a/test/functional/v1/services_controller_test.rb b/test/functional/v1/services_controller_test.rb new file mode 100644 index 0000000..cde7d9f --- /dev/null +++ b/test/functional/v1/services_controller_test.rb @@ -0,0 +1,29 @@ +require 'test_helper' + +class V1::ServicesControllerTest < ActionController::TestCase + + test "anonymous user gets login required service info" do + get :show, format: :json + assert_json_response name: 'anonymous', + eip_rate_limit: false, + description: 'please login to access our services' + end + + test "anonymous user gets vpn service info" do + with_config allow_anonymous_certs: true do + get :show, format: :json + assert_json_response name: 'anonymous', + eip_rate_limit: false, + description: 'anonymous access to the VPN' + end + end + + test "user can see their service info" do + login + get :show, format: :json + default_level = APP_CONFIG[:default_service_level] + assert_json_response APP_CONFIG[:service_levels][default_level] + end + +end + diff --git a/users/test/functional/v1/sessions_controller_test.rb b/test/functional/v1/sessions_controller_test.rb index 4200e8f..df0d681 100644 --- a/users/test/functional/v1/sessions_controller_test.rb +++ b/test/functional/v1/sessions_controller_test.rb @@ -36,7 +36,7 @@ class V1::SessionsControllerTest < ActionController::TestCase post :create, :login => @user.login, 'A' => @client_hex end - test "should authorize" do + test "should authenticate" do request.env['warden'].expects(:authenticate!) @controller.stubs(:current_user).returns(@user) handshake = stub(:to_hash => {h: "ash"}) diff --git a/users/test/functional/v1/users_controller_test.rb b/test/functional/v1/users_controller_test.rb index 7cd9b0c..7cd9b0c 100644 --- a/users/test/functional/v1/users_controller_test.rb +++ b/test/functional/v1/users_controller_test.rb diff --git a/users/test/functional/webfinger_controller_test.rb b/test/functional/webfinger_controller_test.rb index 6597b69..6597b69 100644 --- a/users/test/functional/webfinger_controller_test.rb +++ b/test/functional/webfinger_controller_test.rb diff --git a/users/test/integration/api/Readme.md b/test/integration/api/Readme.md index 04363bd..04363bd 100644 --- a/users/test/integration/api/Readme.md +++ b/test/integration/api/Readme.md diff --git a/test/integration/api/login_test.rb b/test/integration/api/login_test.rb new file mode 100644 index 0000000..92d153f --- /dev/null +++ b/test/integration/api/login_test.rb @@ -0,0 +1,50 @@ +require 'test_helper' +require_relative 'srp_test' + +class LoginTest < SrpTest + + setup do + register_user + end + + test "requires handshake before validation" do + validate("bla") + assert_json_error login: I18n.t(:all_strategies_failed) + end + + test "login with srp" do + authenticate + assert_equal ["M2", "id", "token"], server_auth.keys + assert last_response.successful? + assert_nil server_auth["errors"] + assert server_auth["M2"] + end + + test "wrong password login attempt" do + authenticate password: "wrong password" + assert_json_error "base" => "Not a valid username/password combination" + assert !last_response.successful? + assert_nil server_auth["M2"] + end + + test "wrong username login attempt" do + assert_raises RECORD_NOT_FOUND do + authenticate login: "wrong login" + end + assert_json_error "base" => "Not a valid username/password combination" + assert !last_response.successful? + assert_nil server_auth + end + + test "logout" do + authenticate + logout + assert_equal 204, last_response.status + end + + test "logout requires token" do + authenticate + logout(nil, {}) + assert_equal 422, last_response.status + end +end diff --git a/test/integration/api/pgp_key_test.rb b/test/integration/api/pgp_key_test.rb new file mode 100644 index 0000000..4c7fb4c --- /dev/null +++ b/test/integration/api/pgp_key_test.rb @@ -0,0 +1,35 @@ +require 'test_helper' +require_relative 'srp_test' + +class PgpKeyTest < SrpTest + + setup do + # todo: prepare user and login without doing the srp dance + register_user + authenticate + end + + test "upload pgp key" do + update_user public_key: key + assert_equal key, Identity.for(@user).keys[:pgp] + end + + # eventually probably want to remove most of this into a non-integration + # functional test + test "prevent uploading invalid key" do + update_user public_key: "invalid key" + assert_nil Identity.for(@user).keys[:pgp] + end + + test "prevent emptying public key" do + update_user public_key: key + update_user public_key: "" + assert_equal key, Identity.for(@user).keys[:pgp] + end + + protected + + def key + @key ||= FactoryGirl.build :pgp_key + end +end diff --git a/users/test/integration/api/python/flow_with_srp.py b/test/integration/api/python/flow_with_srp.py index 9fc168b..9fc168b 100755 --- a/users/test/integration/api/python/flow_with_srp.py +++ b/test/integration/api/python/flow_with_srp.py diff --git a/users/test/integration/api/python/login_wrong_username.py b/test/integration/api/python/login_wrong_username.py index 390f250..390f250 100755 --- a/users/test/integration/api/python/login_wrong_username.py +++ b/test/integration/api/python/login_wrong_username.py diff --git a/users/test/integration/api/python/signup.py b/test/integration/api/python/signup.py index 0d3a4e0..0d3a4e0 100755 --- a/users/test/integration/api/python/signup.py +++ b/test/integration/api/python/signup.py diff --git a/users/test/integration/api/python/signup_and_login.py b/test/integration/api/python/signup_and_login.py index ac611d7..ac611d7 100755 --- a/users/test/integration/api/python/signup_and_login.py +++ b/test/integration/api/python/signup_and_login.py diff --git a/users/test/integration/api/python/signup_and_login_wrong_password.py b/test/integration/api/python/signup_and_login_wrong_password.py index 9efffa1..9efffa1 100755 --- a/users/test/integration/api/python/signup_and_login_wrong_password.py +++ b/test/integration/api/python/signup_and_login_wrong_password.py diff --git a/users/test/integration/api/python/umlauts.py b/test/integration/api/python/umlauts.py index 96fecbf..96fecbf 100755 --- a/users/test/integration/api/python/umlauts.py +++ b/test/integration/api/python/umlauts.py diff --git a/test/integration/api/signup_test.rb b/test/integration/api/signup_test.rb new file mode 100644 index 0000000..236c547 --- /dev/null +++ b/test/integration/api/signup_test.rb @@ -0,0 +1,20 @@ +require 'test_helper' +require_relative 'srp_test' + +class SignupTest < SrpTest + + setup do + register_user + end + + test "signup response" do + assert_json_response :login => @login, :ok => true + assert last_response.successful? + end + + test "signup creates user" do + assert @user + assert_equal @login, @user.login + end +end + diff --git a/test/integration/api/srp_test.rb b/test/integration/api/srp_test.rb new file mode 100644 index 0000000..26adc8c --- /dev/null +++ b/test/integration/api/srp_test.rb @@ -0,0 +1,105 @@ +class SrpTest < RackTest + include AssertResponses + + teardown do + if @user + cleanup_user + end + Warden.test_reset! + end + + # this test wraps the api and implements the interface the ruby-srp client. + def handshake(login, aa) + post "http://api.lvh.me:3000/1/sessions.json", + :login => login, + 'A' => aa, + :format => :json + response = JSON.parse(last_response.body) + if response['errors'] + raise RECORD_NOT_FOUND.new(response['errors']) + else + return response['B'] + end + end + + def validate(m) + put "http://api.lvh.me:3000/1/sessions/" + @login + '.json', + :client_auth => m, + :format => :json + return JSON.parse(last_response.body) + end + + protected + + attr_reader :server_auth + + def register_user(login = "integration_test_user", password = 'srp, verify me!') + cleanup_user(login) + post 'http://api.lvh.me:3000/1/users.json', + user_params(login: login, password: password) + @user = User.find_by_login(login) + @login = login + @password = password + end + + def update_user(params) + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', + user_params(params), + auth_headers + end + + def authenticate(params = nil) + @server_auth = srp(params).authenticate(self) + end + + def auth_headers + return {} if @server_auth.nil? + { + "HTTP_AUTHORIZATION" => encoded_token + } + end + + def encoded_token + ActionController::HttpAuthentication::Token.encode_credentials(server_auth["token"]) + end + + def logout(params=nil, headers=nil) + delete "http://api.lvh.me:3000/1/logout.json", + params || {format: :json}, + headers || auth_headers + end + + def cleanup_user(login = nil) + login ||= @user.login + Identity.by_address.key(login + '@' + APP_CONFIG[:domain]).each do |identity| + identity.destroy + end + if user = User.find_by_login(login) + user.destroy + end + end + + def user_params(params) + if params.keys.include?(:password) + srp_process_password(params) + end + return { user: params, format: :json } + end + + def srp_process_password(params) + params.reverse_merge! login: @login, salt: @salt + @srp = SRP::Client.new params[:login], password: params.delete(:password) + @salt = srp.salt.to_s(16) + params.merge! :password_verifier => srp.verifier.to_s(16), + :password_salt => @salt + end + + def srp(params = nil) + if params.nil? + @srp + else + params.reverse_merge! password: @password + SRP::Client.new(params.delete(:login) || @login, params) + end + end +end diff --git a/test/integration/api/update_account_test.rb b/test/integration/api/update_account_test.rb new file mode 100644 index 0000000..63429e7 --- /dev/null +++ b/test/integration/api/update_account_test.rb @@ -0,0 +1,51 @@ +require 'test_helper' +require_relative 'srp_test' + +class UpdateAccountTest < SrpTest + + setup do + register_user + end + + test "require authentication" do + update_user password: "No! Verify me instead." + assert_access_denied + end + + test "require token" do + authenticate + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', + user_params(password: "No! Verify me instead.") + assert_access_denied + end + + test "update password via api" do + authenticate + update_user password: "No! Verify me instead." + authenticate + assert last_response.successful? + assert_nil server_auth["errors"] + assert server_auth["M2"] + end + + test "change login with password_verifier" do + authenticate + new_login = 'zaph' + cleanup_user new_login + update_user login: new_login, password: @password + authenticate + assert last_response.successful? + assert_equal new_login, @user.reload.login + end + + test "prevent changing login without changing password_verifier" do + authenticate + original_login = @user.login + new_login = 'zaph' + cleanup_user new_login + update_user login: new_login + assert last_response.successful? + # does not change login if no password_verifier is present + assert_equal original_login, @user.reload.login + end +end diff --git a/users/test/integration/browser/account_test.rb b/test/integration/browser/account_test.rb index a5677ad..491a9e1 100644 --- a/users/test/integration/browser/account_test.rb +++ b/test/integration/browser/account_test.rb @@ -6,7 +6,7 @@ class AccountTest < BrowserIntegrationTest Identity.destroy_all_disabled end - test "normal account workflow" do + test "signup successfully" do username, password = submit_signup assert page.has_content?("Welcome #{username}") click_on 'Logout' @@ -16,6 +16,12 @@ class AccountTest < BrowserIntegrationTest user.account.destroy end + test "signup with username ending in dot json" do + username = Faker::Internet.user_name + '.json' + submit_signup username + assert page.has_content?("Welcome #{username}") + end + test "successful login" do username, password = submit_signup click_on 'Logout' @@ -51,7 +57,7 @@ class AccountTest < BrowserIntegrationTest end test "default user actions" do - username, password = submit_signup + login click_on "Account Settings" assert page.has_content? I18n.t('destroy_my_account') assert page.has_no_css? '#update_login_and_password' @@ -59,8 +65,8 @@ class AccountTest < BrowserIntegrationTest end test "default admin actions" do - username, password = submit_signup - with_config admins: [username] do + login + with_config admins: [@user.login] do click_on "Account Settings" assert page.has_content? I18n.t('destroy_my_account') assert page.has_no_css? '#update_login_and_password' @@ -70,7 +76,7 @@ class AccountTest < BrowserIntegrationTest test "change password" do with_config user_actions: ['change_password'] do - username, password = submit_signup + login click_on "Account Settings" within('#update_login_and_password') do fill_in 'Password', with: "other password" @@ -78,16 +84,15 @@ class AccountTest < BrowserIntegrationTest click_on 'Save' end click_on 'Logout' - attempt_login(username, "other password") - assert page.has_content?("Welcome #{username}") - User.find_by_login(username).account.destroy + attempt_login(@user.login, "other password") + assert page.has_content?("Welcome #{@user.login}") end end test "change pgp key" do with_config user_actions: ['change_pgp_key'] do pgp_key = FactoryGirl.build :pgp_key - username, password = submit_signup + login click_on "Account Settings" within('#update_pgp_key') do fill_in 'Public key', with: pgp_key @@ -97,9 +102,7 @@ class AccountTest < BrowserIntegrationTest # at some point we're done: page.assert_no_selector 'input[value="Saving..."]' assert page.has_field? 'Public key', with: pgp_key.to_s - user = User.find_by_login(username) - assert_equal pgp_key, user.public_key - user.account.destroy + assert_equal pgp_key, @user.reload.public_key end end @@ -123,6 +126,20 @@ class AccountTest < BrowserIntegrationTest assert page.has_content?("server failed") end + test "does not render signup form without js" do + Capybara.current_driver = :rack_test # no js + visit '/signup' + assert page.has_no_content?("Username") + assert page.has_no_content?("Password") + end + + test "does not render login form without js" do + Capybara.current_driver = :rack_test # no js + visit '/login' + assert page.has_no_content?("Username") + assert page.has_no_content?("Password") + end + def attempt_login(username, password) click_on 'Log In' fill_in 'Username', with: username @@ -131,9 +148,9 @@ class AccountTest < BrowserIntegrationTest end def assert_invalid_login(page) - assert page.has_selector? 'input.btn-primary.disabled' + assert page.has_selector? '.btn-primary.disabled' assert page.has_content? I18n.t(:invalid_user_pass) - assert page.has_no_selector? 'input.btn-primary.disabled' + assert page.has_no_selector? '.btn-primary.disabled' end def inject_malicious_js diff --git a/test/integration/browser/password_validation_test.rb b/test/integration/browser/password_validation_test.rb new file mode 100644 index 0000000..45eb0bf --- /dev/null +++ b/test/integration/browser/password_validation_test.rb @@ -0,0 +1,31 @@ +require 'test_helper' + +class PasswordValidationTest < BrowserIntegrationTest + + test "password confirmation is validated" do + username ||= "test_#{SecureRandom.urlsafe_base64}".downcase + password ||= SecureRandom.base64 + visit '/users/new' + fill_in 'Username', with: username + fill_in 'Password', with: password + fill_in 'Password confirmation', with: password + "-typo" + click_on 'Sign Up' + assert page.has_content? "does not match." + assert_equal '/users/new', current_path + assert page.has_selector? ".error #srp_password_confirmation" + end + + test "password needs to be at least 8 chars long" do + username ||= "test_#{SecureRandom.urlsafe_base64}".downcase + password ||= SecureRandom.base64[0,7] + visit '/users/new' + fill_in 'Username', with: username + fill_in 'Password', with: password + fill_in 'Password confirmation', with: password + click_on 'Sign Up' + assert page.has_content? "needs to be at least 8 characters long" + assert_equal '/users/new', current_path + assert page.has_selector? ".error #srp_password" + end +end + diff --git a/test/integration/browser/session_test.rb b/test/integration/browser/session_test.rb new file mode 100644 index 0000000..fb20847 --- /dev/null +++ b/test/integration/browser/session_test.rb @@ -0,0 +1,17 @@ +require 'test_helper' + +class SessionTest < BrowserIntegrationTest + + test "valid session" do + login + assert page.has_content?("Logout") + end + + test "expired session" do + login + pretend_now_is(Time.now + 80.minutes) do + visit '/' + assert page.has_content?("Log In") + end + end +end diff --git a/help/test/integration/navigation_test.rb b/test/integration/navigation_test.rb index eec8c0e..eec8c0e 100644 --- a/help/test/integration/navigation_test.rb +++ b/test/integration/navigation_test.rb diff --git a/test/integration/os_detection_test.rb b/test/integration/os_detection_test.rb deleted file mode 100644 index 6d9a648..0000000 --- a/test/integration/os_detection_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'test_helper' - -class OsDetectionTest < BrowserIntegrationTest - - test "old windows shows deactivated download" do - page.driver.add_headers "User-Agent" => "Win98" - visit '/' - assert_selector "html.oldwin" - assert has_text? "not available" - end - - test "android shows android download" do - page.driver.add_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/test/leap_web_users_test.rb b/test/leap_web_users_test.rb index f142e54..f142e54 100644 --- a/users/test/leap_web_users_test.rb +++ b/test/leap_web_users_test.rb diff --git a/test/nagios/soledad_sync.py b/test/nagios/soledad_sync.py index 3f176b5..617dd3a 100755 --- a/test/nagios/soledad_sync.py +++ b/test/nagios/soledad_sync.py @@ -7,13 +7,15 @@ import tempfile -import requests import os -import srp._pysrp as srp import shutil import u1db +from support.api import Api +from support.config import Config +from support.user import User + + from u1db.remote.http_target import HTTPSyncTarget -from webapp_login import read_config, parse, authenticate, fail # monkey patch U1DB's HTTPSyncTarget to perform token based auth @@ -37,58 +39,39 @@ HTTPSyncTarget._sign_request = _sign_request # to actually use the Soledad client in the future. def get_soledad_info(config, tempdir): - # get login and get user info - user = config['user'] - api = config['api'] - usr = srp.User( user['username'], user['password'], srp.SHA256, srp.NG_1024 ) - try: - auth = parse(authenticate(api, usr)) - except requests.exceptions.ConnectionError: - fail('no connection to server') - # get soledad server url - service_url = 'https://%s:%d/%d/config/soledad-service.json' % \ - (api['domain'], api['port'], api['version']) - soledad_hosts = requests.get(service_url).json['hosts'] - host = soledad_hosts.keys()[0] - server_url = 'https://%s:%d/user-%s' % \ - (soledad_hosts[host]['hostname'], soledad_hosts[host]['port'], - auth['id']) - # get provider ca certificate - #ca_cert = requests.get('https://127.0.0.1/ca.crt', verify=False).text - #cert_file = os.path.join(tempdir, 'ca.crt') - cert_file = None # not used for now - #with open(cert_file, 'w') as f: - # f.write(ca_cert) - return auth['id'], user['password'], server_url, cert_file, auth['token'] - - -def run_tests(): - tempdir = tempfile.mkdtemp() - uuid, password, server_url, cert_file, token = \ - get_soledad_info(read_config(), tempdir) - exc = None - try: - # in the future, we can replace the following by an actual Soledad - # client sync, if needed - db = u1db.open(os.path.join(tempdir, '%s.db' % uuid), True) - creds = {'token': {'uuid': uuid, 'token': token}} - db.sync(server_url, creds=creds, autocreate=False) - except Exception as e: - exc = e - shutil.rmtree(tempdir) - exit(report(exc)) - - -def report(exc): - if exc is None: - print '0 soledad_sync - OK - can sync soledad fine' - return 0 - if isinstance(exc, u1db.errors.U1DBError): - print '2 soledad_sync - CRITICAL - ' + exc.message - else: - print '2 soledad_sync - CRITICAL - ' + str(exc) - return 2 - + # get login and get user info + user = User(config) + api = Api(config, verify=False) + auth = user.login(api) + # get soledad server url + soledad_hosts = api.get('config/soledad-service.json')['hosts'] + host = soledad_hosts.keys()[0] + server_url = 'https://%s:%d/user-%s' % \ + (soledad_hosts[host]['hostname'], soledad_hosts[host]['port'], + auth['id']) + # get provider ca certificate + #ca_cert = requests.get('https://127.0.0.1/ca.crt', verify=False).text + #cert_file = os.path.join(tempdir, 'ca.crt') + cert_file = None # not used for now + #with open(cert_file, 'w') as f: + # f.write(ca_cert) + return auth['id'], server_url, cert_file, auth['token'] + + +def can_sync_soledad_fine(): + tempdir = tempfile.mkdtemp() + try: + uuid, server_url, cert_file, token = \ + get_soledad_info(Config(), tempdir) + # in the future, we can replace the following by an actual Soledad + # client sync, if needed + db = u1db.open(os.path.join(tempdir, '%s.db' % uuid), True) + creds = {'token': {'uuid': uuid, 'token': token}} + db.sync(server_url, creds=creds, autocreate=False) + finally: + shutil.rmtree(tempdir) if __name__ == '__main__': - run_tests() + from support import nagios_test + exit_code = nagios_test.run(can_sync_soledad_fine) + exit(exit_code) diff --git a/certs/app/mailers/.gitkeep b/test/nagios/support/__init__.py index e69de29..e69de29 100644 --- a/certs/app/mailers/.gitkeep +++ b/test/nagios/support/__init__.py diff --git a/test/nagios/support/api.py b/test/nagios/support/api.py new file mode 100644 index 0000000..ec1af99 --- /dev/null +++ b/test/nagios/support/api.py @@ -0,0 +1,39 @@ +import requests +import json + +class Api(): + def __init__(self, config, verify=True): + self.config = config.api + self.session = requests.session() + self.verify = verify + + def api_url(self, path): + return self.api_root() + path + + def api_root(self): + return "https://{domain}:{port}/{version}/".format(**self.config) + + def get(self, path, **args): + response = self.session.get(self.api_url(path), + verify=self.verify, + **args) + return self.parse_json(response) + + def post(self, path, **args): + response = self.session.post(self.api_url(path), + verify=self.verify, + **args) + return self.parse_json(response) + + def put(self, path, **args): + response = self.session.put(self.api_url(path), + verify=self.verify, + **args) + return self.parse_json(response) + + def parse_json(self, response): + try: + return response.json() + except TypeError: + return response.json # older versions of requests + diff --git a/test/nagios/support/config.py b/test/nagios/support/config.py new file mode 100644 index 0000000..afb4464 --- /dev/null +++ b/test/nagios/support/config.py @@ -0,0 +1,14 @@ +import yaml + +class Config(): + def __init__(self, filename="/etc/leap/hiera.yaml"): + with open("/etc/leap/hiera.yaml", 'r') as stream: + config = yaml.load(stream) + self.user = config['webapp']['nagios_test_user'] + if 'username' not in self.user: + raise Exception('nagios test user lacks username') + if 'password' not in self.user: + raise Exception('nagios test user lacks password') + self.api = config['api'] + self.api['version'] = config['webapp']['api_version'] + diff --git a/test/nagios/support/nagios_report.py b/test/nagios/support/nagios_report.py new file mode 100644 index 0000000..13cd551 --- /dev/null +++ b/test/nagios/support/nagios_report.py @@ -0,0 +1,24 @@ +def functions_for_system(under_test): + """ + returns a set of functions to use for nagios reporting: + >>> ok, warn, critical, unknown = functions_for_system("tested system") + + each of them will print a nagios line with its argument and + return the exit code: + >>> warn("that looks strange") + 1 tested system - WARNING - that looks strange + 1 + """ + def report_function(code): + return lambda message : report(under_test, code, message) + return map(report_function, [0,1,2,3]) + +def report(system, code, message): + codes = {0: 'OK', 1: 'WARNING', 2: 'CRITICAL', 3: 'UNKNOWN'} + print "%d %s - %s - %s" % \ + (code, system, codes[code], message) + return code + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/test/nagios/support/nagios_test.py b/test/nagios/support/nagios_test.py new file mode 100644 index 0000000..3eb8d55 --- /dev/null +++ b/test/nagios/support/nagios_test.py @@ -0,0 +1,49 @@ +import __main__ as main +import os +import sys +import nagios_report + +def run(test): + """ + run takes a function and tries it out. + If it returns nothing or 0 everything is fine and run prints an OK message + with the function name. + >>> def this_works_fine(): return + >>> run(this_works_fine) + 0 nagios_test.py - OK - this_works_fine + 0 + >>> def this_also_works_fine(): return 0 + >>> run(this_also_works_fine) + 0 nagios_test.py - OK - this_also_works_fine + 0 + + If the function returns something else it will be printed as a warning. + >>> run(lambda : "this is a warning") + 1 nagios_test.py - WARNING - this is a warning + 1 + + Errors raised will result in a CRITICAL nagios string. + >>> def failure(): raise Exception("something went wrong") + >>> run(failure) + 2 nagios_test.py - CRITICAL - something went wrong + 2 + """ + try: + name = os.path.basename(main.__file__) + except AttributeError: + name = sys.argv[0] + ok, warn, fail, unknown = nagios_report.functions_for_system(name) + try: + warning = test() + if warning and warning != 0: + code = warn(warning) + else: + code = ok(test.__name__) + except Exception as exc: + code = fail(exc.message or str(exc)) + return code + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/test/nagios/support/user.py b/test/nagios/support/user.py new file mode 100644 index 0000000..9bf1d0a --- /dev/null +++ b/test/nagios/support/user.py @@ -0,0 +1,64 @@ +import srp._pysrp as srp +import binascii +import string +import random + +safe_unhexlify = lambda x: binascii.unhexlify(x) if ( + len(x) % 2 == 0) else binascii.unhexlify('0' + x) + +# let's have some random name and password +def id_generator(size=6, chars=string.ascii_lowercase + string.digits): + return ''.join(random.choice(chars) for x in range(size)) + +class User(): + def __init__(self, config = None): + if config and config.user: + self.username = config.user["username"] + self.password = config.user["password"] + else: + self.username = 'test_' + id_generator() + self.password = id_generator() + id_generator() + self.srp_user = srp.User(self.username, self.password, srp.SHA256, srp.NG_1024) + + def signup(self, api): + salt, vkey = srp.create_salted_verification_key( self.username, self.password, srp.SHA256, srp.NG_1024 ) + user_params = { + 'user[login]': self.username, + 'user[password_verifier]': binascii.hexlify(vkey), + 'user[password_salt]': binascii.hexlify(salt) + } + return api.post('users.json', data = user_params) + + def login(self, api): + init=self.init_authentication(api) + if ('errors' in init): + raise Exception('test user not found') + auth=self.authenticate(api, init) + if ('errors' in auth): + raise Exception('srp password auth failed') + self.verify_server(auth) + if not self.is_authenticated(): + raise Exception('user is not authenticated') + return auth + + def init_authentication(self, api): + uname, A = self.srp_user.start_authentication() + params = { + 'login': uname, + 'A': binascii.hexlify(A) + } + return api.post('sessions', data=params) + + def authenticate(self, api, init): + M = self.srp_user.process_challenge( + safe_unhexlify(init['salt']), safe_unhexlify(init['B'])) + auth = api.put('sessions/' + self.username, + data={'client_auth': binascii.hexlify(M)}) + return auth + + def verify_server(self, auth): + self.srp_user.verify_session(safe_unhexlify(auth["M2"])) + + def is_authenticated(self): + return self.srp_user.authenticated() + diff --git a/test/nagios/webapp_login.py b/test/nagios/webapp_login.py index 1711238..7741325 100755 --- a/test/nagios/webapp_login.py +++ b/test/nagios/webapp_login.py @@ -2,85 +2,17 @@ # Test Authentication with the webapp API works. -import requests -import json -import string -import random -import srp._pysrp as srp -import binascii -import yaml +from support.api import Api +from support.config import Config +from support.user import User - -safe_unhexlify = lambda x: binascii.unhexlify(x) if ( - len(x) % 2 == 0) else binascii.unhexlify('0' + x) - - -def read_config(): - with open("/etc/leap/hiera.yaml", 'r') as stream: - config = yaml.load(stream) - user = config['webapp']['nagios_test_user'] - if 'username' not in user: - fail('nagios test user lacks username') - if 'password' not in user: - fail('nagios test user lacks password') - api = config['api'] - api['version'] = config['webapp']['api_version'] - return {'api': api, 'user': user} - - -def run_tests(config): - user = config['user'] - api = config['api'] - usr = srp.User(user['username'], user['password'], srp.SHA256, srp.NG_1024) - try: - auth = parse(authenticate(api, usr)) - except requests.exceptions.ConnectionError: - fail('no connection to server') - exit(report(auth, usr)) - -# parse the server responses - - -def parse(response): - request = response.request - try: - return json.loads(response.text) - except ValueError: - return None - - -def authenticate(api, usr): - api_url = "https://{domain}:{port}/{version}".format(**api) - session = requests.session() - uname, A = usr.start_authentication() - params = { - 'login': uname, - 'A': binascii.hexlify(A) - } - init = parse( - session.post(api_url + '/sessions', data=params, verify=False)) - if ('errors' in init): - fail('test user not found') - M = usr.process_challenge( - safe_unhexlify(init['salt']), safe_unhexlify(init['B'])) - return session.put(api_url + '/sessions/' + uname, verify=False, - data={'client_auth': binascii.hexlify(M)}) - - -def report(auth, usr): - if ('errors' in auth): - fail('srp password auth failed') - usr.verify_session(safe_unhexlify(auth["M2"])) - if usr.authenticated(): - print '0 webapp_login - OK - can login to webapp fine' - return 0 - print '1 webapp_login - WARNING - failed to verify webapp server' - return 1 - - -def fail(reason): - print '2 webapp_login - CRITICAL - ' + reason - exit(2) +def login_successfully(): + config = Config() + user = User(config) + api = Api(config, verify=False) + user.login(api) if __name__ == '__main__': - run_tests(read_config()) + from support import nagios_test + exit_code = nagios_test.run(login_successfully) + exit(exit_code) diff --git a/test/nagios/webapp_signup.py b/test/nagios/webapp_signup.py new file mode 100755 index 0000000..3e7283e --- /dev/null +++ b/test/nagios/webapp_signup.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +# Test Signup and Login with the webapp API works. + +from support.api import Api +from support.config import Config +from support.user import User + +def signup_successfully(): + config = Config() + user = User() + api = Api(config, verify=False) + user.signup(api) + user.login(api) + +if __name__ == '__main__': + from support import nagios_test + exit_code = nagios_test.run(signup_successfully) + exit(exit_code) diff --git a/test/support/assert_responses.rb b/test/support/assert_responses.rb new file mode 100644 index 0000000..b01166f --- /dev/null +++ b/test/support/assert_responses.rb @@ -0,0 +1,46 @@ +module AssertResponses + + # response that works with different TestCases: + # ActionController::TestCase has @response + # ActionDispatch::IntegrationTest has @response + # Rack::Test::Methods defines last_response + def get_response + @response || last_response + end + + def assert_attachement_filename(name) + assert_equal %Q(attachment; filename="#{name}"), + get_response.headers["Content-Disposition"] + end + + def json_response + response = JSON.parse(get_response.body) + response.respond_to?(:with_indifferent_access) ? + response.with_indifferent_access : + response + end + + def assert_json_response(object) + assert_equal 'application/json', + get_response.content_type.to_s.split(';').first + if object.is_a? Hash + object.stringify_keys! if object.respond_to? :stringify_keys! + assert_equal object, json_response + else + assert_equal object.to_json, get_response.body + end + end + + def assert_json_error(object) + object.stringify_keys! if object.respond_to? :stringify_keys! + assert_json_response :errors => object + end +end + +class ::ActionController::TestCase + include AssertResponses +end + +class ::ActionDispatch::IntegrationTest + include AssertResponses +end diff --git a/users/test/support/auth_test_helper.rb b/test/support/auth_test_helper.rb index 57f9f9b..57f9f9b 100644 --- a/users/test/support/auth_test_helper.rb +++ b/test/support/auth_test_helper.rb diff --git a/test/support/browser_integration_test.rb b/test/support/browser_integration_test.rb new file mode 100644 index 0000000..1c872ff --- /dev/null +++ b/test/support/browser_integration_test.rb @@ -0,0 +1,98 @@ +# +# BrowserIntegrationTest +# +# Use this class for capybara based integration tests for the ui. +# + +class BrowserIntegrationTest < ActionDispatch::IntegrationTest + + CONFIG_RU = (Rails.root + 'config.ru').to_s + OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first + + require 'capybara/poltergeist' + + Capybara.register_driver :rack_test do |app| + Capybara::RackTest::Driver.new(app) + end + + Capybara.register_driver :poltergeist do |app| + Capybara::Poltergeist::Driver.new(app) + end + + # this is integration testing. So let's make the whole + # rack stack available... + Capybara.app = OUTER_APP + Capybara.run_server = true + Capybara.app_host = 'http://lvh.me:3003' + Capybara.server_port = 3003 + Capybara.javascript_driver = :poltergeist + Capybara.default_wait_time = 5 + + + # Make the Capybara DSL available + include Capybara::DSL + + setup do + Capybara.current_driver = Capybara.javascript_driver + page.driver.add_headers 'ACCEPT-LANGUAGE' => 'en-EN' + end + + teardown do + Capybara.reset_sessions! # Forget the (simulated) browser state + Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver + end + + def submit_signup(username = nil, password = nil) + username ||= "test_#{SecureRandom.urlsafe_base64}".downcase + password ||= SecureRandom.base64 + visit '/users/new' + fill_in 'Username', with: username + fill_in 'Password', with: password + fill_in 'Password confirmation', with: password + click_on 'Sign Up' + return username, password + end + + # currently this only works for tests with poltergeist. + def login(user = nil) + @user ||= user ||= FactoryGirl.create(:user) + token = Token.create user_id: user.id + page.driver.add_header "Authorization", %Q(Token token="#{token}") + visit '/' + end + + teardown do + if @user && @user.reload + Identity.destroy_all_for @user + @user.destroy + end + end + + add_teardown_hook do |testcase| + unless testcase.passed? + testcase.save_state + end + end + + def save_state + File.open(logfile_path, 'w') do |test_log| + test_log.puts self.class.name + test_log.puts "=========================" + test_log.puts __name__ + test_log.puts Time.now + test_log.puts current_path + test_log.puts page.status_code + test_log.puts page.response_headers + test_log.puts "page.html" + test_log.puts "------------------------" + test_log.puts page.html + test_log.puts "server log" + test_log.puts "------------------------" + test_log.puts `tail log/test.log -n 200` + end + page.save_screenshot screenshot_path + # some drivers do not support screenshots + rescue Capybara::NotSupportedByDriverError + end + +end diff --git a/test/support/rack_test.rb b/test/support/rack_test.rb new file mode 100644 index 0000000..806339a --- /dev/null +++ b/test/support/rack_test.rb @@ -0,0 +1,38 @@ +require_relative 'assert_responses' + +class RackTest < ActiveSupport::TestCase + include Rack::Test::Methods + include Warden::Test::Helpers + + CONFIG_RU = (Rails.root + 'config.ru').to_s + OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first + + def app + OUTER_APP + end + + def assert_access_denied + assert_json_response('error' => I18n.t(:not_authorized)) + assert_response :unprocessable_entity + end + + # inspired by rails 4 + # -> actionpack/lib/action_dispatch/testing/assertions/response.rb + def assert_response(type, message = nil) + # RackTest does not know @response + response_code = last_response.status + message ||= "Expected response to be a <#{type}>, but was <#{response_code}>" + + if Symbol === type + if [:success, :missing, :redirect, :error].include?(type) + assert last_response.send("#{type}?"), message + else + code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type] + assert_equal code, response_code, message + end + else + assert_equal type, response_code, message + end + end + +end diff --git a/users/test/support/stub_record_helper.rb b/test/support/stub_record_helper.rb index 25138a0..25138a0 100644 --- a/users/test/support/stub_record_helper.rb +++ b/test/support/stub_record_helper.rb diff --git a/users/test/support/time_test_helper.rb b/test/support/time_test_helper.rb index f673f12..f673f12 100644 --- a/users/test/support/time_test_helper.rb +++ b/test/support/time_test_helper.rb diff --git a/core/test/support/with_config_helper.rb b/test/support/with_config_helper.rb index 65eb7bc..65eb7bc 100644 --- a/core/test/support/with_config_helper.rb +++ b/test/support/with_config_helper.rb diff --git a/test/test_helper.rb b/test/test_helper.rb index 3fb2716..d001ac7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -4,80 +4,15 @@ require 'rails/test_help' require 'mocha/setup' +# Load support files from toplevel +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } + # Load support files from all engines -Dir["#{File.dirname(__FILE__)}/../*/test/support/**/*.rb"].each { |f| require f } +Dir["#{File.dirname(__FILE__)}/../engines/*/test/support/**/*.rb"].each { |f| require f } class ActiveSupport::TestCase # Add more helper methods to be used by all tests here... - def file_path(name) - File.join(Rails.root, 'test', 'files', name) - end - -end - -require 'capybara/poltergeist' - -CONFIG_RU = (Rails.root + 'config.ru').to_s -OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first - -Capybara.register_driver :rack_test do |app| - Capybara::RackTest::Driver.new(app) -end - -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app) -end - -# this is integration testing. So let's make the whole -# rack stack available... -Capybara.app = OUTER_APP -Capybara.run_server = true -Capybara.app_host = 'http://lvh.me:3003' -Capybara.server_port = 3003 -Capybara.javascript_driver = :poltergeist -Capybara.default_wait_time = 5 - -class BrowserIntegrationTest < ActionDispatch::IntegrationTest - # Make the Capybara DSL available - include Capybara::DSL - include IntegrationTestHelper - - setup do - Capybara.current_driver = Capybara.javascript_driver - page.driver.add_headers 'ACCEPT-LANGUAGE' => 'en-EN' - end - - teardown do - Capybara.reset_sessions! # Forget the (simulated) browser state - Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver - end - - add_teardown_hook do |testcase| - unless testcase.passed? - testcase.save_state - end - end - - def save_state - page.save_screenshot screenshot_path - File.open(logfile_path, 'w') do |test_log| - test_log.puts self.class.name - test_log.puts "=========================" - test_log.puts __name__ - test_log.puts Time.now - test_log.puts current_path - test_log.puts page.status_code - test_log.puts page.response_headers - test_log.puts "page.html" - test_log.puts "------------------------" - test_log.puts page.html - test_log.puts "server log" - test_log.puts "------------------------" - test_log.puts `tail log/test.log -n 200` - end - end - protected def logfile_path @@ -87,4 +22,9 @@ class BrowserIntegrationTest < ActionDispatch::IntegrationTest def screenshot_path Rails.root + 'tmp' + "#{self.class.name.underscore}.#{__name__}.png" end + + def file_path(name) + File.join(Rails.root, 'test', 'files', name) + end + end diff --git a/users/test/unit/account_test.rb b/test/unit/account_test.rb index 4fb3c3d..b2bfe27 100644 --- a/users/test/unit/account_test.rb +++ b/test/unit/account_test.rb @@ -8,7 +8,7 @@ class AccountTest < ActiveSupport::TestCase test "create a new account" do user = Account.create(FactoryGirl.attributes_for(:user)) - assert user.valid? + assert user.valid?, "unexpected errors: #{user.errors.inspect}" assert user.persisted? assert id = user.identity assert_equal user.email_address, id.address diff --git a/test/unit/anonymous_user_test.rb b/test/unit/anonymous_user_test.rb new file mode 100644 index 0000000..6e94d39 --- /dev/null +++ b/test/unit/anonymous_user_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' + +class AnonymousUserTest < ActiveSupport::TestCase + + setup do + @anonymous = AnonymousUser.new + end + + test "has nil values" do + assert_nil @anonymous.id + assert_nil @anonymous.email_address + assert_nil @anonymous.login + end + + test "has no messages" do + assert_equal [], @anonymous.messages + end + + test "has anonymous service level" do + assert @anonymous.effective_service_level.is_a? AnonymousServiceLevel + end + +end diff --git a/certs/test/unit/client_certificate_test.rb b/test/unit/client_certificate_test.rb index 036e724..036e724 100644 --- a/certs/test/unit/client_certificate_test.rb +++ b/test/unit/client_certificate_test.rb diff --git a/users/test/unit/helpers/session_helper_test.rb b/test/unit/helpers/session_helper_test.rb index 2824733..2824733 100644 --- a/users/test/unit/helpers/session_helper_test.rb +++ b/test/unit/helpers/session_helper_test.rb diff --git a/users/test/unit/helpers/users_helper_test.rb b/test/unit/helpers/users_helper_test.rb index 96af37a..96af37a 100644 --- a/users/test/unit/helpers/users_helper_test.rb +++ b/test/unit/helpers/users_helper_test.rb diff --git a/users/test/unit/identity_test.rb b/test/unit/identity_test.rb index eca104f..eca104f 100644 --- a/users/test/unit/identity_test.rb +++ b/test/unit/identity_test.rb diff --git a/users/test/unit/local_email_test.rb b/test/unit/local_email_test.rb index 20ee7f1..20ee7f1 100644 --- a/users/test/unit/local_email_test.rb +++ b/test/unit/local_email_test.rb diff --git a/users/test/unit/token_test.rb b/test/unit/token_test.rb index 6c9f209..a3c6cf6 100644 --- a/users/test/unit/token_test.rb +++ b/test/unit/token_test.rb @@ -78,6 +78,12 @@ class ClientCertificateTest < ActiveSupport::TestCase end - + test "Token.destroy_all_expired does not interfere with expired.authenticate" do + expired = FactoryGirl.create :token, last_seen_at: 2.hours.ago + with_config auth: {token_expires_after: 60} do + Token.destroy_all_expired + end + assert_nil expired.authenticate + end end diff --git a/users/test/unit/user_test.rb b/test/unit/user_test.rb index ffbb7d8..ffbb7d8 100644 --- a/users/test/unit/user_test.rb +++ b/test/unit/user_test.rb diff --git a/users/test/unit/warden_strategy_secure_remote_password_test.rb b/test/unit/warden_strategy_secure_remote_password_test.rb index e6fcfbe..e6fcfbe 100644 --- a/users/test/unit/warden_strategy_secure_remote_password_test.rb +++ b/test/unit/warden_strategy_secure_remote_password_test.rb diff --git a/users/test/unit/webfinger/host_meta_presenter_test.rb b/test/unit/webfinger/host_meta_presenter_test.rb index af86404..af86404 100644 --- a/users/test/unit/webfinger/host_meta_presenter_test.rb +++ b/test/unit/webfinger/host_meta_presenter_test.rb diff --git a/users/test/unit/webfinger/user_presenter_test.rb b/test/unit/webfinger/user_presenter_test.rb index 04aeb22..04aeb22 100644 --- a/users/test/unit/webfinger/user_presenter_test.rb +++ b/test/unit/webfinger/user_presenter_test.rb diff --git a/ui_dependencies.rb b/ui_dependencies.rb deleted file mode 100644 index 4b5d706..0000000 --- a/ui_dependencies.rb +++ /dev/null @@ -1,28 +0,0 @@ -gem "haml", "~> 3.1.7" -gem "bootstrap-sass", "= 2.3.2.2" -gem "jquery-rails" -gem "simple_form" -gem 'client_side_validations' -gem 'client_side_validations-simple_form' -gem "bootswatch-rails", "~> 0.5.0" - -gem 'kaminari', "0.13.0" # for pagination. trying 0.13.0 as there seem to be - # issues with 0.14.0 when using couchrest - -gem 'rails-i18n' # locale files for built-in validation messages and times - # https://github.com/svenfuchs/rails-i18n - # for a list of keys: - # https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml - -gem 'rdiscount' # for rendering .md templates - -group :assets do - gem "haml-rails", "~> 0.3.4" - gem "sass-rails", "~> 3.2.5" - gem "coffee-rails", "~> 3.2.2" - gem "uglifier", "~> 1.2.7" - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - gem 'therubyracer', "~> 0.10.2", :platforms => :ruby - -end diff --git a/users/Gemfile b/users/Gemfile deleted file mode 100644 index 4101ead..0000000 --- a/users/Gemfile +++ /dev/null @@ -1,15 +0,0 @@ -source "https://rubygems.org" - -eval(File.read(File.dirname(__FILE__) + '/../common_dependencies.rb')) -eval(File.read(File.dirname(__FILE__) + '/../ui_dependencies.rb')) - -# We require leap_web_core from here so we can use the path option. -gem "leap_web_core", :path => '../core' - -# Declare your gem's dependencies in leap_web_users.gemspec. -# Bundler will treat runtime dependencies like base dependencies, and -# development dependencies will be added by default to the :development group. -gemspec - -# To use debugger -# gem 'ruby-debug' diff --git a/users/Rakefile b/users/Rakefile deleted file mode 100644 index 38da5fc..0000000 --- a/users/Rakefile +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env rake - -require 'rake/packagetask' -require 'rubygems/package_task' - -begin - require 'bundler/setup' -rescue LoadError - puts 'You must `gem install bundler` and `bundle install` to run rake tasks' -end -begin - require 'rdoc/task' -rescue LoadError - require 'rdoc/rdoc' - require 'rake/rdoctask' - RDoc::Task = Rake::RDocTask -end - -RDoc::Task.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'LeapWebUsers' - rdoc.options << '--line-numbers' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -spec = eval(File.read('leap_web_users.gemspec')) -Gem::PackageTask.new(spec) do |p| - p.gem_spec = spec -end - -Bundler::GemHelper.install_tasks - -require 'rake/testtask' - -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.libs << 'test' - t.pattern = 'test/**/*_test.rb' - t.verbose = false -end - - -task :default => :test diff --git a/users/app/assets/images/leap_web_users/.gitkeep b/users/app/assets/images/leap_web_users/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/assets/images/leap_web_users/.gitkeep +++ /dev/null diff --git a/users/app/assets/javascripts/leap_web_users/.gitkeep b/users/app/assets/javascripts/leap_web_users/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/assets/javascripts/leap_web_users/.gitkeep +++ /dev/null diff --git a/users/app/assets/stylesheets/leap_web_users/.gitkeep b/users/app/assets/stylesheets/leap_web_users/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/assets/stylesheets/leap_web_users/.gitkeep +++ /dev/null diff --git a/users/app/controllers/.gitkeep b/users/app/controllers/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/controllers/.gitkeep +++ /dev/null diff --git a/users/app/controllers/controller_extension/token_authentication.rb b/users/app/controllers/controller_extension/token_authentication.rb deleted file mode 100644 index 530294a..0000000 --- a/users/app/controllers/controller_extension/token_authentication.rb +++ /dev/null @@ -1,23 +0,0 @@ -module ControllerExtension::TokenAuthentication - extend ActiveSupport::Concern - - def token_authenticate - authenticate_with_http_token do |token_id, options| - @token = Token.find(token_id) - end - @token.authenticate if @token - end - - def logout - super - clear_token - end - - def clear_token - authenticate_with_http_token do |token_id, options| - @token = Token.find(token_id) - @token.destroy if @token - end - end -end - diff --git a/users/app/helpers/.gitkeep b/users/app/helpers/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/helpers/.gitkeep +++ /dev/null diff --git a/users/app/mailers/.gitkeep b/users/app/mailers/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/mailers/.gitkeep +++ /dev/null diff --git a/users/app/models/.gitkeep b/users/app/models/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/models/.gitkeep +++ /dev/null diff --git a/users/app/models/service_level.rb b/users/app/models/service_level.rb deleted file mode 100644 index 299aaf1..0000000 --- a/users/app/models/service_level.rb +++ /dev/null @@ -1,19 +0,0 @@ -class ServiceLevel - - def initialize(attributes = {}) - @id = attributes[:id] || APP_CONFIG[:default_service_level] - end - - def self.authenticated_select_options - APP_CONFIG[:service_levels].map { |id,config_hash| [config_hash[:description], id] if config_hash[:name] != 'anonymous'}.compact - end - - def id - @id - end - - def config_hash - APP_CONFIG[:service_levels][@id] - end - -end diff --git a/users/app/models/unauthenticated_user.rb b/users/app/models/unauthenticated_user.rb deleted file mode 100644 index 0fc17d2..0000000 --- a/users/app/models/unauthenticated_user.rb +++ /dev/null @@ -1,6 +0,0 @@ -# The nil object for the user class -class UnauthenticatedUser < Object - - # will probably want something here to return service level as APP_CONFIG[:service_levels][0] but not sure how will be accessing. - -end diff --git a/users/app/views/.gitkeep b/users/app/views/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/app/views/.gitkeep +++ /dev/null diff --git a/users/app/views/sessions/new.html.haml b/users/app/views/sessions/new.html.haml deleted file mode 100644 index 771dc97..0000000 --- a/users/app/views/sessions/new.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.span1 -.span9 - = render :partial => 'users/warnings' - %h2=t :login - = simple_form_for [:api, @session], :validate => true, :html => { :id => :new_session, :class => 'form-horizontal' } do |f| - = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username } - = f.input :password, :required => false, :input_html => { :id => :srp_password } - .form-actions - = f.button :submit, :value => t(:login), :class => 'btn-primary' - = link_to t(:cancel), home_path, :class => 'btn' diff --git a/users/config/routes.rb b/users/config/routes.rb deleted file mode 100644 index 736b283..0000000 --- a/users/config/routes.rb +++ /dev/null @@ -1,28 +0,0 @@ -Rails.application.routes.draw do - - namespace "api", { module: "v1", - path: "/1/", - defaults: {format: 'json'} } do - resources :sessions, :only => [:new, :create, :update] - delete "logout" => "sessions#destroy", :as => "logout" - resources :users, :only => [:create, :update, :destroy, :index] - end - - scope "(:locale)", :locale => MATCH_LOCALE do - get "login" => "sessions#new", :as => "login" - delete "logout" => "sessions#destroy", :as => "logout" - - get "signup" => "users#new", :as => "signup" - resources :users, :except => [:create, :update] do - # resource :email_settings, :only => [:edit, :update] - # resources :email_aliases, :only => [:destroy], :id => /.*/ - post 'deactivate', on: :member - post 'enable', on: :member - end - end - - get "/.well-known/host-meta" => 'webfinger#host_meta' - get "/webfinger" => 'webfinger#search' - get "/key/:login" => 'keys#show' - -end diff --git a/users/leap_web_users.gemspec b/users/leap_web_users.gemspec deleted file mode 100644 index 7d1f220..0000000 --- a/users/leap_web_users.gemspec +++ /dev/null @@ -1,22 +0,0 @@ -$:.push File.expand_path("../lib", __FILE__) - -require File.expand_path('../../lib/leap_web/version.rb', __FILE__) - -# Describe your gem and declare its dependencies: -Gem::Specification.new do |s| - s.name = "leap_web_users" - s.version = LeapWeb::VERSION - s.authors = ["Azul"] - s.email = ["azul@leap.se"] - s.homepage = "http://www.leap.se" - s.summary = "User registration and authorization for the leap platform" - s.description = "This this plugin for the leap platform provides user signup and login. It uses Secure Remote Password for the authentication." - - s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile"] - s.test_files = Dir["test/**/*"] - - s.add_dependency "leap_web_core", LeapWeb::VERSION - - s.add_dependency "ruby-srp", "~> 0.2.1" - s.add_dependency "rails_warden" -end diff --git a/users/lib/leap_web_users.rb b/users/lib/leap_web_users.rb deleted file mode 100644 index e1b7b1f..0000000 --- a/users/lib/leap_web_users.rb +++ /dev/null @@ -1,4 +0,0 @@ -require "leap_web_users/engine" - -module LeapWebUsers -end diff --git a/users/lib/leap_web_users/engine.rb b/users/lib/leap_web_users/engine.rb deleted file mode 100644 index f8ed71c..0000000 --- a/users/lib/leap_web_users/engine.rb +++ /dev/null @@ -1,16 +0,0 @@ -# thou shall require all your dependencies in an engine. -require "leap_web_core" -require "leap_web_core/ui_dependencies" -require "rails_warden" -require "ruby-srp" - -require "warden/session_serializer" -require "warden/strategies/secure_remote_password" - -require "webfinger" - -module LeapWebUsers - class Engine < ::Rails::Engine - - end -end diff --git a/users/lib/tasks/leap_web_users_tasks.rake b/users/lib/tasks/leap_web_users_tasks.rake deleted file mode 100644 index 3d0649c..0000000 --- a/users/lib/tasks/leap_web_users_tasks.rake +++ /dev/null @@ -1,4 +0,0 @@ -# desc "Explaining what the task does" -# task :leap_web_users do -# # Task goes here -# end diff --git a/users/script/rails b/users/script/rails deleted file mode 100755 index ee08520..0000000 --- a/users/script/rails +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby1.8 -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -ENGINE_ROOT = File.expand_path('../..', __FILE__) -ENGINE_PATH = File.expand_path('../../lib/leap_web_users/engine', __FILE__) - -require 'rails/all' -require 'rails/engine/commands' diff --git a/users/test/factories.rb b/users/test/factories.rb deleted file mode 100644 index ae00d43..0000000 --- a/users/test/factories.rb +++ /dev/null @@ -1,34 +0,0 @@ -FactoryGirl.define do - - factory :user do - login { Faker::Internet.user_name } - password_verifier "1234ABCD" - password_salt "4321AB" - - factory :user_with_settings do - email_forward { Faker::Internet.email } - email_aliases_attributes do - {:a => Faker::Internet.user_name + '@' + APP_CONFIG[:domain]} - end - end - - factory :admin_user do - after(:build) do |admin| - admin.stubs(:is_admin?).returns(true) - end - end - end - - factory :token do - user - end - - factory :pgp_key do - keyblock <<-EOPGP ------BEGIN PGP PUBLIC KEY BLOCK----- -+Dummy+PGP+KEY+++Dummy+PGP+KEY+++Dummy+PGP+KEY+++Dummy+PGP+KEY+ -#{SecureRandom.base64(4032)} ------END PGP PUBLIC KEY BLOCK----- - EOPGP - end -end diff --git a/users/test/fixtures/.gitkeep b/users/test/fixtures/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/test/fixtures/.gitkeep +++ /dev/null diff --git a/users/test/functional/.gitkeep b/users/test/functional/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/test/functional/.gitkeep +++ /dev/null diff --git a/users/test/integration/.gitkeep b/users/test/integration/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/test/integration/.gitkeep +++ /dev/null diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb deleted file mode 100644 index edd0859..0000000 --- a/users/test/integration/api/account_flow_test.rb +++ /dev/null @@ -1,136 +0,0 @@ -require 'test_helper' -require_relative 'rack_test' - -class AccountFlowTest < RackTest - - setup do - @login = "integration_test_user" - Identity.find_by_address(@login + '@' + APP_CONFIG[:domain]).tap{|i| i.destroy if i} - User.find_by_login(@login).tap{|u| u.destroy if u} - @password = "srp, verify me!" - @srp = SRP::Client.new @login, :password => @password - @user_params = { - :login => @login, - :password_verifier => @srp.verifier.to_s(16), - :password_salt => @srp.salt.to_s(16) - } - post 'http://api.lvh.me:3000/1/users.json', :user => @user_params - @user = User.find_by_login(@login) - end - - teardown do - if @user.reload - @user.identity.destroy - @user.destroy - end - Warden.test_reset! - end - - # this test wraps the api and implements the interface the ruby-srp client. - def handshake(login, aa) - post "http://api.lvh.me:3000/1/sessions.json", - :login => login, - 'A' => aa, - :format => :json - response = JSON.parse(last_response.body) - if response['errors'] - raise RECORD_NOT_FOUND.new(response['errors']) - else - return response['B'] - end - end - - def validate(m) - put "http://api.lvh.me:3000/1/sessions/" + @login + '.json', - :client_auth => m, - :format => :json - return JSON.parse(last_response.body) - end - - test "signup response" do - assert_json_response :login => @login, :ok => true - assert last_response.successful? - end - - test "signup and login with srp via api" do - server_auth = @srp.authenticate(self) - assert last_response.successful? - assert_nil server_auth["errors"] - assert server_auth["M2"] - end - - test "signup and wrong password login attempt" do - srp = SRP::Client.new @login, :password => "wrong password" - server_auth = srp.authenticate(self) - assert_json_error "base" => "Not a valid username/password combination" - assert !last_response.successful? - assert_nil server_auth["M2"] - end - - test "signup and wrong username login attempt" do - srp = SRP::Client.new "wrong_login", :password => @password - server_auth = nil - assert_raises RECORD_NOT_FOUND do - server_auth = srp.authenticate(self) - end - assert_json_error "base" => "Not a valid username/password combination" - assert !last_response.successful? - assert_nil server_auth - end - - test "update password via api" do - @srp.authenticate(self) - @password = "No! Verify me instead." - @srp = SRP::Client.new @login, :password => @password - @user_params = { - # :login => @login, - :password_verifier => @srp.verifier.to_s(16), - :password_salt => @srp.salt.to_s(16) - } - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', - :user => @user_params, - :format => :json - server_auth = @srp.authenticate(self) - assert last_response.successful? - assert_nil server_auth["errors"] - assert server_auth["M2"] - end - - test "prevent changing login without changing password_verifier" do - server_auth = @srp.authenticate(self) - original_login = @user.login - new_login = 'zaph' - User.find_by_login(new_login).try(:destroy) - Identity.by_address.key(new_login + '@' + APP_CONFIG[:domain]).each do |identity| - identity.destroy - end - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:login => new_login}, :format => :json - assert last_response.successful? - # does not change login if no password_verifier is present - assert_equal original_login, @user.login - end - - test "upload pgp key" do - server_auth = @srp.authenticate(self) - key = FactoryGirl.build :pgp_key - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => key}, :format => :json - assert_equal key, Identity.for(@user).keys[:pgp] - end - - # eventually probably want to remove most of this into a non-integration - # functional test - test "prevent uploading invalid key" do - server_auth = @srp.authenticate(self) - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => :blah}, :format => :json - assert_nil Identity.for(@user).keys[:pgp] - end - - test "prevent emptying public key" do - server_auth = @srp.authenticate(self) - key = FactoryGirl.build :pgp_key - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => key}, :format => :json - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => ""}, :format => :json - assert_equal key, Identity.for(@user).keys[:pgp] - end - -end diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb deleted file mode 100644 index fb761e5..0000000 --- a/users/test/integration/api/login_test.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'test_helper' -require_relative 'rack_test' - -class AccountFlowTest < RackTest - - setup do - @login = "integration_test_user" - end - - test "require json requests" do - put "http://api.lvh.me:3000/1/sessions/" + @login, - :client_auth => "This is not a valid login anyway" - assert_json_error login: I18n.t(:all_strategies_failed) - end - -end diff --git a/users/test/integration/api/rack_test.rb b/users/test/integration/api/rack_test.rb deleted file mode 100644 index 9a69f52..0000000 --- a/users/test/integration/api/rack_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RackTest < ActiveSupport::TestCase - include Rack::Test::Methods - include Warden::Test::Helpers - include LeapWebCore::AssertResponses - - def app - OUTER_APP - end -end diff --git a/users/test/integration/browser/session_test.rb b/users/test/integration/browser/session_test.rb deleted file mode 100644 index 3a41b3a..0000000 --- a/users/test/integration/browser/session_test.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'test_helper' - -class SessionTest < BrowserIntegrationTest - - setup do - @username, password = submit_signup - end - - teardown do - user = User.find_by_login(@username) - id = user.identity - id.destroy - user.destroy - end - - test "valid session" do - assert page.has_content?("Welcome #{@username}") - end - - test "expired session" do - assert page.has_content?("Welcome #{@username}") - pretend_now_is(Time.now + 40.minutes) do - visit '/' - assert page.has_no_content?("Welcome #{@username}") - end - end -end diff --git a/users/test/integration/navigation_test.rb b/users/test/integration/navigation_test.rb deleted file mode 100644 index eec8c0e..0000000 --- a/users/test/integration/navigation_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'test_helper' - -class NavigationTest < ActionDispatch::IntegrationTest - - # test "the truth" do - # assert true - # end -end - diff --git a/users/test/support/integration_test_helper.rb b/users/test/support/integration_test_helper.rb deleted file mode 100644 index 51e47c6..0000000 --- a/users/test/support/integration_test_helper.rb +++ /dev/null @@ -1,12 +0,0 @@ -module IntegrationTestHelper - def submit_signup(username = nil, password = nil) - username ||= "test_#{SecureRandom.urlsafe_base64}".downcase - password ||= SecureRandom.base64 - visit '/users/new' - fill_in 'Username', with: username - fill_in 'Password', with: password - fill_in 'Password confirmation', with: password - click_on 'Sign Up' - return username, password - end -end diff --git a/users/test/test_helper.rb b/users/test/test_helper.rb deleted file mode 100644 index 52dff53..0000000 --- a/users/test/test_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -ENV["RAILS_ENV"] = "test" -require File.expand_path('../../../test/dummy/config/environment', __FILE__) -require 'rails/test_help' -require 'mocha/setup' - -Rails.backtrace_cleaner.remove_silencers! - -# Load support files -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } diff --git a/users/test/unit/.gitkeep b/users/test/unit/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/users/test/unit/.gitkeep +++ /dev/null diff --git a/users/test/unit/email_test.rb b/users/test/unit/email_test.rb deleted file mode 100644 index 7cfbc84..0000000 --- a/users/test/unit/email_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'test_helper' - -class EmailTest < ActiveSupport::TestCase - - test "valid format" do - email = Email.new(email_string) - assert email.valid? - end - - test "validates format" do - email = Email.new("email") - assert !email.valid? - assert_equal ["needs to be a valid email address"], email.errors[:email] - end - - def email_string - @email_string ||= Faker::Internet.email - end -end diff --git a/users/test/unit/unauthorized_user_test.rb b/users/test/unit/unauthorized_user_test.rb deleted file mode 100644 index 5b96ae1..0000000 --- a/users/test/unit/unauthorized_user_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'test_helper' - -class UnauthorizedUserTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end |