diff --git a/app/controllers/logins_controller.rb b/app/controllers/logins_controller.rb deleted file mode 100644 index e7a5daf..0000000 --- a/app/controllers/logins_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -class LoginsController < ApplicationController - - def new; end - - def create - email = params[:email].strip - - if login_service.login(email) - redirect_to sent_login_path, flash: { email_recipient: email } - else - @invalid_email = true - render :new - end - end - - def sent - @email_recipient = flash[:email_recipient] - redirect_to new_login_path unless @email_recipient - end - - private - - def login_service - EmailLoginService.new - end - -end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index c05728f..78d4a5d 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,44 +1,8 @@ class SessionsController < ApplicationController - def new - end - - def create - user = login_service.validate(params[:token].to_s.strip) - - if user - self.current_user = user - redirect_to_profile(user) - else - render :error - end - end - def destroy self.current_user = nil redirect_to root_path, notice: "See you later!" end - private - - def login_service - EmailLoginService.new - end - - def redirect_to_profile(user) - if user.username - redirect_back_or_to profile_path(user), notice: login_notice(user) - else - redirect_to new_username_path, notice: login_notice(user) - end - end - - def login_notice(user) - if user.first_login? - "Welcome to asciinema!" - else - "Welcome back!" - end - end - end diff --git a/app/mailers/.gitkeep b/app/mailers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/mailers/notifications.rb b/app/mailers/notifications.rb deleted file mode 100644 index c0edcb6..0000000 --- a/app/mailers/notifications.rb +++ /dev/null @@ -1,14 +0,0 @@ -class Notifications < ActionMailer::Base - default from: CFG.smtp_from_address - - def self.delay_login_request(user_id, token) - delay.login_request(user_id, token) - end - - def login_request(user_id, token) - user = User.find(user_id) - @login_url = login_token_url(token) - - mail to: user.email - end -end diff --git a/app/services/email_login_service.rb b/app/services/email_login_service.rb deleted file mode 100644 index 3ce3995..0000000 --- a/app/services/email_login_service.rb +++ /dev/null @@ -1,21 +0,0 @@ -class EmailLoginService - - def login(email) - user = User.for_email!(email) - expiring_token = ExpiringToken.create_for_user(user) - Notifications.delay_login_request(expiring_token.user_id, expiring_token.token) - true - rescue User::InvalidEmailError - false - end - - def validate(token) - expiring_token = ExpiringToken.active_for_token(token) - - if expiring_token - expiring_token.use! - expiring_token.user - end - end - -end diff --git a/app/views/logins/new.html.slim b/app/views/logins/new.html.slim deleted file mode 100644 index 5192666..0000000 --- a/app/views/logins/new.html.slim +++ /dev/null @@ -1,33 +0,0 @@ -.container - .row - .col-md-6 - h1 - span class="glyphicon glyphicon-user" - | Log in - - br - - p Log in to asciinema.org using your email address: - - = form_tag login_path, class: "form-inline login-form" do - .form-group - input.form-control.email name="email" type="email" placeholder="Enter email" data-behavior="focus" - button.btn.btn-primary type="submit" Log in - - - if @invalid_email - br - p.text-danger This email address doesn't seem to be correct. - - .col-md-6 - h1 - span class="glyphicon glyphicon-info-sign" - | First time here? - - br - - p - | asciinema.org uses email-based, passwordless login process. - Whether you're here for the first time or you're coming back, - just enter your email address and you'll get sent a login link. - If you're doing this for the first time then your user account will - automatically get created. diff --git a/app/views/logins/sent.html.slim b/app/views/logins/sent.html.slim deleted file mode 100644 index 486f978..0000000 --- a/app/views/logins/sent.html.slim +++ /dev/null @@ -1,14 +0,0 @@ -.container - .row - .col-md-12 - h1 You're almost there! - - br - - p - | We sent a login link to - strong = @email_recipient - ' . Please click on the link to login to your account. - ' The link is valid for next 15 minutes. - - p If it doesn't arrive, check your spam folder, or #{link_to 'enter your email again', new_login_path} to get another login link. diff --git a/app/views/notifications/login_request.text.erb b/app/views/notifications/login_request.text.erb deleted file mode 100644 index ff42e61..0000000 --- a/app/views/notifications/login_request.text.erb +++ /dev/null @@ -1,7 +0,0 @@ -Hello, - -Click the following link to log in to asciinema.org: - - <%= @login_url %> - -If you did not initiate this request, just ignore this email. The request will expire shortly. diff --git a/app/views/sessions/error.html.slim b/app/views/sessions/error.html.slim deleted file mode 100644 index f31a785..0000000 --- a/app/views/sessions/error.html.slim +++ /dev/null @@ -1,15 +0,0 @@ -.container - .row - .col-md-12 - h1 Invalid login link - - br - - p Your login link is either invalid or has expired. - - p - ' Login links are valid for 15 minutes. If you think yours might have expired then - a href=new_login_path request a new login link - | . - - p If you're copy-pasting the link check if the link hasn't been corrupted by your email client's message formatting. diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb deleted file mode 100644 index b495ee8..0000000 --- a/app/views/sessions/new.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -
-
-
-

Welcome.

-
-

Click the button and you're in!

-
- <%= form_tag method: :post do %> - - <% end %> -
-
-
diff --git a/config/application.rb b/config/application.rb index 78162c7..f347db9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -60,15 +60,5 @@ module Asciinema action: "unauthenticated_user" ) end - - config.action_mailer.default_url_options = { - protocol: CFG.url_scheme, - host: CFG.url_host, - port: CFG.url_port - } - - if CFG.smtp_settings - config.action_mailer.smtp_settings = CFG.smtp_settings - end end end diff --git a/config/cfg.rb b/config/cfg.rb index ac3118d..d4e6f7a 100644 --- a/config/cfg.rb +++ b/config/cfg.rb @@ -19,8 +19,6 @@ module Asciinema attribute :session_encryption_salt, String, default: 'encrypted cookie' attribute :session_signing_salt, String, default: 'signed encrypted cookie' attribute :admin_ids, Array[Integer] - attribute :smtp_settings, Hash - attribute :smtp_from_address, String def home_asciicast if home_asciicast_id @@ -33,10 +31,6 @@ module Asciinema def ssl? url_scheme == 'https' end - - def smtp_from_address - super || "asciinema " - end end end diff --git a/config/routes.rb b/config/routes.rb index d2197f5..c4f23d0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,14 +18,7 @@ Rails.application.routes.draw do get "/oembed" => "oembed#show", as: :oembed - resource :login, only: [:new, :create] do - get :sent - end - - get "/login" => redirect("/login/new") - - get "/login/:token" => "sessions#new", as: :login_token - post "/login/:token" => "sessions#create" + get "/login/new" => redirect("/not-gonna-happen"), as: :new_login # define new_login_path get "/logout" => "sessions#destroy" resources :api_tokens, only: [:create, :destroy] diff --git a/spec/controllers/logins_controller_spec.rb b/spec/controllers/logins_controller_spec.rb deleted file mode 100644 index a8589e2..0000000 --- a/spec/controllers/logins_controller_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'rails_helper' - -describe LoginsController do - - describe "#new" do - subject { get :new } - - it "renders 'new' template" do - should render_template('new') - end - end - - describe "#create" do - subject { post :create, email: "foo@example.com" } - - let(:login_service) { double(:login_service) } - - before do - allow(controller).to receive(:login_service) { login_service } - allow(login_service).to receive(:login).with("foo@example.com") { login_success } - end - - context "when login succeeds" do - let(:login_success) { true } - - it "sets email_recipient in flash" do - subject - expect(flash[:email_recipient]).to eq("foo@example.com") - end - - it "redirects to 'sent' page" do - should redirect_to(sent_login_path) - end - end - - context "when login fails" do - let(:login_success) { false } - - it "renders 'new' template" do - should render_template('new') - end - end - end - - describe "#sent" do - subject { get :sent, {}, {}, { email_recipient: email_recipient } } - - context "when email_recipient is set in flash" do - let(:email_recipient) { "foo@example.com" } - - it "renders 'sent' template" do - should render_template('sent') - end - end - - context "when email_recipient is not set in flash" do - let(:email_recipient) { nil } - - it "redirects to login page" do - should redirect_to(new_login_path) - end - end - end - -end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 3d9d988..3217425 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -2,75 +2,6 @@ require 'rails_helper' describe SessionsController do - describe "#new" do - subject { get :new, token: 'the-to-ken' } - - before do - subject - end - - it "displays button" do - should render_template('new') - end - end - - describe "#create" do - subject { post :create, token: 'the-to-ken' } - - let(:login_service) { double(:login_service) } - - before do - allow(controller).to receive(:login_service) { login_service } - allow(login_service).to receive(:validate).with('the-to-ken') { user } - end - - context "when token is successfully validated" do - let(:user) { stub_model(User) } - - before do - allow(controller).to receive(:current_user=) - - subject - end - - it "sets the current_user" do - expect(controller).to have_received(:current_user=).with(user) - end - - it "sets a notice" do - expect(flash[:notice]).to_not be_blank - end - - context "when user has username" do - let(:user) { User.new(username: "foobar") } - - it "redirects to user's profile" do - should redirect_to(public_profile_path(username: "foobar")) - end - end - - context "when user has no username" do - let(:user) { User.new } - - it "redirects to new username page" do - should redirect_to(new_username_path) - end - end - end - - context "when token is not validated" do - let(:user) { nil } - - before do - subject - end - - it "displays error" do - should render_template('error') - end - end - end - describe "#destroy" do before do allow(controller).to receive(:current_user=) diff --git a/spec/features/tokens_spec.rb b/spec/features/tokens_spec.rb deleted file mode 100644 index ef27f07..0000000 --- a/spec/features/tokens_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'rails_helper' - -feature "Recorder tokens management" do - - let!(:user) { create(:user) } - - scenario 'Listing tokens when user has none' do - login_as user - visit edit_user_path - - expect(page).to have_content('asciinema auth') - end - - scenario 'Listing tokens when user has some' do - api_token = create(:api_token, user: user) - - login_as user - visit edit_user_path - - expect(page).to have_content(api_token.token) - expect(page).to have_link('Revoke') - expect(page).to have_no_content('asciinema auth') - end - - scenario 'Revoking a token' do - api_token = create(:api_token, user: user) - - login_as user - visit edit_user_path - - click_on "Revoke" - - expect(page).to have_content(api_token.token) - expect(page).to have_no_link('Revoke') - end - -end - diff --git a/spec/features/user_spec.rb b/spec/features/user_spec.rb index 36f9025..8096ed9 100644 --- a/spec/features/user_spec.rb +++ b/spec/features/user_spec.rb @@ -13,20 +13,4 @@ feature "User's profile" do expect(page).to have_selector('.asciicast-list .play-button') end - scenario 'Updating profile', js: true, unstable: true do - login_as user - - within 'header' do - click_on user.username - click_on 'Settings' - end - - fill_in 'Username', with: 'batman' - click_on 'Save' - - within 'header' do - expect(page).to have_content('batman') - end - end - end diff --git a/spec/mailers/notifications_spec.rb b/spec/mailers/notifications_spec.rb deleted file mode 100644 index 3e47092..0000000 --- a/spec/mailers/notifications_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require "rails_helper" - -RSpec.describe Notifications, :type => :mailer do - describe "login_request" do - let(:mail) { Notifications.login_request(user.id, "the-to-ken") } - let(:user) { create(:user, email: "foo@example.com") } - - it "renders the headers" do - expect(mail.subject).to eq("Login request") - expect(mail.to).to eq(["foo@example.com"]) - expect(mail.from).to eq(["hello@localhost"]) - end - - it "renders the body" do - expect(mail.body.encoded).to match("Click") - expect(mail.body.encoded).to match(login_token_path("the-to-ken")) - end - end - -end diff --git a/spec/services/email_login_service_spec.rb b/spec/services/email_login_service_spec.rb deleted file mode 100644 index aa2e658..0000000 --- a/spec/services/email_login_service_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -require 'rails_helper' - -describe EmailLoginService do - - let(:creator) { described_class.new } - - describe "#login" do - subject { creator.login(email) } - - let(:email) { "me@example.com" } - - context "when given email is blank" do - let(:email) { nil } - - it "returns false" do - expect(subject).to be(false) - end - end - - context "when given email is invalid" do - let(:email) { "oops" } - - it "returns false" do - expect(subject).to be(false) - end - end - - context "when there's no user with given email" do - it "creates a user with given email" do - expect { subject }.to change(User, :count).by(1) - expect(User.last.email).to eq("me@example.com") - end - - it "creates an expiring token for new user" do - expect { subject }.to change(ExpiringToken, :count).by(1) - expect(ExpiringToken.last.user).to eq(User.last) - end - - it "sends login email" do - expect(Notifications).to receive(:delay_login_request) - subject - end - - it "returns true" do - expect(subject).to be(true) - end - end - - context "when there's a user with given email" do - let!(:user) { create(:user, email: "me@example.com") } - - it "creates an expiring token this user" do - expect { subject }.to change(ExpiringToken, :count).by(1) - expect(ExpiringToken.last.user).to eq(user) - end - - it "sends login email" do - expect(Notifications).to receive(:delay_login_request) - subject - end - - it "returns true" do - expect(subject).to be(true) - end - end - end - - describe "#validate" do - subject { creator.validate(token) } - - let(:token) { "the-to-ken" } - - context "when given token is valid" do - let!(:expiring_token) { create(:expiring_token, user: user, token: token) } - let(:user) { create(:user) } - - it "marks token as used" do - now = Time.now - - Timecop.freeze(now) do - subject - end - - expect(expiring_token.reload.used_at.to_i).to eq(now.to_i) - end - - it "returns user associated with the token" do - expect(subject).to eq(user) - end - end - - context "when given token is invalid" do - it "returns nil" do - expect(subject).to be(nil) - end - end - end - -end diff --git a/spec/support/authentication.rb b/spec/support/authentication.rb index f112d42..afd5d6d 100644 --- a/spec/support/authentication.rb +++ b/spec/support/authentication.rb @@ -17,16 +17,6 @@ module Asciinema controller.current_user = nil end end - - module FeatureHelpers - def login_as(user) - visit new_login_path - fill_in :email, with: user.email - click_button 'Log in' - visit "/login/#{user.expiring_tokens.last.token}" - click_button "Log in" - end - end end end @@ -36,5 +26,4 @@ RSpec.configure do |config| end config.include Asciinema::Test::ControllerHelpers, type: :controller - config.include Asciinema::Test::FeatureHelpers, type: :feature end