مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2025-12-01 05:43:04 +00:00
initial commit from appmail
هذا الالتزام موجود في:
45
app/controllers/address_endpoints_controller.rb
Normal file
45
app/controllers/address_endpoints_controller.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
class AddressEndpointsController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @address_endpoint = @server.address_endpoints.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@address_endpoints = @server.address_endpoints.order(:address).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@address_endpoint = @server.address_endpoints.build
|
||||
end
|
||||
|
||||
def create
|
||||
@address_endpoint = @server.address_endpoints.build(safe_params)
|
||||
if @address_endpoint.save
|
||||
flash[:notice] = params[:return_notice] if params[:return_notice].present?
|
||||
redirect_to_with_json [:return_to, [organization, @server, :address_endpoints]]
|
||||
else
|
||||
render_form_errors 'new', @address_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @address_endpoint.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :address_endpoints]
|
||||
else
|
||||
render_form_errors 'edit', @address_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@address_endpoint.destroy
|
||||
redirect_to_with_json [organization, @server, :address_endpoints]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:address_endpoint).permit(:address)
|
||||
end
|
||||
|
||||
end
|
||||
10
app/controllers/admin/organizations_controller.rb
Normal file
10
app/controllers/admin/organizations_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class Admin::OrganizationsController < ApplicationController
|
||||
|
||||
before_action :admin_required
|
||||
before_action { params[:id] && @organization = Organization.find_by_permalink!(params[:id]) }
|
||||
|
||||
def index
|
||||
@organizations = Organization.order(:created_at => :desc).includes(:owner).page(params[:page])
|
||||
end
|
||||
|
||||
end
|
||||
10
app/controllers/admin/stats_controller.rb
Normal file
10
app/controllers/admin/stats_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
class Admin::StatsController < ApplicationController
|
||||
|
||||
before_action :admin_required
|
||||
|
||||
def stats
|
||||
@stats = Statistic.global
|
||||
@queue_size = QueuedMessage.unlocked.retriable.count
|
||||
end
|
||||
|
||||
end
|
||||
131
app/controllers/application_controller.rb
Normal file
131
app/controllers/application_controller.rb
Normal file
@@ -0,0 +1,131 @@
|
||||
require 'authie/session'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
before_action :login_required
|
||||
before_action :verified_email_required
|
||||
before_action :set_timezone
|
||||
|
||||
rescue_from Authie::Session::InactiveSession, :with => :auth_session_error
|
||||
rescue_from Authie::Session::ExpiredSession, :with => :auth_session_error
|
||||
rescue_from Authie::Session::BrowserMismatch, :with => :auth_session_error
|
||||
|
||||
private
|
||||
|
||||
def login_required
|
||||
unless logged_in?
|
||||
redirect_to login_path(:return_to => request.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
def admin_required
|
||||
if logged_in?
|
||||
unless current_user.admin?
|
||||
render :text => "Not permitted"
|
||||
end
|
||||
else
|
||||
redirect_to login_path(:return_to => request.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
def verified_email_required
|
||||
if logged_in? && !current_user.verified?
|
||||
redirect_to verify_path(:return_to => request.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
def require_organization_admin
|
||||
unless organization.admin?(current_user)
|
||||
redirect_to organization_root_path(organization), :alert => "This page can only be accessed by the organization admins"
|
||||
end
|
||||
end
|
||||
|
||||
def require_organization_owner
|
||||
unless organization.owner == current_user
|
||||
redirect_to organization_root_path(organization), :alert => "This page can only be accessed by the organization's owner (#{organization.owner.name})"
|
||||
end
|
||||
end
|
||||
|
||||
def auth_session_error(exception)
|
||||
Rails.logger.info "AuthSessionError: #{exception.class}: #{exception.message}"
|
||||
redirect_to login_path(:return_to => request.fullpath)
|
||||
end
|
||||
|
||||
def page_title
|
||||
@page_title ||= ["Postal"]
|
||||
end
|
||||
helper_method :page_title
|
||||
|
||||
def redirect_to_with_return_to(url, *args)
|
||||
if params[:return_to].blank? || !params[:return_to].starts_with?('/')
|
||||
redirect_to url_with_return_to(url), *args
|
||||
else
|
||||
redirect_to url_with_return_to(url), *args
|
||||
end
|
||||
end
|
||||
|
||||
def set_timezone
|
||||
Time.zone = logged_in? ? current_user.time_zone : 'UTC'
|
||||
end
|
||||
|
||||
def append_info_to_payload(payload)
|
||||
super
|
||||
payload[:ip] = request.ip
|
||||
payload[:user] = logged_in? ? current_user.id : nil
|
||||
end
|
||||
|
||||
def url_with_return_to(url)
|
||||
if params[:return_to].blank? || !params[:return_to].starts_with?('/')
|
||||
url_for(url)
|
||||
else
|
||||
params[:return_to]
|
||||
end
|
||||
end
|
||||
|
||||
def redirect_to_with_json(url, flash_messages = {})
|
||||
if url.is_a?(Array) && url[0] == :return_to
|
||||
url = url_with_return_to(url[1])
|
||||
else
|
||||
url = url_for(url)
|
||||
end
|
||||
|
||||
flash_messages.each do |key, value|
|
||||
flash[key] = value
|
||||
end
|
||||
respond_to do |wants|
|
||||
wants.html { redirect_to url }
|
||||
wants.json { render :json => {:redirect_to => url} }
|
||||
end
|
||||
end
|
||||
|
||||
def render_form_errors(action_name, object)
|
||||
respond_to do |wants|
|
||||
wants.html { render action_name }
|
||||
wants.json { render :json => {:form_errors => object.errors.full_messages}, :status => 422 }
|
||||
end
|
||||
end
|
||||
|
||||
def flash_now(type, message, options = {})
|
||||
respond_to do |wants|
|
||||
wants.html do
|
||||
flash.now[type] = message
|
||||
if options[:render_action]
|
||||
render options[:render_action]
|
||||
end
|
||||
end
|
||||
wants.json { render :json => {:flash => {type => message}} }
|
||||
end
|
||||
end
|
||||
|
||||
def login(user)
|
||||
if logged_in?
|
||||
auth_session.invalidate!
|
||||
reset_session
|
||||
end
|
||||
Authie::Session.start(self, :user => user)
|
||||
@current_user = user
|
||||
end
|
||||
|
||||
end
|
||||
0
app/controllers/concerns/.keep
Normal file
0
app/controllers/concerns/.keep
Normal file
20
app/controllers/concerns/within_organization.rb
Normal file
20
app/controllers/concerns/within_organization.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
module WithinOrganization
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
helper_method :organization
|
||||
before_action :add_organization_to_page_title
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def organization
|
||||
@organization ||= current_user.organizations_scope.find_by_permalink!(params[:org_permalink])
|
||||
end
|
||||
|
||||
def add_organization_to_page_title
|
||||
page_title << organization.name
|
||||
end
|
||||
|
||||
end
|
||||
38
app/controllers/credentials_controller.rb
Normal file
38
app/controllers/credentials_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class CredentialsController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @credential = @server.credentials.find_by_key!(params[:id]) }
|
||||
|
||||
def index
|
||||
@credentials = @server.credentials.order(:name).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@credential = @server.credentials.build
|
||||
end
|
||||
|
||||
def create
|
||||
@credential = @server.credentials.build(params.require(:credential).permit(:type, :name, :hold))
|
||||
if @credential.save
|
||||
redirect_to_with_json [organization, @server, :credentials]
|
||||
else
|
||||
render_form_errors 'new', @credential
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @credential.update(params.require(:credential).permit(:name, :hold))
|
||||
redirect_to_with_json [organization, @server, :credentials]
|
||||
else
|
||||
render_form_errors 'edit', @credential
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@credential.destroy
|
||||
redirect_to_with_json [organization, @server, :credentials]
|
||||
end
|
||||
|
||||
end
|
||||
102
app/controllers/domains_controller.rb
Normal file
102
app/controllers/domains_controller.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
class DomainsController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action do
|
||||
if params[:server_id]
|
||||
@server = organization.servers.present.find_by_permalink!(params[:server_id])
|
||||
params[:id] && @domain = @server.domains.find_by_uuid!(params[:id])
|
||||
else
|
||||
params[:id] && @domain = organization.domains.find_by_uuid!(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
if @server
|
||||
@domains = @server.domains.order(:name).to_a
|
||||
else
|
||||
@domains = organization.domains.order(:name).to_a
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@domain = @server ? @server.domains.build : organization.domains.build
|
||||
end
|
||||
|
||||
def create
|
||||
scope = @server ? @server.domains : organization.domains
|
||||
@domain = scope.build(params.require(:domain).permit(:name, :verification_method))
|
||||
|
||||
if @domain.save
|
||||
if @auto_verified
|
||||
flash[:notice] = "Ownership of this domain does not need to be verified because it already has been verified in this organization."
|
||||
redirect_to_with_json [:setup, organization, @server, @domain]
|
||||
else
|
||||
redirect_to_with_json [:verify, organization, @server, @domain]
|
||||
end
|
||||
else
|
||||
render_form_errors 'new', @domain
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@domain.destroy
|
||||
redirect_to_with_json [organization, @server, :domains]
|
||||
end
|
||||
|
||||
def verify
|
||||
if @domain.verified?
|
||||
redirect_to [organization, @server, :domains], :alert => "#{@domain.name} has already been verified."
|
||||
return
|
||||
end
|
||||
|
||||
if request.post?
|
||||
case @domain.verification_method
|
||||
when 'DNS'
|
||||
if @domain.verify_with_dns
|
||||
redirect_to_with_json [:setup, organization, @server, @domain], :notice => "#{@domain.name} has been verified successfully. You now need to configure your DNS records."
|
||||
else
|
||||
respond_to do |wants|
|
||||
wants.html { flash.now[:alert] = "We couldn't verify your domain. Please double check you've added the TXT record correctly." }
|
||||
wants.json { render :json => {:flash => {:alert => "We couldn't verify your domain. Please double check you've added the TXT record correctly."}}}
|
||||
end
|
||||
end
|
||||
when 'Email'
|
||||
if params[:code]
|
||||
if @domain.verification_token == params[:code].to_s.strip
|
||||
@domain.verify
|
||||
redirect_to_with_json [:setup, organization, @server, @domain], :notice => "#{@domain.name} has been verified successfully. You now need to configure your DNS records."
|
||||
else
|
||||
respond_to do |wants|
|
||||
wants.html { flash.now[:alert] = "Invalid verification code. Please check and try again." }
|
||||
wants.json { render :json => {:flash => {:alert => "Invalid verification code. Please check and try again."}}}
|
||||
end
|
||||
end
|
||||
elsif params[:email_address].present?
|
||||
raise Postal::Error, "Invalid email address" unless @domain.verification_email_addresses.include?(params[:email_address])
|
||||
AppMailer.verify_domain(@domain, params[:email_address], current_user).deliver
|
||||
if @domain.owner.is_a?(Server)
|
||||
redirect_to_with_json verify_organization_server_domain_path(organization, @server, @domain, :email_address => params[:email_address])
|
||||
else
|
||||
redirect_to_with_json verify_organization_domain_path(organization, @domain, :email_address => params[:email_address])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
unless @domain.verified?
|
||||
redirect_to [:verify, organization, @server, @domain], :alert => "You can't set up DNS for this domain until it has been verified."
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
if @domain.check_dns(:manual)
|
||||
redirect_to_with_json [organization, @server, :domains], :notice => "Your DNS records for #{@domain.name} look good!"
|
||||
else
|
||||
redirect_to_with_json [:setup, organization, @server, @domain], :alert => "There seems to be something wrong with your DNS records. Check below for information."
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
11
app/controllers/help_controller.rb
Normal file
11
app/controllers/help_controller.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class HelpController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.find_by_permalink!(params[:server_id]) }
|
||||
|
||||
def outgoing
|
||||
@credentials = @server.credentials.group_by(&:type)
|
||||
end
|
||||
|
||||
end
|
||||
45
app/controllers/http_endpoints_controller.rb
Normal file
45
app/controllers/http_endpoints_controller.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
class HTTPEndpointsController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @http_endpoint = @server.http_endpoints.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@http_endpoints = @server.http_endpoints.order(:name).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@http_endpoint = @server.http_endpoints.build
|
||||
end
|
||||
|
||||
def create
|
||||
@http_endpoint = @server.http_endpoints.build(safe_params)
|
||||
if @http_endpoint.save
|
||||
flash[:notice] = params[:return_notice] if params[:return_notice].present?
|
||||
redirect_to_with_json [:return_to, [organization, @server, :http_endpoints]]
|
||||
else
|
||||
render_form_errors 'new', @http_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @http_endpoint.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :http_endpoints]
|
||||
else
|
||||
render_form_errors 'edit', @http_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@http_endpoint.destroy
|
||||
redirect_to_with_json [organization, @server, :http_endpoints]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:http_endpoint).permit(:name, :url, :encoding, :format, :strip_replies, :include_attachments, :timeout)
|
||||
end
|
||||
|
||||
end
|
||||
55
app/controllers/ip_pool_rules_controller.rb
Normal file
55
app/controllers/ip_pool_rules_controller.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
class IPPoolRulesController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action do
|
||||
if params[:server_id]
|
||||
@server = organization.servers.present.find_by_permalink!(params[:server_id])
|
||||
params[:id] && @ip_pool_rule = @server.ip_pool_rules.find_by_uuid!(params[:id])
|
||||
else
|
||||
params[:id] && @ip_pool_rule = organization.ip_pool_rules.find_by_uuid!(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
if @server
|
||||
@ip_pool_rules = @server.ip_pool_rules
|
||||
else
|
||||
@ip_pool_rules = organization.ip_pool_rules
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@ip_pool_rule = @server ? @server.ip_pool_rules.build : organization.ip_pool_rules.build
|
||||
end
|
||||
|
||||
def create
|
||||
scope = @server ? @server.ip_pool_rules : organization.ip_pool_rules
|
||||
@ip_pool_rule = scope.build(safe_params)
|
||||
if @ip_pool_rule.save
|
||||
redirect_to_with_json [organization, @server, :ip_pool_rules]
|
||||
else
|
||||
render_form_errors 'new', @ip_pool_rule
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @ip_pool_rule.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :ip_pool_rules]
|
||||
else
|
||||
render_form_errors 'edit', @ip_pool_rule
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@ip_pool_rule.destroy
|
||||
redirect_to_with_json [organization, @server, :ip_pool_rules]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:ip_pool_rule).permit(:from_text, :to_text, :ip_pool_id)
|
||||
end
|
||||
|
||||
end
|
||||
9
app/controllers/ip_pools_controller.rb
Normal file
9
app/controllers/ip_pools_controller.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class IPPoolsController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
def index
|
||||
@ip_pools = organization.ip_pools.dedicated.order(:name)
|
||||
end
|
||||
|
||||
end
|
||||
226
app/controllers/messages_controller.rb
Normal file
226
app/controllers/messages_controller.rb
Normal file
@@ -0,0 +1,226 @@
|
||||
class MessagesController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @message = @server.message_db.message(params[:id].to_i) }
|
||||
|
||||
def new
|
||||
if params[:direction] == 'incoming'
|
||||
@message = IncomingMessagePrototype.new(@server, request.ip, 'web-ui', {})
|
||||
@message.from = session[:test_in_from] || current_user.email_tag
|
||||
@message.to = @server.routes.order(:name).first&.description
|
||||
else
|
||||
@message = OutgoingMessagePrototype.new(@server, request.ip, 'web-ui', {})
|
||||
@message.to = session[:test_out_to] || current_user.email_address
|
||||
if domain = @server.domains.verified.order(:name).first
|
||||
@message.from = "test@#{domain.name}"
|
||||
end
|
||||
end
|
||||
@message.subject = "Test Message at #{Time.now.to_s(:long)}"
|
||||
@message.plain_body = "This is a message to test the delivery of messages through Postal."
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:direction] == 'incoming'
|
||||
session[:test_in_from] = params[:message][:from] if params[:message]
|
||||
@message = IncomingMessagePrototype.new(@server, request.ip, 'web-ui', params[:message])
|
||||
@message.attachments = [{:name => "test.txt", :content_type => "text/plain", :data => "Hello world!"}]
|
||||
else
|
||||
session[:test_out_to] = params[:message][:to] if params[:message]
|
||||
@message = OutgoingMessagePrototype.new(@server, request.ip, 'web-ui', params[:message])
|
||||
end
|
||||
if result = @message.create_messages
|
||||
if result.size == 1
|
||||
redirect_to_with_json organization_server_message_path(organization, @server, result.first.last[:id]), :notice => "Message was queued successfully"
|
||||
else
|
||||
redirect_to_with_json [:queue, organization, @server], :notice => "Messages queued successfully "
|
||||
end
|
||||
else
|
||||
respond_to do |wants|
|
||||
wants.html do
|
||||
flash.now[:alert] = "Your message could not be sent. Ensure that all fields are completed fully. #{result.errors.inspect}"
|
||||
render 'new'
|
||||
end
|
||||
wants.json do
|
||||
render :json => {:flash => {:alert => "Your message could not be sent. Please check all field are completed fully."}}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def outgoing
|
||||
@searchable = true
|
||||
get_messages('outgoing')
|
||||
respond_to do |wants|
|
||||
wants.html
|
||||
wants.json { render :json => {
|
||||
:flash => flash.each_with_object({}) { |(type, message), hash| hash[type] = message},
|
||||
:region_html => render_to_string(:partial => 'index', :formats => [:html])
|
||||
}}
|
||||
end
|
||||
end
|
||||
|
||||
def incoming
|
||||
@searchable = true
|
||||
get_messages('incoming')
|
||||
respond_to do |wants|
|
||||
wants.html
|
||||
wants.json { render :json => {
|
||||
:flash => flash.each_with_object({}) { |(type, message), hash| hash[type] = message},
|
||||
:region_html => render_to_string(:partial => 'index', :formats => [:html])
|
||||
}}
|
||||
end
|
||||
end
|
||||
|
||||
def held
|
||||
get_messages('held')
|
||||
end
|
||||
|
||||
def deliveries
|
||||
render :json => {:html => render_to_string(:partial => 'deliveries', :locals => {:message => @message})}
|
||||
end
|
||||
|
||||
def html_raw
|
||||
render :html => @message.html_body_without_tracking_image.html_safe
|
||||
end
|
||||
|
||||
def spam_checks
|
||||
@spam_checks = @message.spam_checks.sort_by { |s| s['score']}.reverse
|
||||
end
|
||||
|
||||
def attachment
|
||||
if @message.attachments.size > params[:attachment].to_i
|
||||
attachment = @message.attachments[params[:attachment].to_i]
|
||||
send_data attachment.body, :content_type => attachment.mime_type, :disposition => 'download', :filename => attachment.filename
|
||||
else
|
||||
redirect_to attachments_organization_server_message_path(organization, @server, @message.id), :alert => "Attachment not found. Choose an attachment from the list below."
|
||||
end
|
||||
end
|
||||
|
||||
def download
|
||||
if @message.raw_message
|
||||
send_data @message.raw_message, :filename => "Message-#{organization.permalink}-#{@server.permalink}-#{@message.id}.eml", :content_type => "text/plain"
|
||||
else
|
||||
redirect_to organization_server_message_path(organization, @server, @message.id), :alert => "We no longer have the raw message stored for this message."
|
||||
end
|
||||
end
|
||||
|
||||
def retry
|
||||
if @message.queued_message
|
||||
@message.queued_message.queue!
|
||||
flash[:notice] = "This message will be retried shortly."
|
||||
elsif @message.held?
|
||||
@message.add_to_message_queue(:manual => true)
|
||||
flash[:notice] = "This message has been released. Delivery will be attempted shortly."
|
||||
elsif @server.mode == 'Development'
|
||||
@message.add_to_message_queue(:manual => true)
|
||||
flash[:notice] = "This message will be redelivered shortly."
|
||||
else
|
||||
flash[:alert] = "This message is no longer queued for sending."
|
||||
end
|
||||
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
|
||||
end
|
||||
|
||||
def cancel_hold
|
||||
@message.cancel_hold
|
||||
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
|
||||
end
|
||||
|
||||
def remove_from_queue
|
||||
if @message.queued_message && !@message.queued_message.locked?
|
||||
@message.queued_message.destroy
|
||||
end
|
||||
redirect_to_with_json organization_server_message_path(organization, @server, @message.id)
|
||||
end
|
||||
|
||||
def suppressions
|
||||
@suppressions = @server.message_db.suppression_list.all_with_pagination(params[:page])
|
||||
end
|
||||
|
||||
def activity
|
||||
@entries = @message.activity_entries
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_messages(scope)
|
||||
if scope == 'held'
|
||||
options = {:where => {:held => 1}}
|
||||
else
|
||||
options = {:where => {:scope => scope, :spam => false}, :order => :timestamp, :direction => 'desc'}
|
||||
|
||||
if @query = (params[:query] || session["msg_query_#{@server.id}_#{scope}"]).presence
|
||||
session["msg_query_#{@server.id}_#{scope}"] = @query
|
||||
qs = Postal::QueryString.new(@query)
|
||||
if qs.empty?
|
||||
flash.now[:alert] = "It doesn't appear you entered anything to filter on. Please double check your query."
|
||||
else
|
||||
@queried = true
|
||||
if qs[:order] == 'oldest-first'
|
||||
options[:direction] = 'asc'
|
||||
end
|
||||
|
||||
options[:where][:rcpt_to] = qs[:to] if qs[:to]
|
||||
options[:where][:mail_from] = qs[:from] if qs[:from]
|
||||
options[:where][:status] = qs[:status] if qs[:status]
|
||||
options[:where][:token] = qs[:token] if qs[:token]
|
||||
|
||||
if qs[:msgid]
|
||||
options[:where][:message_id] = qs[:msgid]
|
||||
options[:where].delete(:spam)
|
||||
options[:where].delete(:scope)
|
||||
end
|
||||
options[:where][:tag] = qs[:tag] if qs[:tag]
|
||||
options[:where][:id] = qs[:id] if qs[:id]
|
||||
options[:where][:spam] = true if qs[:spam] == 'yes' || qs[:spam] == 'y'
|
||||
if qs[:before] || qs[:after]
|
||||
options[:where][:timestamp] = {}
|
||||
if qs[:before]
|
||||
begin
|
||||
options[:where][:timestamp][:less_than] = get_time_from_string(qs[:before]).to_f
|
||||
rescue TimeUndetermined => e
|
||||
flash.now[:alert] = "Couldn't determine time for before from '#{qs[:before]}'"
|
||||
end
|
||||
end
|
||||
|
||||
if qs[:after]
|
||||
begin
|
||||
options[:where][:timestamp][:greater_than] = get_time_from_string(qs[:after]).to_f
|
||||
rescue TimeUndetermined => e
|
||||
flash.now[:alert] = "Couldn't determine time for after from '#{qs[:after]}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
session["msg_query_#{@server.id}_#{scope}"] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@messages = @server.message_db.messages_with_pagination(params[:page], options)
|
||||
end
|
||||
|
||||
class TimeUndetermined < Postal::Error; end
|
||||
|
||||
def get_time_from_string(string)
|
||||
begin
|
||||
if string =~ /\A(\d{2,4})\-(\d{2})\-(\d{2}) (\d{2})\:(\d{2})\z/
|
||||
time = Time.new($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i)
|
||||
elsif string =~ /\A(\d{2,4})\-(\d{2})\-(\d{2})\z/
|
||||
time = Time.new($1.to_i, $2.to_i, $3.to_i, 0)
|
||||
else
|
||||
time = Chronic.parse(string, :context => :past)
|
||||
end
|
||||
rescue
|
||||
end
|
||||
|
||||
if time.nil?
|
||||
raise TimeUndetermined, "Couldn't determine a suitable time from '#{string}'"
|
||||
else
|
||||
time
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
62
app/controllers/organizations_controller.rb
Normal file
62
app/controllers/organizations_controller.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
class OrganizationsController < ApplicationController
|
||||
|
||||
before_action :require_organization_admin, :only => [:edit, :update, :delete, :destroy]
|
||||
|
||||
def index
|
||||
@organizations = current_user.organizations.present.order(:name).to_a
|
||||
if @organizations.size == 1 && params[:nrd].nil?
|
||||
redirect_to organization_root_path(@organizations.first)
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@organization = Organization.new
|
||||
end
|
||||
|
||||
def create
|
||||
@organization = Organization.new(params.require(:organization).permit(:name, :permalink))
|
||||
@organization.owner = current_user
|
||||
if @organization.save
|
||||
@organization.users << current_user
|
||||
redirect_to_with_json organization_root_path(@organization)
|
||||
else
|
||||
render_form_errors 'new', @organization
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@organization_obj = current_user.organizations_scope.find(organization.id)
|
||||
end
|
||||
|
||||
def update
|
||||
@organization_obj = current_user.organizations_scope.find(organization.id)
|
||||
if @organization_obj.update(params.require(:organization).permit(:name, :time_zone))
|
||||
redirect_to_with_json organization_settings_path(@organization_obj), :notice => "Settings for #{@organization_obj.name} have been saved successfully."
|
||||
else
|
||||
render_form_errors 'edit', @organization_obj
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
unless current_user.authenticate(params[:password])
|
||||
respond_to do |wants|
|
||||
wants.html { redirect_to organization_delete_path(@organization), :alert => "The password you entered was not valid. Please check and try again." }
|
||||
wants.json { render :json => {:alert => "The password you entered was invalid. Please check and try again."} }
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
organization.soft_destroy
|
||||
redirect_to_with_json root_path(:nrd => 1), :notice => "#{@organization.name} has been removed successfully."
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def organization
|
||||
if [:edit, :update, :delete, :destroy].include?(action_name.to_sym)
|
||||
@organization ||= params[:org_permalink] ? current_user.organizations_scope.find_by_permalink!(params[:org_permalink]) : nil
|
||||
end
|
||||
end
|
||||
helper_method :organization
|
||||
|
||||
end
|
||||
44
app/controllers/routes_controller.rb
Normal file
44
app/controllers/routes_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class RoutesController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @route = @server.routes.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@routes = @server.routes.order(:name).includes(:domain, :endpoint).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@route = @server.routes.build
|
||||
end
|
||||
|
||||
def create
|
||||
@route = @server.routes.build(safe_params)
|
||||
if @route.save
|
||||
redirect_to_with_json [organization, @server, :routes]
|
||||
else
|
||||
render_form_errors 'new', @route
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @route.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :routes]
|
||||
else
|
||||
render_form_errors 'edit', @route
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@route.destroy
|
||||
redirect_to_with_json [organization, @server, :routes]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:route).permit(:name, :domain_id, :spam_mode, :_endpoint, :additional_route_endpoints_array => [])
|
||||
end
|
||||
|
||||
end
|
||||
90
app/controllers/servers_controller.rb
Normal file
90
app/controllers/servers_controller.rb
Normal file
@@ -0,0 +1,90 @@
|
||||
class ServersController < ApplicationController
|
||||
|
||||
include WithinOrganization
|
||||
|
||||
before_action :require_organization_admin, :only => [:new, :create, :delete, :destroy]
|
||||
before_action :admin_required, :only => [:admin, :suspend, :unsuspend]
|
||||
before_action { params[:id] && @server = organization.servers.present.find_by_permalink!(params[:id]) }
|
||||
|
||||
def index
|
||||
@servers = organization.servers.present.order(:name).to_a
|
||||
end
|
||||
|
||||
def show
|
||||
if @server.created_at < 48.hours.ago
|
||||
@graph_type = :daily
|
||||
graph_data = @server.message_db.statistics.get(:daily, [:incoming, :outgoing, :bounces], Time.now, 30)
|
||||
elsif @server.created_at < 24.hours.ago
|
||||
@graph_type = :hourly
|
||||
graph_data = @server.message_db.statistics.get(:hourly, [:incoming, :outgoing, :bounces], Time.now, 48)
|
||||
else
|
||||
@graph_type = :hourly
|
||||
graph_data = @server.message_db.statistics.get(:hourly, [:incoming, :outgoing, :bounces], Time.now, 24)
|
||||
end
|
||||
@first_date = graph_data.first.first
|
||||
@last_date = graph_data.last.first
|
||||
@graph_data = graph_data.map(&:last)
|
||||
@messages = @server.message_db.messages(:order => 'id', :direction => 'desc', :limit => 6)
|
||||
end
|
||||
|
||||
def new
|
||||
@server = organization.servers.build
|
||||
end
|
||||
|
||||
def create
|
||||
@server = organization.servers.build(safe_params(:permalink))
|
||||
if @server.save
|
||||
redirect_to_with_json organization_server_path(organization, @server)
|
||||
else
|
||||
render_form_errors 'new', @server
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
extra_params = [:spam_threshold, :spam_failure_threshold, :postmaster_address]
|
||||
extra_params += [:send_limit, :allow_sender, :log_smtp_data, :outbound_spam_threshold, :message_retention_days, :raw_message_retention_days, :raw_message_retention_size, :ip_pool_id] if current_user.admin?
|
||||
if @server.update(safe_params(*extra_params))
|
||||
redirect_to_with_json organization_server_path(organization, @server), :notice => "Server settings have been updated"
|
||||
else
|
||||
render_form_errors 'edit', @server
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
unless current_user.authenticate(params[:password])
|
||||
respond_to do |wants|
|
||||
wants.html do
|
||||
redirect_to [:delete, organization, @server], :alert => "The password you entered was not valid. Please check and try again."
|
||||
end
|
||||
wants.json do
|
||||
render :json => {:alert => "The password you entere was invalid. Please check and try again"}
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
@server.soft_destroy
|
||||
redirect_to_with_json organization_root_path(organization), :notice => "#{@server.name} has been deleted successfully"
|
||||
end
|
||||
|
||||
def queue
|
||||
@messages = @server.queued_messages.order(:id => :desc).page(params[:page])
|
||||
@messages_with_message = @messages.include_message
|
||||
end
|
||||
|
||||
def suspend
|
||||
@server.suspend(params[:reason])
|
||||
redirect_to_with_json [organization, @server], :notice => "Server has been suspended"
|
||||
end
|
||||
|
||||
def unsuspend
|
||||
@server.unsuspend
|
||||
redirect_to_with_json [organization, @server], :notice => "Server has been unsuspended"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params(*extras)
|
||||
params.require(:server).permit(:name, :mode, :ip_pool_id, *extras)
|
||||
end
|
||||
|
||||
end
|
||||
75
app/controllers/sessions_controller.rb
Normal file
75
app/controllers/sessions_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
class SessionsController < ApplicationController
|
||||
|
||||
layout 'sub'
|
||||
|
||||
skip_before_action :login_required, :only => [:new, :create, :create_with_token, :begin_password_reset, :finish_password_reset, :ip, :raise_error]
|
||||
skip_before_action :verified_email_required
|
||||
|
||||
def create
|
||||
login(User.authenticate(params[:email_address], params[:password]))
|
||||
flash[:remember_login] = true
|
||||
redirect_to_with_return_to root_path
|
||||
rescue Postal::Errors::AuthenticationError => e
|
||||
flash.now[:alert] = "The credentials you've provided are incorrect. Please check and try again."
|
||||
render 'new'
|
||||
end
|
||||
|
||||
def create_with_token
|
||||
result = JWT.decode(params[:token], Postal.signing_key.to_s, 'HS256')[0]
|
||||
if result['timestamp'] > 1.minute.ago.to_f
|
||||
login(User.find(result['user'].to_i))
|
||||
redirect_to root_path
|
||||
else
|
||||
destroy
|
||||
end
|
||||
rescue JWT::VerificationError
|
||||
destroy
|
||||
end
|
||||
|
||||
def destroy
|
||||
auth_session.invalidate! if logged_in?
|
||||
reset_session
|
||||
redirect_to login_path
|
||||
end
|
||||
|
||||
def persist
|
||||
auth_session.persist! if logged_in?
|
||||
render :plain => "OK"
|
||||
end
|
||||
|
||||
def begin_password_reset
|
||||
if request.post?
|
||||
if user = User.where(:email_address => params[:email_address]).first
|
||||
user.begin_password_reset(params[:return_to])
|
||||
redirect_to login_path(:return_to => params[:return_to]), :notice => "Please check your e-mail and click the link in the e-mail we've sent you."
|
||||
else
|
||||
redirect_to login_reset_path(:return_to => params[:return_to]), :alert => "No user exists with that e-mail address. Please check and try again."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def finish_password_reset
|
||||
@user = User.where(:password_reset_token => params[:token]).where("password_reset_token_valid_until > ?", Time.now).first
|
||||
if @user.nil?
|
||||
redirect_to login_path(:return_to => params[:return_to]), :alert => "This link has expired or never existed. Please choose reset password to try again."
|
||||
end
|
||||
|
||||
if request.post?
|
||||
if params[:password].blank?
|
||||
flash.now[:alert] = "You must enter a new password"
|
||||
return
|
||||
end
|
||||
@user.password = params[:password]
|
||||
@user.password_confirmation = params[:password_confirmation]
|
||||
if @user.save
|
||||
login(@user)
|
||||
redirect_to_with_return_to root_path, :notice => "Your new password has been set and you've been logged in."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ip
|
||||
render :plain => "ip: #{request.ip} remote ip: #{request.remote_ip}"
|
||||
end
|
||||
|
||||
end
|
||||
43
app/controllers/smtp_endpoints_controller.rb
Normal file
43
app/controllers/smtp_endpoints_controller.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
class SMTPEndpointsController < ApplicationController
|
||||
include WithinOrganization
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @smtp_endpoint = @server.smtp_endpoints.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@smtp_endpoints = @server.smtp_endpoints.order(:name).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@smtp_endpoint = @server.smtp_endpoints.build
|
||||
end
|
||||
|
||||
def create
|
||||
@smtp_endpoint = @server.smtp_endpoints.build(safe_params)
|
||||
if @smtp_endpoint.save
|
||||
flash[:notice] = params[:return_notice] if params[:return_notice].present?
|
||||
redirect_to_with_json [:return_to, [organization, @server, :smtp_endpoints]]
|
||||
else
|
||||
render_form_errors 'new', @smtp_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @smtp_endpoint.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :smtp_endpoints]
|
||||
else
|
||||
render_form_errors 'edit', @smtp_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@smtp_endpoint.destroy
|
||||
redirect_to_with_json [organization, @server, :smtp_endpoints]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:smtp_endpoint).permit(:name, :hostname, :port, :ssl_mode)
|
||||
end
|
||||
|
||||
end
|
||||
49
app/controllers/track_domains_controller.rb
Normal file
49
app/controllers/track_domains_controller.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
class TrackDomainsController < ApplicationController
|
||||
include WithinOrganization
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @track_domain = @server.track_domains.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@track_domains = @server.track_domains.order(:name).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@track_domain = @server.track_domains.build
|
||||
end
|
||||
|
||||
def create
|
||||
@track_domain = @server.track_domains.build(params.require(:track_domain).permit(:name, :domain_id, :track_loads, :track_clicks, :excluded_click_domains, :ssl_enabled))
|
||||
if @track_domain.save
|
||||
redirect_to_with_json [:return_to, [organization, @server, :track_domains]]
|
||||
else
|
||||
render_form_errors 'new', @track_domain
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @track_domain.update(params.require(:track_domain).permit(:track_loads, :track_clicks, :excluded_click_domains, :ssl_enabled))
|
||||
redirect_to_with_json [organization, @server, :track_domains]
|
||||
else
|
||||
render_form_errors 'edit', @track_domain
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@track_domain.destroy
|
||||
redirect_to_with_json [organization, @server, :track_domains]
|
||||
end
|
||||
|
||||
def check
|
||||
if @track_domain.check_dns
|
||||
redirect_to_with_json [organization, @server, :track_domains], :notice => "Your CNAME for #{@track_domain.full_name} looks good!"
|
||||
else
|
||||
redirect_to_with_json [organization, @server, :track_domains], :alert => "There seems to be something wrong with your DNS record. Check documentation for information."
|
||||
end
|
||||
end
|
||||
|
||||
def toggle_ssl
|
||||
@track_domain.update(:ssl_enabled => !@track_domain.ssl_enabled)
|
||||
redirect_to_with_json [organization, @server, :track_domains], :notice => "SSL settings for #{@track_domain.full_name} updated successfully."
|
||||
end
|
||||
|
||||
end
|
||||
85
app/controllers/user_controller.rb
Normal file
85
app/controllers/user_controller.rb
Normal file
@@ -0,0 +1,85 @@
|
||||
class UserController < ApplicationController
|
||||
|
||||
skip_before_action :login_required, :only => [:new, :create]
|
||||
skip_before_action :verified_email_required, :only => [:edit, :update, :verify]
|
||||
|
||||
def new
|
||||
@user = User.new
|
||||
render :layout => 'sub'
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.new(params.require(:user).permit(:first_name, :last_name, :email_address, :password, :password_confirmation))
|
||||
if @user.save
|
||||
AppMailer.new_user(@user).deliver
|
||||
self.current_user = @user
|
||||
redirect_to verify_path(:return_to => params[:return_to])
|
||||
else
|
||||
render 'new', :layout => 'sub'
|
||||
end
|
||||
end
|
||||
|
||||
def join
|
||||
if @invite = UserInvite.where(:uuid => params[:token]).where("expires_at > ?", Time.now).first
|
||||
if request.post?
|
||||
@invite.accept(current_user)
|
||||
redirect_to_with_json root_path(:nrd => 1), :notice => "Invitation has been accepted successfully. You now have access to this organization."
|
||||
elsif request.delete?
|
||||
@invite.reject
|
||||
redirect_to_with_json root_path(:nrd => 1), :notice => "Invitation has been rejected successfully."
|
||||
else
|
||||
@organizations = @invite.organizations.order(:name).to_a
|
||||
end
|
||||
else
|
||||
redirect_to_with_json root_path(:nrd => 1), :alert => "The invite URL you have has expired. Please ask the person who invited you to re-send your invitation."
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(current_user.id)
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(current_user.id)
|
||||
@user.attributes = params.require(:user).permit(:first_name, :last_name, :time_zone, :email_address, :password, :password_confirmation)
|
||||
|
||||
if @user.authenticate_with_previous_password_first(params[:password])
|
||||
@password_correct = true
|
||||
else
|
||||
respond_to do |wants|
|
||||
wants.html do
|
||||
flash.now[:alert] = "The current password you have entered is incorrect. Please check and try again."
|
||||
render 'edit'
|
||||
end
|
||||
wants.json do
|
||||
render :json => {:alert => "The current password you've entered is incorrect. Please check and try again"}
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
email_changed = @user.email_address_changed?
|
||||
|
||||
if @user.save
|
||||
if email_changed
|
||||
redirect_to_with_json verify_path(:return_to => settings_path), :notice => "Your settings have been updated successfully. As you've changed, your e-mail address you'll need to verify it before you can continue."
|
||||
else
|
||||
redirect_to_with_json settings_path, :notice => "Your settings have been updated successfully."
|
||||
end
|
||||
else
|
||||
render_form_errors 'edit', @user
|
||||
end
|
||||
end
|
||||
|
||||
def verify
|
||||
if request.post?
|
||||
if params[:code].to_s.strip == current_user.email_verification_token.to_s || (Rails.env.development? && params[:code].to_s.strip == "123456")
|
||||
current_user.verify!
|
||||
redirect_to_with_json [:return_to, root_path], :notice => "Thanks - your e-mail address has been verified successfully."
|
||||
else
|
||||
flash_now :alert, "The code you've entered isn't correct. Please check and try again."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
63
app/controllers/users_controller.rb
Normal file
63
app/controllers/users_controller.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
class UsersController < ApplicationController
|
||||
include WithinOrganization
|
||||
before_action :require_organization_admin
|
||||
before_action :require_organization_owner, :only => [:make_owner]
|
||||
before_action { params[:id] && @user = params[:invite] ? organization.user_invites.find_by_uuid!(params[:id]) : organization.users.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@users = organization.organization_users.where(:user_type => 'User').includes(:user).to_a.sort_by { |u| "#{u.user.first_name}#{u.user.last_name}".upcase }
|
||||
@pending_users = organization.organization_users.where(:user_type => "UserInvite").includes(:user).to_a.sort_by { |u| u.user.email_address.upcase }
|
||||
end
|
||||
|
||||
def new
|
||||
@organization_user = organization.organization_users.build
|
||||
end
|
||||
|
||||
def create
|
||||
@organization_user = organization.organization_users.build(params.require(:organization_user).permit(:email_address, :admin, :all_servers))
|
||||
if @organization_user.save
|
||||
AppMailer.user_invite(@organization_user.user, organization).deliver
|
||||
redirect_to_with_json [organization, :users], :notice => "An invitation will be sent to #{@organization_user.user.email_address} which will allow them to access your organization."
|
||||
else
|
||||
render_form_errors 'new', @organization_user
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@organization_user = organization.user_assignment(@user)
|
||||
end
|
||||
|
||||
def update
|
||||
@organization_user = organization.user_assignment(@user)
|
||||
if @organization_user.update(params.require(:organization_user).permit(:admin))
|
||||
redirect_to_with_json [organization, :users], :notice => "Permissions for #{@organization_user.user.name} have been updated successfully."
|
||||
else
|
||||
render_form_errors 'edit', @organization_user
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @user == current_user
|
||||
redirect_to_with_json [organization, :users], :alert => "You cannot revoke your own access."
|
||||
return
|
||||
end
|
||||
|
||||
if @user == organization.owner
|
||||
redirect_to_with_json [organization, :users], :alert => "You cannot revoke the organization owner's access."
|
||||
return
|
||||
end
|
||||
|
||||
organization.organization_users.where(:user => @user).destroy_all
|
||||
redirect_to_with_json [organization, :users], :notice => "#{@user.name} has been removed from this organization"
|
||||
end
|
||||
|
||||
def make_owner
|
||||
if @user.is_a?(User)
|
||||
organization.make_owner(@user)
|
||||
redirect_to_with_json [organization, :users], :notice => "#{@user.name} is now the owner of this organization."
|
||||
else
|
||||
raise Postal::Error, "User must be a User not a UserInvite to make owner"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
51
app/controllers/webhooks_controller.rb
Normal file
51
app/controllers/webhooks_controller.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
class WebhooksController < ApplicationController
|
||||
include WithinOrganization
|
||||
before_action { @server = organization.servers.present.find_by_permalink!(params[:server_id]) }
|
||||
before_action { params[:id] && @webhook = @server.webhooks.find_by_uuid!(params[:id]) }
|
||||
|
||||
def index
|
||||
@webhooks = @server.webhooks.order(:url).to_a
|
||||
end
|
||||
|
||||
def new
|
||||
@webhook = @server.webhooks.build(:all_events => true)
|
||||
end
|
||||
|
||||
def create
|
||||
@webhook = @server.webhooks.build(safe_params)
|
||||
if @webhook.save
|
||||
redirect_to_with_json [organization, @server, :webhooks]
|
||||
else
|
||||
render_form_errors 'new', @webhook
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @webhook.update(safe_params)
|
||||
redirect_to_with_json [organization, @server, :webhooks]
|
||||
else
|
||||
render_form_errors 'edit', @webhook
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@webhook.destroy
|
||||
redirect_to_with_json [organization, @server, :webhooks]
|
||||
end
|
||||
|
||||
def history
|
||||
@current_page = params[:page] ? params[:page].to_i : 1
|
||||
@requests = @server.message_db.webhooks.list(@current_page)
|
||||
end
|
||||
|
||||
def history_request
|
||||
@req = @server.message_db.webhooks.find(params[:uuid])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def safe_params
|
||||
params.require(:webhook).permit(:name, :url, :all_events, :enabled, :events => [])
|
||||
end
|
||||
|
||||
end
|
||||
المرجع في مشكلة جديدة
حظر مستخدم