Added feature to restrict chat by ip or/and country.
This commit is contained in:
parent
b7d949bf38
commit
5fb6bfed7d
9 changed files with 412 additions and 28 deletions
|
@ -6,24 +6,24 @@ class App.UiElement.column_select extends App.UiElement.ApplicationUiElement
|
||||||
attribute.multiple = 'multiple'
|
attribute.multiple = 'multiple'
|
||||||
|
|
||||||
# build options list based on config
|
# build options list based on config
|
||||||
@getConfigOptionList( attribute, params )
|
@getConfigOptionList(attribute, params)
|
||||||
|
|
||||||
# build options list based on relation
|
# build options list based on relation
|
||||||
@getRelationOptionList( attribute, params )
|
@getRelationOptionList(attribute, params)
|
||||||
|
|
||||||
# add null selection if needed
|
# add null selection if needed
|
||||||
@addNullOption( attribute, params )
|
@addNullOption(attribute, params)
|
||||||
|
|
||||||
# sort attribute.options
|
# sort attribute.options
|
||||||
@sortOptions( attribute, params )
|
@sortOptions(attribute, params)
|
||||||
|
|
||||||
# find selected/checked item of list
|
# find selected/checked item of list
|
||||||
@selectedOptions( attribute, params )
|
@selectedOptions(attribute, params)
|
||||||
|
|
||||||
# disable item of list
|
# disable item of list
|
||||||
@disabledOptions( attribute, params )
|
@disabledOptions(attribute, params)
|
||||||
|
|
||||||
# filter attributes
|
# filter attributes
|
||||||
@filterOption( attribute, params )
|
@filterOption(attribute, params)
|
||||||
|
|
||||||
new App.ColumnSelect( attribute: attribute ).element()
|
new App.ColumnSelect(attribute: attribute).element()
|
||||||
|
|
|
@ -39,14 +39,27 @@ class App.ColumnSelect extends Spine.Controller
|
||||||
)
|
)
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
if !_.isEmpty(@attribute.seperator)
|
||||||
|
values = []
|
||||||
|
if @attribute.value
|
||||||
|
values = @attribute.value.split(';')
|
||||||
|
else if @attribute.default
|
||||||
|
values = @attribute.default.split(';')
|
||||||
|
|
||||||
|
for value in values
|
||||||
|
for option in @options.attribute.options
|
||||||
|
if option.value is value
|
||||||
|
option.selected = true
|
||||||
|
|
||||||
@values = []
|
@values = []
|
||||||
_.each @options.attribute.options, (option) =>
|
_.each @options.attribute.options, (option) =>
|
||||||
if option.selected
|
if option.selected
|
||||||
@values.push option.value.toString()
|
@values.push option.value.toString()
|
||||||
|
|
||||||
@html App.view('generic/column_select')
|
@html App.view('generic/column_select')(
|
||||||
attribute: @options.attribute
|
attribute: @options.attribute
|
||||||
values: @values
|
values: @values
|
||||||
|
)
|
||||||
|
|
||||||
# keep inital height
|
# keep inital height
|
||||||
# disabled for now since controls in modals get rendered hidden
|
# disabled for now since controls in modals get rendered hidden
|
||||||
|
@ -60,13 +73,17 @@ class App.ColumnSelect extends Spine.Controller
|
||||||
@throttledSelect()
|
@throttledSelect()
|
||||||
|
|
||||||
select: (value) ->
|
select: (value) ->
|
||||||
@selected.find("[data-value='#{value}']").removeClass 'is-hidden'
|
@selected.find("[data-value='#{value}']").removeClass('is-hidden')
|
||||||
@pool.find("[data-value='#{value}']").addClass 'is-hidden'
|
@pool.find("[data-value='#{value}']").addClass('is-hidden')
|
||||||
@values.push(value)
|
@values.push(value)
|
||||||
@shadow.val(@values)
|
|
||||||
@shadow.trigger('change')
|
|
||||||
|
|
||||||
@placeholder.addClass 'is-hidden'
|
if !_.isEmpty(@attribute.seperator)
|
||||||
|
@shadow.val(@values.join(';'))
|
||||||
|
else
|
||||||
|
@shadow.val(@values)
|
||||||
|
@shadow.trigger('change')
|
||||||
|
|
||||||
|
@placeholder.addClass('is-hidden')
|
||||||
|
|
||||||
if @search.val() and @poolOptions.not('.is-filtered').not('.is-hidden').size() is 0
|
if @search.val() and @poolOptions.not('.is-filtered').not('.is-hidden').size() is 0
|
||||||
@clear()
|
@clear()
|
||||||
|
@ -76,14 +93,17 @@ class App.ColumnSelect extends Spine.Controller
|
||||||
@throttledRemove()
|
@throttledRemove()
|
||||||
|
|
||||||
remove: (value) ->
|
remove: (value) ->
|
||||||
@pool.find("[data-value='#{value}']").removeClass 'is-hidden'
|
@pool.find("[data-value='#{value}']").removeClass('is-hidden')
|
||||||
@selected.find("[data-value='#{value}']").addClass 'is-hidden'
|
@selected.find("[data-value='#{value}']").addClass('is-hidden')
|
||||||
@values.splice(@values.indexOf(value), 1)
|
@values.splice(@values.indexOf(value), 1)
|
||||||
@shadow.val(@values)
|
if !_.isEmpty(@attribute.seperator)
|
||||||
@shadow.trigger('change')
|
@shadow.val(@values.join(';'))
|
||||||
|
else
|
||||||
|
@shadow.val(@values)
|
||||||
|
@shadow.trigger('change')
|
||||||
|
|
||||||
if !@values.length
|
if !@values.length
|
||||||
@placeholder.removeClass 'is-hidden'
|
@placeholder.removeClass('is-hidden')
|
||||||
|
|
||||||
filter: (event) ->
|
filter: (event) ->
|
||||||
filter = $(event.currentTarget).val()
|
filter = $(event.currentTarget).val()
|
||||||
|
@ -92,16 +112,16 @@ class App.ColumnSelect extends Spine.Controller
|
||||||
return if $(el).hasClass('is-hidden')
|
return if $(el).hasClass('is-hidden')
|
||||||
|
|
||||||
if $(el).text().toLowerCase().indexOf(filter.toLowerCase()) > -1
|
if $(el).text().toLowerCase().indexOf(filter.toLowerCase()) > -1
|
||||||
$(el).removeClass 'is-filtered'
|
$(el).removeClass('is-filtered')
|
||||||
else
|
else
|
||||||
$(el).addClass 'is-filtered'
|
$(el).addClass('is-filtered')
|
||||||
|
|
||||||
@clearButton.toggleClass 'is-hidden', filter.length is 0
|
@clearButton.toggleClass 'is-hidden', filter.length is 0
|
||||||
|
|
||||||
clear: ->
|
clear: ->
|
||||||
@search.val('')
|
@search.val('')
|
||||||
@poolOptions.removeClass 'is-filtered'
|
@poolOptions.removeClass('is-filtered')
|
||||||
@clearButton.addClass 'is-hidden'
|
@clearButton.addClass('is-hidden')
|
||||||
|
|
||||||
onFilterKeydown: (event) ->
|
onFilterKeydown: (event) ->
|
||||||
return if event.keyCode != 13
|
return if event.keyCode != 13
|
||||||
|
|
|
@ -1,16 +1,260 @@
|
||||||
class App.Chat extends App.Model
|
class App.Chat extends App.Model
|
||||||
@configure 'Chat', 'name', 'active', 'public', 'max_queue', 'note'
|
@configure 'Chat', 'name', 'active', 'public', 'max_queue', 'block_ip', 'block_country', 'note'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/chats'
|
@url: @apiPath + '/chats'
|
||||||
|
@countries:
|
||||||
|
AF: 'Afghanistan'
|
||||||
|
AL: 'Albania'
|
||||||
|
DZ: 'Algeria'
|
||||||
|
AS: 'American Samoa'
|
||||||
|
AD: 'Andorra'
|
||||||
|
AO: 'Angola'
|
||||||
|
AI: 'Anguilla'
|
||||||
|
AQ: 'Antarctica'
|
||||||
|
AG: 'Antigua And Barbuda'
|
||||||
|
AR: 'Argentina'
|
||||||
|
AM: 'Armenia'
|
||||||
|
AW: 'Aruba'
|
||||||
|
AU: 'Australia'
|
||||||
|
AT: 'Austria'
|
||||||
|
AZ: 'Azerbaijan'
|
||||||
|
BS: 'Bahamas'
|
||||||
|
BH: 'Bahrain'
|
||||||
|
BD: 'Bangladesh'
|
||||||
|
BB: 'Barbados'
|
||||||
|
BY: 'Belarus'
|
||||||
|
BE: 'Belgium'
|
||||||
|
BZ: 'Belize'
|
||||||
|
BJ: 'Benin'
|
||||||
|
BM: 'Bermuda'
|
||||||
|
BT: 'Bhutan'
|
||||||
|
BO: 'Bolivia'
|
||||||
|
BA: 'Bosnia And Herzegovina'
|
||||||
|
BW: 'Botswana'
|
||||||
|
BV: 'Bouvet Island'
|
||||||
|
BR: 'Brazil'
|
||||||
|
IO: 'British Indian Ocean Territory'
|
||||||
|
BN: 'Brunei Darussalam'
|
||||||
|
BG: 'Bulgaria'
|
||||||
|
BF: 'Burkina Faso'
|
||||||
|
BI: 'Burundi'
|
||||||
|
KH: 'Cambodia'
|
||||||
|
CM: 'Cameroon'
|
||||||
|
CA: 'Canada'
|
||||||
|
CV: 'Cape Verde'
|
||||||
|
KY: 'Cayman Islands'
|
||||||
|
CF: 'Central African Republic'
|
||||||
|
TD: 'Chad'
|
||||||
|
CL: 'Chile'
|
||||||
|
CN: 'China'
|
||||||
|
CX: 'Christmas Island'
|
||||||
|
CC: 'Cocos (keeling) Islands'
|
||||||
|
CO: 'Colombia'
|
||||||
|
KM: 'Comoros'
|
||||||
|
CG: 'Congo'
|
||||||
|
CD: 'Congo, The Democratic Republic Of The'
|
||||||
|
CK: 'Cook Islands'
|
||||||
|
CR: 'Costa Rica'
|
||||||
|
CI: 'Cote D\'ivoire'
|
||||||
|
HR: 'Croatia'
|
||||||
|
CU: 'Cuba'
|
||||||
|
CY: 'Cyprus'
|
||||||
|
CZ: 'Czech Republic'
|
||||||
|
DK: 'Denmark'
|
||||||
|
DJ: 'Djibouti'
|
||||||
|
DM: 'Dominica'
|
||||||
|
DO: 'Dominican Republic'
|
||||||
|
TP: 'East Timor'
|
||||||
|
EC: 'Ecuador'
|
||||||
|
EG: 'Egypt'
|
||||||
|
SV: 'El Salvador'
|
||||||
|
GQ: 'Equatorial Guinea'
|
||||||
|
ER: 'Eritrea'
|
||||||
|
EE: 'Estonia'
|
||||||
|
ET: 'Ethiopia'
|
||||||
|
FK: 'Falkland Islands (malvinas)'
|
||||||
|
FO: 'Faroe Islands'
|
||||||
|
FJ: 'Fiji'
|
||||||
|
FI: 'Finland'
|
||||||
|
FR: 'France'
|
||||||
|
GF: 'French Guiana'
|
||||||
|
PF: 'French Polynesia'
|
||||||
|
TF: 'French Southern Territories'
|
||||||
|
GA: 'Gabon'
|
||||||
|
GM: 'Gambia'
|
||||||
|
GE: 'Georgia'
|
||||||
|
DE: 'Germany'
|
||||||
|
GH: 'Ghana'
|
||||||
|
GI: 'Gibraltar'
|
||||||
|
GR: 'Greece'
|
||||||
|
GL: 'Greenland'
|
||||||
|
GD: 'Grenada'
|
||||||
|
GP: 'Guadeloupe'
|
||||||
|
GU: 'Guam'
|
||||||
|
GT: 'Guatemala'
|
||||||
|
GN: 'Guinea'
|
||||||
|
GW: 'Guinea-bissau'
|
||||||
|
GY: 'Guyana'
|
||||||
|
HT: 'Haiti'
|
||||||
|
HM: 'Heard Island And Mcdonald Islands'
|
||||||
|
VA: 'Holy See (vatican City State)'
|
||||||
|
HN: 'Honduras'
|
||||||
|
HK: 'Hong Kong'
|
||||||
|
HU: 'Hungary'
|
||||||
|
IS: 'Iceland'
|
||||||
|
IN: 'India'
|
||||||
|
ID: 'Indonesia'
|
||||||
|
IR: 'Iran, Islamic Republic Of'
|
||||||
|
IQ: 'Iraq'
|
||||||
|
IE: 'Ireland'
|
||||||
|
IL: 'Israel'
|
||||||
|
IT: 'Italy'
|
||||||
|
JM: 'Jamaica'
|
||||||
|
JP: 'Japan'
|
||||||
|
JO: 'Jordan'
|
||||||
|
KZ: 'Kazakstan'
|
||||||
|
KE: 'Kenya'
|
||||||
|
KI: 'Kiribati'
|
||||||
|
KP: 'Korea, Democratic People\'s Republic Of'
|
||||||
|
KR: 'Korea, Republic Of'
|
||||||
|
KV: 'Kosovo'
|
||||||
|
KW: 'Kuwait'
|
||||||
|
KG: 'Kyrgyzstan'
|
||||||
|
LA: 'Lao People\'s Democratic Republic'
|
||||||
|
LV: 'Latvia'
|
||||||
|
LB: 'Lebanon'
|
||||||
|
LS: 'Lesotho'
|
||||||
|
LR: 'Liberia'
|
||||||
|
LY: 'Libyan Arab Jamahiriya'
|
||||||
|
LI: 'Liechtenstein'
|
||||||
|
LT: 'Lithuania'
|
||||||
|
LU: 'Luxembourg'
|
||||||
|
MO: 'Macau'
|
||||||
|
MK: 'Macedonia, The Former Yugoslav Republic Of'
|
||||||
|
MG: 'Madagascar'
|
||||||
|
MW: 'Malawi'
|
||||||
|
MY: 'Malaysia'
|
||||||
|
MV: 'Maldives'
|
||||||
|
ML: 'Mali'
|
||||||
|
MT: 'Malta'
|
||||||
|
MH: 'Marshall Islands'
|
||||||
|
MQ: 'Martinique'
|
||||||
|
MR: 'Mauritania'
|
||||||
|
MU: 'Mauritius'
|
||||||
|
YT: 'Mayotte'
|
||||||
|
MX: 'Mexico'
|
||||||
|
FM: 'Micronesia, Federated States Of'
|
||||||
|
MD: 'Moldova, Republic Of'
|
||||||
|
MC: 'Monaco'
|
||||||
|
MN: 'Mongolia'
|
||||||
|
MS: 'Montserrat'
|
||||||
|
ME: 'Montenegro'
|
||||||
|
MA: 'Morocco'
|
||||||
|
MZ: 'Mozambique'
|
||||||
|
MM: 'Myanmar'
|
||||||
|
NA: 'Namibia'
|
||||||
|
NR: 'Nauru'
|
||||||
|
NP: 'Nepal'
|
||||||
|
NL: 'Netherlands'
|
||||||
|
AN: 'Netherlands Antilles'
|
||||||
|
NC: 'New Caledonia'
|
||||||
|
NZ: 'New Zealand'
|
||||||
|
NI: 'Nicaragua'
|
||||||
|
NE: 'Niger'
|
||||||
|
NG: 'Nigeria'
|
||||||
|
NU: 'Niue'
|
||||||
|
NF: 'Norfolk Island'
|
||||||
|
MP: 'Northern Mariana Islands'
|
||||||
|
NO: 'Norway'
|
||||||
|
OM: 'Oman'
|
||||||
|
PK: 'Pakistan'
|
||||||
|
PW: 'Palau'
|
||||||
|
PS: 'Palestinian Territory, Occupied'
|
||||||
|
PA: 'Panama'
|
||||||
|
PG: 'Papua New Guinea'
|
||||||
|
PY: 'Paraguay'
|
||||||
|
PE: 'Peru'
|
||||||
|
PH: 'Philippines'
|
||||||
|
PN: 'Pitcairn'
|
||||||
|
PL: 'Poland'
|
||||||
|
PT: 'Portugal'
|
||||||
|
PR: 'Puerto Rico'
|
||||||
|
QA: 'Qatar'
|
||||||
|
RE: 'Reunion'
|
||||||
|
RO: 'Romania'
|
||||||
|
RU: 'Russian Federation'
|
||||||
|
RW: 'Rwanda'
|
||||||
|
SH: 'Saint Helena'
|
||||||
|
KN: 'Saint Kitts And Nevis'
|
||||||
|
LC: 'Saint Lucia'
|
||||||
|
PM: 'Saint Pierre And Miquelon'
|
||||||
|
VC: 'Saint Vincent And The Grenadines'
|
||||||
|
WS: 'Samoa'
|
||||||
|
SM: 'San Marino'
|
||||||
|
ST: 'Sao Tome And Principe'
|
||||||
|
SA: 'Saudi Arabia'
|
||||||
|
SN: 'Senegal'
|
||||||
|
RS: 'Serbia'
|
||||||
|
SC: 'Seychelles'
|
||||||
|
SL: 'Sierra Leone'
|
||||||
|
SG: 'Singapore'
|
||||||
|
SK: 'Slovakia'
|
||||||
|
SI: 'Slovenia'
|
||||||
|
SB: 'Solomon Islands'
|
||||||
|
SO: 'Somalia'
|
||||||
|
ZA: 'South Africa'
|
||||||
|
GS: 'South Georgia And The South Sandwich Islands'
|
||||||
|
ES: 'Spain'
|
||||||
|
LK: 'Sri Lanka'
|
||||||
|
SD: 'Sudan'
|
||||||
|
SR: 'Suriname'
|
||||||
|
SJ: 'Svalbard And Jan Mayen'
|
||||||
|
SZ: 'Swaziland'
|
||||||
|
SE: 'Sweden'
|
||||||
|
CH: 'Switzerland'
|
||||||
|
SY: 'Syrian Arab Republic'
|
||||||
|
TW: 'Taiwan, Province Of China'
|
||||||
|
TJ: 'Tajikistan'
|
||||||
|
TZ: 'Tanzania, United Republic Of'
|
||||||
|
TH: 'Thailand'
|
||||||
|
TG: 'Togo'
|
||||||
|
TK: 'Tokelau'
|
||||||
|
TO: 'Tonga'
|
||||||
|
TT: 'Trinidad And Tobago'
|
||||||
|
TN: 'Tunisia'
|
||||||
|
TR: 'Turkey'
|
||||||
|
TM: 'Turkmenistan'
|
||||||
|
TC: 'Turks And Caicos Islands'
|
||||||
|
TV: 'Tuvalu'
|
||||||
|
UG: 'Uganda'
|
||||||
|
UA: 'Ukraine'
|
||||||
|
AE: 'United Arab Emirates'
|
||||||
|
GB: 'United Kingdom'
|
||||||
|
US: 'United States'
|
||||||
|
UM: 'United States Minor Outlying Islands'
|
||||||
|
UY: 'Uruguay'
|
||||||
|
UZ: 'Uzbekistan'
|
||||||
|
VU: 'Vanuatu'
|
||||||
|
VE: 'Venezuela'
|
||||||
|
VN: 'Viet Nam'
|
||||||
|
VG: 'Virgin Islands, British'
|
||||||
|
VI: 'Virgin Islands, U.s.'
|
||||||
|
WF: 'Wallis And Futuna'
|
||||||
|
EH: 'Western Sahara'
|
||||||
|
YE: 'Yemen'
|
||||||
|
ZM: 'Zambia'
|
||||||
|
ZW: 'Zimbabwe'
|
||||||
|
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
||||||
{ name: 'note', display: 'Note', tag: 'textarea', limit: 250, null: true },
|
{ name: 'note', display: 'Note', tag: 'textarea', limit: 250, null: true },
|
||||||
#{ name: 'public', display: 'Public', tag: 'boolean', default: true },
|
{ name: 'max_queue', display: 'Max. clients in waitlist', tag: 'input', default: 2 },
|
||||||
{ name: 'max_queue', display: 'Max. clients in waitlist', tag: 'input', default: 2 },
|
{ name: 'block_ip', display: 'Blocked IPs (separated by ;)', tag: 'input', default: '', null: true },
|
||||||
|
{ name: 'block_country', display: 'Blocked contries', tag: 'column_select', multiple: true, null: true, default: '', options: @countries, seperator: ';' },
|
||||||
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
||||||
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||||
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
||||||
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
<% if @attribute.seperator: %>
|
||||||
|
<input class="js-shadow hide" id="<%= @attribute.id %>" name="<%= @attribute.name %>" value="<%= @attribute.value %>">
|
||||||
|
<% else: %>
|
||||||
<select
|
<select
|
||||||
class="columnSelect-shadow js-shadow"
|
class="columnSelect-shadow js-shadow"
|
||||||
id="<%= @attribute.id %>"
|
id="<%= @attribute.id %>"
|
||||||
|
@ -11,6 +14,7 @@
|
||||||
<option value="<%= option.value %>" <%= ' selected' if option.selected %>><%= option.name %></option>
|
<option value="<%= option.value %>" <%= ' selected' if option.selected %>><%= option.name %></option>
|
||||||
<% end %>
|
<% end %>
|
||||||
</select>
|
</select>
|
||||||
|
<% end %>
|
||||||
<div class="columnSelect-column columnSelect-column--selected js-selected" data-name="<%= @attribute.name %>">
|
<div class="columnSelect-column columnSelect-column--selected js-selected" data-name="<%= @attribute.name %>">
|
||||||
<div class="u-placeholder u-unselectable js-placeholder<%= ' is-hidden' if @values.length %>"><%- @T('Nothing selected') %></div>
|
<div class="u-placeholder u-unselectable js-placeholder<%= ' is-hidden' if @values.length %>"><%- @T('Nothing selected') %></div>
|
||||||
<% for option in @attribute.options: %>
|
<% for option in @attribute.options: %>
|
||||||
|
|
|
@ -264,4 +264,46 @@ optional you can put the max oldest chat sessions as argument
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
check if ip address is blocked for chat
|
||||||
|
|
||||||
|
chat = Chat.find(123)
|
||||||
|
chat.blocked_ip?(ip)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def blocked_ip?(ip)
|
||||||
|
return false if ip.blank?
|
||||||
|
return false if block_ip.blank?
|
||||||
|
ips = block_ip.split(';')
|
||||||
|
ips.each do |local_ip|
|
||||||
|
return true if ip == local_ip.strip
|
||||||
|
return true if ip.match?(/#{local_ip.strip.gsub(/\*/, '.+?')}/)
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
check if country is blocked for chat
|
||||||
|
|
||||||
|
chat = Chat.find(123)
|
||||||
|
chat.blocked_country?(ip)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def blocked_country?(ip)
|
||||||
|
return false if ip.blank?
|
||||||
|
retunn false if block_country.blank?
|
||||||
|
geo_ip = Service::GeoIp.location(ip)
|
||||||
|
return false if geo_ip.blank?
|
||||||
|
return false if geo_ip['country_code'].blank?
|
||||||
|
countries = block_country.split(';')
|
||||||
|
countries.each do |local_country|
|
||||||
|
return true if geo_ip['country_code'] == local_country
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -467,6 +467,8 @@ class CreateTicket < ActiveRecord::Migration[4.2]
|
||||||
t.string :note, limit: 250, null: true
|
t.string :note, limit: 250, null: true
|
||||||
t.boolean :active, null: false, default: true
|
t.boolean :active, null: false, default: true
|
||||||
t.boolean :public, null: false, default: false
|
t.boolean :public, null: false, default: false
|
||||||
|
t.string :block_ip, limit: 5000, null: true
|
||||||
|
t.string :block_country, limit: 5000, null: true
|
||||||
t.string :preferences, limit: 5000, null: true
|
t.string :preferences, limit: 5000, null: true
|
||||||
t.integer :updated_by_id, null: false
|
t.integer :updated_by_id, null: false
|
||||||
t.integer :created_by_id, null: false
|
t.integer :created_by_id, null: false
|
||||||
|
|
10
db/migrate/20180128000001_chat_add_ip_country.rb
Normal file
10
db/migrate/20180128000001_chat_add_ip_country.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class ChatAddIpCountry < ActiveRecord::Migration[5.1]
|
||||||
|
def up
|
||||||
|
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.find_by(name: 'system_init_done')
|
||||||
|
|
||||||
|
add_column :chats, :block_ip, :string, limit: 5000, null: true
|
||||||
|
add_column :chats, :block_country, :string, limit: 5000, null: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,6 +3,8 @@ class Sessions::Event::ChatStatusCustomer < Sessions::Event::ChatBase
|
||||||
def run
|
def run
|
||||||
return super if super
|
return super if super
|
||||||
return if !check_chat_exists
|
return if !check_chat_exists
|
||||||
|
return if !check_chat_block_by_ip
|
||||||
|
return if !check_chat_block_by_country
|
||||||
|
|
||||||
# check if it's a chat sessin reconnect
|
# check if it's a chat sessin reconnect
|
||||||
session_id = nil
|
session_id = nil
|
||||||
|
@ -32,4 +34,30 @@ class Sessions::Event::ChatStatusCustomer < Sessions::Event::ChatBase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_chat_block_by_ip
|
||||||
|
chat = current_chat
|
||||||
|
return true if !chat.blocked_ip?(@remote_ip)
|
||||||
|
error = {
|
||||||
|
event: 'chat_error',
|
||||||
|
data: {
|
||||||
|
state: 'chat_unavailable',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Sessions.send(@client_id, error)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_chat_block_by_country
|
||||||
|
chat = current_chat
|
||||||
|
return true if !chat.blocked_country?(@remote_ip)
|
||||||
|
error = {
|
||||||
|
event: 'chat_error',
|
||||||
|
data: {
|
||||||
|
state: 'chat_unavailable',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Sessions.send(@client_id, error)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ class ChatTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
groups = Group.all
|
groups = Group.all
|
||||||
roles = Role.where( name: %w[Agent] )
|
roles = Role.where(name: %w[Agent])
|
||||||
@agent1 = User.create_or_update(
|
@agent1 = User.create_or_update(
|
||||||
login: 'ticket-chat-agent1@example.com',
|
login: 'ticket-chat-agent1@example.com',
|
||||||
firstname: 'Notification',
|
firstname: 'Notification',
|
||||||
|
@ -352,4 +352,38 @@ class ChatTest < ActiveSupport::TestCase
|
||||||
travel_back
|
travel_back
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'blocked ip test' do
|
||||||
|
chat = Chat.create!(
|
||||||
|
name: 'ip test',
|
||||||
|
max_queue: 5,
|
||||||
|
note: '',
|
||||||
|
block_ip: '127.0.0.1;127.0.0.2;127.1.0.*',
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_not(chat.blocked_ip?('128.0.0.1'))
|
||||||
|
assert_not(chat.blocked_ip?('127.0.0.30'))
|
||||||
|
assert(chat.blocked_ip?('127.0.0.1'))
|
||||||
|
assert(chat.blocked_ip?('127.0.0.2'))
|
||||||
|
assert(chat.blocked_ip?('127.1.0.1'))
|
||||||
|
assert(chat.blocked_ip?('127.1.0.100'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'blocked country test' do
|
||||||
|
chat = Chat.create!(
|
||||||
|
name: 'country test',
|
||||||
|
max_queue: 5,
|
||||||
|
note: '',
|
||||||
|
block_country: 'AU;CH',
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_not(chat.blocked_country?('127.0.0.1'))
|
||||||
|
assert(chat.blocked_country?('1.1.1.8'))
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue