mirror of
https://github.com/discourse/discourse.git
synced 2024-12-15 22:42:13 +08:00
SECURITY: Remove disposable invite feature
This commit is contained in:
parent
b0be304591
commit
7ad2703397
|
@ -7,8 +7,8 @@ class InvitesController < ApplicationController
|
||||||
skip_before_filter :redirect_to_login_if_required
|
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_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_new_registrations_allowed, only: [:show, :perform_accept_invitation]
|
||||||
before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
|
before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_now
|
expires_now
|
||||||
|
@ -104,42 +104,6 @@ class InvitesController < ApplicationController
|
||||||
end
|
end
|
||||||
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
|
def destroy
|
||||||
params.require(:email)
|
params.require(:email)
|
||||||
|
|
||||||
|
|
|
@ -149,24 +149,6 @@ class Invite < ActiveRecord::Base
|
||||||
invite
|
invite
|
||||||
end
|
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)
|
def self.get_group_ids(group_names)
|
||||||
group_ids = []
|
group_ids = []
|
||||||
if group_names
|
if group_names
|
||||||
|
|
|
@ -647,8 +647,6 @@ Discourse::Application.routes.draw do
|
||||||
post "invites/reinvite" => "invites#resend_invite"
|
post "invites/reinvite" => "invites#resend_invite"
|
||||||
post "invites/reinvite-all" => "invites#resend_all_invites"
|
post "invites/reinvite-all" => "invites#resend_all_invites"
|
||||||
post "invites/link" => "invites#create_invite_link"
|
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"
|
delete "invites" => "invites#destroy"
|
||||||
put "invites/show/:id" => "invites#perform_accept_invitation", as: 'perform_accept_invite'
|
put "invites/show/:id" => "invites#perform_accept_invitation", as: 'perform_accept_invite'
|
||||||
|
|
||||||
|
|
|
@ -257,10 +257,6 @@ class Guardian
|
||||||
user.admin?
|
user.admin?
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_create_disposable_invite?(user)
|
|
||||||
user.admin?
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_send_multiple_invites?(user)
|
def can_send_multiple_invites?(user)
|
||||||
user.staff?
|
user.staff?
|
||||||
end
|
end
|
||||||
|
|
|
@ -288,109 +288,6 @@ describe InvitesController do
|
||||||
end
|
end
|
||||||
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
|
context '.resend_invite' do
|
||||||
|
|
||||||
it 'requires you to be logged in' do
|
it 'requires you to be logged in' do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user