From 7ad2703397b15fec032fb2201419a144bfce348e Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 7 Jul 2017 20:24:39 -0400 Subject: [PATCH] SECURITY: Remove disposable invite feature --- app/controllers/invites_controller.rb | 40 +------- app/models/invite.rb | 18 ---- config/routes.rb | 2 - lib/guardian.rb | 4 - spec/controllers/invites_controller_spec.rb | 103 -------------------- 5 files changed, 2 insertions(+), 165 deletions(-) diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 1693d1616a7..d6a207b5026 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -7,8 +7,8 @@ class InvitesController < ApplicationController skip_before_filter :redirect_to_login_if_required before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :resend_invite, :resend_all_invites, :upload_csv] - before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation, :redeem_disposable_invite] - before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite] + before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation] + before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation] def show expires_now @@ -104,42 +104,6 @@ class InvitesController < ApplicationController end end - def create_disposable_invite - guardian.ensure_can_create_disposable_invite!(current_user) - params.permit(:username, :email, :quantity, :group_names) - - username_or_email = params[:username] ? fetch_username : fetch_email - user = User.find_by_username_or_email(username_or_email) - - # generate invite tokens - invite_tokens = Invite.generate_disposable_tokens(user, params[:quantity], params[:group_names]) - - render_json_dump(invite_tokens) - end - - def redeem_disposable_invite - params.require(:email) - params.permit(:username, :name, :topic) - params[:email] = params[:email].split(' ').join('+') - - invite = Invite.find_by(invite_key: params[:token]) - - if invite.present? - user = Invite.redeem_from_token(params[:token], params[:email], params[:username], params[:name], params[:topic].to_i) - if user.present? - log_on_user(user) - post_process_invite(user) - topic = invite.topics.first - if topic.present? - redirect_to path("#{topic.relative_url}") - return - end - end - end - - redirect_to path("/") - end - def destroy params.require(:email) diff --git a/app/models/invite.rb b/app/models/invite.rb index 3b76c456db3..bd2c68c9104 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -149,24 +149,6 @@ class Invite < ActiveRecord::Base invite end - # generate invite tokens without email - def self.generate_disposable_tokens(invited_by, quantity=nil, group_names=nil) - invite_tokens = [] - quantity ||= 1 - group_ids = get_group_ids(group_names) - - quantity.to_i.times do - invite = Invite.create!(invited_by: invited_by) - group_ids = group_ids - invite.invited_groups.pluck(:group_id) - group_ids.each do |group_id| - invite.invited_groups.create!(group_id: group_id) - end - invite_tokens.push(invite.invite_key) - end - - invite_tokens - end - def self.get_group_ids(group_names) group_ids = [] if group_names diff --git a/config/routes.rb b/config/routes.rb index 6b94848c0fe..36c265da182 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -647,8 +647,6 @@ Discourse::Application.routes.draw do post "invites/reinvite" => "invites#resend_invite" post "invites/reinvite-all" => "invites#resend_all_invites" post "invites/link" => "invites#create_invite_link" - post "invites/disposable" => "invites#create_disposable_invite" - get "invites/redeem/:token" => "invites#redeem_disposable_invite" delete "invites" => "invites#destroy" put "invites/show/:id" => "invites#perform_accept_invitation", as: 'perform_accept_invite' diff --git a/lib/guardian.rb b/lib/guardian.rb index 83513c6eb27..8d4069328ad 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -257,10 +257,6 @@ class Guardian user.admin? end - def can_create_disposable_invite?(user) - user.admin? - end - def can_send_multiple_invites?(user) user.staff? end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 90795927759..82a97d87ffc 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -288,109 +288,6 @@ describe InvitesController do end end - context '.create_disposable_invite' do - it 'requires you to be logged in' do - expect { - post :create, email: 'jake@adventuretime.ooo' - }.to raise_error(Discourse::NotLoggedIn) - end - - context 'while logged in as normal user' do - let(:user) { Fabricate(:user) } - - it "does not create disposable invitation" do - log_in - post :create_disposable_invite, email: user.email - expect(response).not_to be_success - end - end - - context 'while logged in as admin' do - before do - log_in(:admin) - end - let(:user) { Fabricate(:user) } - - it "creates disposable invitation" do - post :create_disposable_invite, email: user.email - expect(response).to be_success - expect(Invite.where(invited_by_id: user.id).count).to eq(1) - end - - it "creates multiple disposable invitations" do - post :create_disposable_invite, email: user.email, quantity: 10 - expect(response).to be_success - expect(Invite.where(invited_by_id: user.id).count).to eq(10) - end - - it "allows group invite" do - group = Fabricate(:group) - post :create_disposable_invite, email: user.email, group_names: group.name - expect(response).to be_success - expect(Invite.find_by(invited_by_id: user.id).invited_groups.count).to eq(1) - end - - it "allows multiple group invite" do - group_1 = Fabricate(:group, name: "security") - group_2 = Fabricate(:group, name: "support") - post :create_disposable_invite, email: user.email, group_names: "security,support" - expect(response).to be_success - expect(Invite.find_by(invited_by_id: user.id).invited_groups.count).to eq(2) - end - - end - - end - - context '.redeem_disposable_invite' do - - context 'with an invalid invite token' do - before do - get :redeem_disposable_invite, email: "name@example.com", token: "doesn't exist" - end - - it "redirects to the root" do - expect(response).to redirect_to("/") - end - - it "should not change the session" do - expect(session[:current_user_id]).to be_blank - end - end - - context 'with a valid invite token' do - let(:topic) { Fabricate(:topic) } - let(:invitee) { Fabricate(:user) } - let(:invite) { Invite.create!(invited_by: invitee) } - - it 'converts "space" to "+" in email parameter' do - Invite.expects(:redeem_from_token).with(invite.invite_key, "fname+lname@example.com", nil, nil, topic.id) - get :redeem_disposable_invite, email: "fname lname@example.com", token: invite.invite_key, topic: topic.id - end - - it 'redeems the invite' do - Invite.expects(:redeem_from_token).with(invite.invite_key, "name@example.com", nil, nil, topic.id) - get :redeem_disposable_invite, email: "name@example.com", token: invite.invite_key, topic: topic.id - end - - context 'when redeem returns a user' do - let(:user) { Fabricate(:user) } - - before do - Invite.expects(:redeem_from_token).with(invite.invite_key, user.email, nil, nil, topic.id).returns(user) - get :redeem_disposable_invite, email: user.email, token: invite.invite_key, topic: topic.id - end - - it 'logs in user' do - expect(session[:current_user_id]).to eq(user.id) - end - - end - - end - - end - context '.resend_invite' do it 'requires you to be logged in' do