mobile-subscriber 1.0.0.alpha4 → 1.0.0.alpha5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mobile-subscriber.rb +13 -3
  3. data/lib/mobile_subscriber/dictionaries/dialing_and_country_codes.rb +468 -28
  4. data/lib/mobile_subscriber/http/known_imsi_headers.rb +22 -0
  5. data/lib/mobile_subscriber/http/known_msisdn_headers.rb +68 -0
  6. data/lib/mobile_subscriber/http/request_info.rb +166 -0
  7. data/lib/mobile_subscriber/identity.rb +97 -1
  8. data/lib/mobile_subscriber/version.rb +1 -1
  9. data/mobile_subscriber.thor +41 -0
  10. data/spec/factories/mobile_requests.rb +28 -0
  11. data/spec/factories/mobile_requests_from_claro.rb +257 -0
  12. data/spec/factories/mobile_requests_from_iusacell.rb +13 -0
  13. data/spec/factories/mobile_requests_from_movistar.rb +15 -0
  14. data/spec/factories/mobile_requests_from_telcel.rb +14 -0
  15. data/spec/factories/mobile_requests_from_vivo.rb +13 -0
  16. data/spec/features/claro_user_detection_spec.rb +170 -0
  17. data/spec/features/iusacell_user_detection_spec.rb +19 -0
  18. data/spec/features/movistar_user_detection_spec.rb +19 -0
  19. data/spec/features/telcel_user_detection_spec.rb +19 -0
  20. data/spec/models/{isdn_spec.rb → identity_spec.rb} +5 -5
  21. data/spec/shared_examples/identity_detection_in_argentina.rb +11 -0
  22. data/spec/shared_examples/identity_detection_in_brazil.rb +12 -0
  23. data/spec/shared_examples/identity_detection_in_chile.rb +12 -0
  24. data/spec/shared_examples/identity_detection_in_colombia.rb +12 -0
  25. data/spec/shared_examples/identity_detection_in_costa_rica.rb +15 -0
  26. data/spec/shared_examples/identity_detection_in_dominican_republic.rb +12 -0
  27. data/spec/shared_examples/identity_detection_in_ecuador.rb +12 -0
  28. data/spec/shared_examples/identity_detection_in_el_salvador.rb +15 -0
  29. data/spec/shared_examples/identity_detection_in_guatemala.rb +15 -0
  30. data/spec/shared_examples/identity_detection_in_honduras.rb +11 -0
  31. data/spec/shared_examples/identity_detection_in_mexico.rb +11 -0
  32. data/spec/shared_examples/identity_detection_in_nicaragua.rb +12 -0
  33. data/spec/shared_examples/identity_detection_in_panama.rb +12 -0
  34. data/spec/shared_examples/identity_detection_in_peru.rb +12 -0
  35. data/spec/shared_examples/identity_detection_in_puerto_rico.rb +14 -0
  36. data/spec/shared_examples/of_msisdn_detection_from_http_request.rb +3 -188
  37. data/templates/dialing_and_country_codes.rb.erb +20 -0
  38. metadata +58 -28
  39. data/lib/mobile_subscriber/detection/from_msisdn_http_request_header.rb +0 -48
  40. data/lib/mobile_subscriber/detection/from_x_nokia_msisdn_http_request_header.rb +0 -58
  41. data/lib/mobile_subscriber/detection/from_x_up_calling_line_id_http_request_header.rb +0 -65
  42. data/lib/mobile_subscriber/detection/from_x_up_ch_msisdn_http_request_header.rb +0 -35
  43. data/lib/mobile_subscriber/detection/from_x_up_subno_http_request_header.rb +0 -44
  44. data/lib/mobile_subscriber/detection/from_x_wap_msisdn_http_request_header.rb +0 -37
  45. data/lib/mobile_subscriber/detection/from_x_wap_sesiones3g_mdn_http_request_header.rb +0 -39
  46. data/lib/mobile_subscriber/detection/from_x_ztgo_beareraddress_http_request_header.rb +0 -36
  47. data/lib/mobile_subscriber/detection/http_request_info.rb +0 -77
  48. data/lib/mobile_subscriber/isdn.rb +0 -89
  49. data/spec/detection/from_msisdn_http_request_header_spec.rb +0 -53
  50. data/spec/detection/from_x_nokia_msisdn_http_request_header_spec.rb +0 -99
  51. data/spec/detection/from_x_up_calling_line_id_http_request_header_spec.rb +0 -39
  52. data/spec/detection/from_x_up_subno_http_request_header_spec.rb +0 -43
  53. data/spec/detection/from_x_wap_msisdn_http_request_header_spec.rb +0 -32
  54. data/spec/detection/from_x_wap_sesiones3g_mdn_http_request_header_spec.rb +0 -29
  55. data/spec/factories/requests.rb +0 -229
@@ -1,58 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
-
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
6
- # - Telcel México
7
- # - Claro Argentina
8
- # - Claro Costa Rica
9
- # - Claro Puerto Rico
10
- # - Claro Guatemala
11
- # - Claro Honduras
12
- # - Claro Nicaragua
13
- # - Claro El Salvador
14
- module FromXNokiaMsisdnHttpRequestHeader
15
-
16
- def extract_from_x_nokia_msisdn_http_request_header(http_request_info)
17
- if msisdn = http_request_info.headers['X-Nokia-Msisdn'] and msisdn.length >= 8
18
-
19
- country_code = (
20
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
21
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]] || # Dominican 3-digit needed
22
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,1]] # Puerto Rico 1-digit country code of "1"
23
- )
24
-
25
- # Determine the Network Operator tuple (MCC + MNC):
26
- # TODO: Validate IP ranges, additional headers, etc.
27
- network_id_tuple = case country_code
28
- when 'PR' # Claro Puerto Rico:
29
- { mcc: "330", mnc: "110" }
30
- when 'MX' # Telcel México:
31
- { mcc: "334", mnc: "020" }
32
- when 'GT' # Claro Guatemala:
33
- { mcc: "704", mnc: "01" }
34
- when 'SV' # Claro El Salvador:
35
- { mcc: "706", mnc: "01" }
36
- when 'HN' # Claro Honduras:
37
- { mcc: "708", mnc: "001" }
38
- when 'NI' # Claro Nicaragua:
39
- { mcc: "710", mnc: "21" }
40
- when 'CR' # Claro Costa Rica
41
- { mcc: "712", mnc: "03" }
42
- when 'AR' # Claro Argentina:
43
- { mcc: "722", mnc: "330" }
44
- end
45
-
46
- # Return only if we identified the network:
47
- if network_id_tuple.present?
48
- {
49
- id: msisdn,
50
- mobile_country_code: network_id_tuple[:mcc],
51
- mobile_network_code: network_id_tuple[:mnc],
52
- http_request_info: http_request_info
53
- }
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,65 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
-
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN por el
6
- # header de HTTP 'X-Up-Calling-Line-Id':
7
- # - Claro Perú
8
- # - TIM (Telecom Italia Mobile) Brasil
9
- # - OI Brasil
10
- # - Movistar México
11
- # - Movistar Argentina
12
- # - Movistar Perú
13
- module FromXUpCallingLineIdHttpRequestHeader
14
-
15
- def extract_from_x_up_calling_line_id_http_request_header(http_request_info)
16
- if msisdn = http_request_info.headers['X-Up-Calling-Line-Id'] and msisdn.length >= 8
17
-
18
- country_code = (
19
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
20
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
21
- )
22
-
23
- # Determine the Network Operator tuple (MCC + MNC):
24
- # TODO: Validate IP ranges, additional headers, etc.
25
- network_id_tuple = case country_code
26
- when 'PE'
27
- # Claro Perú includes the "X-Nokia-Imsi" header...
28
- imsi = http_request_info.headers['X-Nokia-Imsi']
29
- if imsi.present?
30
- # Claro Peru: (IP's 190.113.x)
31
- { mcc: "716", mnc: "10" } if imsi.start_with?('71610')
32
- else
33
- # Movistar Peru: (IP's 190.238.x)
34
- { mcc: "716", mnc: "06" }
35
- end
36
- when 'BR'
37
- if x_msp_apn_header = request.env["X-Msp-Apn"] and x_msp_apn_header.present?
38
- if http_request_x_msp_apn_header =~ /OI/i
39
- # Oi Brazil:
40
- { mcc: "724", mnc: "30" }
41
- else
42
- # TIM Brazil:
43
- { mcc: "724", mnc: "02" }
44
- end
45
- end
46
- when 'MX' # Movistar Mexico:
47
- { mcc: "334", mnc: "030" }
48
- when 'AR' # Movistar Argentina:
49
- # TODO: Determine (if possible) the MNC (010 or 070)
50
- { mcc: "722", mnc: "010" }
51
- end
52
-
53
- # Return only if we identified the network:
54
- if network_id_tuple.present?
55
- {
56
- id: msisdn,
57
- mobile_country_code: network_id_tuple[:mcc],
58
- mobile_network_code: network_id_tuple[:mnc],
59
- http_request_info: http_request_info
60
- }
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,35 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
- module MobileSubscriber::Detection
3
- # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
4
- # - Vivo Brasil
5
- module FromXUpChMsisdnHttpRequestHeader
6
-
7
- def extract_from_x_up_ch_msisdn_http_request_header(http_request_info)
8
- if msisdn = http_request_info.headers['X-Up-Ch-Msisdn'] and msisdn.length >= 8
9
-
10
- country_code = (
11
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
12
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
13
- )
14
-
15
- # Determine the Network Operator tuple (MCC + MNC):
16
- # TODO: Validate IP ranges, additional headers, etc.
17
- network_id_tuple = case country_code
18
- when 'BR' # Vivo Brazil:
19
- # TODO: Determine (if possible) the MNC (06, 10, 11, 23)
20
- { mcc: "724", mnc: "06" }
21
- end
22
-
23
- # Return only if we identified the network:
24
- if network_id_tuple.present?
25
- {
26
- id: msisdn,
27
- mobile_country_code: network_id_tuple[:mcc],
28
- mobile_network_code: network_id_tuple[:mnc],
29
- http_request_info: http_request_info
30
- }
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,44 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
- # Módulo que provee métodos de deteccion y validacion para MSISDN por el
5
- # header de HTTP 'X-Up-Subno':
6
- # - Claro Colombia
7
- # - Claro Panamá
8
- # - Comcel Colombia
9
- module FromXUpSubnoHttpRequestHeader
10
-
11
- def extract_from_x_up_subno_http_request_header(http_request_info)
12
- if msisdn = http_request_info.headers['X-Up-Subno'] and msisdn.length >= 8
13
-
14
- country_code = (
15
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
16
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
17
- )
18
-
19
- # Determine the Network Operator tuple (MCC + MNC):
20
- # TODO: Validate IP ranges, additional headers, etc.
21
- network_id_tuple = case country_code
22
- when 'CO'
23
- # TODO: Discernir por ip/hostname
24
- #{ mcc: "732", mnc: "101" } # Comcel Colombia
25
-
26
- # Claro Colombia
27
- { mcc: "732", mnc: "101" }
28
- when 'PA' # Claro Panamá:
29
- { mcc: "714", mnc: "03" }
30
- end
31
-
32
- # Return only if we identified the network:
33
- if network_id_tuple.present?
34
- {
35
- id: msisdn,
36
- mobile_country_code: network_id_tuple[:mcc],
37
- mobile_network_code: network_id_tuple[:mnc],
38
- http_request_info: http_request_info
39
- }
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,37 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
-
5
- # Módulo que provee métodos de detección y validacion para MSISDN por el
6
- # header de HTTP 'X-Wap-Msisdn':
7
- # - Claro Chile
8
- module FromXWapMsisdnHttpRequestHeader
9
-
10
- def extract_from_x_wap_msisdn_http_request_header(http_request_info)
11
- if msisdn = http_request_info.headers['X-Wap-Msisdn'] and msisdn.length >= 8
12
-
13
- country_code = (
14
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
15
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
16
- )
17
-
18
- # Determine the Network Operator tuple (MCC + MNC):
19
- # TODO: Validate IP ranges, additional headers, etc.
20
- network_id_tuple = case country_code
21
- when 'CL' # Claro Chile
22
- { mcc: "730", mnc: "03" }
23
- end
24
-
25
- # Return only if we identified the network:
26
- if network_id_tuple.present?
27
- {
28
- id: msisdn,
29
- mobile_country_code: network_id_tuple[:mcc],
30
- mobile_network_code: network_id_tuple[:mnc],
31
- http_request_info: http_request_info
32
- }
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,39 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
- # Módulo que provee métodos de detección y validacion para MSISDN por el
5
- # header de HTTP 'X-Wap-Sesiones3g-Mdn':
6
- # - Iusacell
7
- module FromXWapSesiones3gMdnHttpRequestHeader
8
-
9
- def extract_from_x_wap_sesiones3g_mdn_http_request_header(http_request_info)
10
- if msisdn = http_request_info.headers['X-Wap-Sesiones3g-Mdn'] and msisdn.length >= 8
11
-
12
- country_code = (
13
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
14
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
15
- )
16
-
17
- # Determine the Network Operator tuple (MCC + MNC):
18
- # TODO: Validate IP ranges, additional headers, etc.
19
- network_id_tuple = case country_code
20
- when 'MX' # Iusacell Mexico:
21
- # TODO: Determine (if possible) the MNC:
22
- # - MNC "040": Iusacell/Unefon
23
- # - MNC "050": Iusacell
24
- { mcc: "334", mnc: "040" }
25
- end
26
-
27
- # Return only if we identified the network:
28
- if network_id_tuple.present?
29
- {
30
- id: msisdn,
31
- mobile_country_code: network_id_tuple[:mcc],
32
- mobile_network_code: network_id_tuple[:mnc],
33
- http_request_info: http_request_info
34
- }
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,36 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
-
3
- module MobileSubscriber::Detection
4
- # Módulo que provee métodos de detección y validacion para MSISDN por el
5
- # header de HTTP 'X-Ztgo-Beareraddress':
6
- # - Movistar Ecuador
7
- module FromXZtgoBeareraddressHttpRequestHeader
8
-
9
- def extract_from_x_ztgo_beareraddress_http_request_header(http_request_info)
10
- if msisdn = http_request_info.headers['X-Ztgo-Beareraddress'] and msisdn.length >= 8
11
-
12
- country_code = (
13
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
14
- MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
15
- )
16
-
17
- # Determine the Network Operator tuple (MCC + MNC):
18
- # TODO: Validate IP ranges, additional headers, etc.
19
- network_id_tuple = case country_code
20
- when 'EC' # Movistar Ecuador:
21
- { mcc: "740", mnc: "00" }
22
- end
23
-
24
- # Return only if we identified the network:
25
- if network_id_tuple.present?
26
- {
27
- id: msisdn,
28
- mobile_country_code: network_id_tuple[:mcc],
29
- mobile_network_code: network_id_tuple[:mnc],
30
- http_request_info: http_request_info
31
- }
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,77 +0,0 @@
1
- module MobileSubscriber::Detection
2
- class HttpRequestInfo
3
- attr_reader :remote_ip, :headers
4
-
5
- def initialize(env)
6
-
7
- @remote_ip = env['REMOTE_ADDR']
8
-
9
- # Reference Links:
10
- # - http://www.slideshare.net/DefCamp/mobile-networks-exploiting-http-headers-and-data-traffic
11
- # - http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
12
- @headers = [
13
- # HTTP Headers that contain important request details for validation
14
- 'Max-Forwards', # Para validar el número de forwards que el cliente permite... muy pobre..
15
- 'Via',
16
- 'X-Forwarded-For', # lista de IP's que originaron la petición, en caso de pasar por proxies:
17
-
18
- # HTTP headers that contain the MSISDN:
19
- # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
20
- 'Cookie',
21
- 'Igcli',
22
- 'Msisdn',
23
- 'Rapmin',
24
- 'X-Fh-Msisdn',
25
- "X-H3-G-Msisdn",
26
- 'X-Hts-Clid',
27
- 'X-Jinny-Cid',
28
- 'X-Msisdn',
29
- 'X-Msp-Clid',
30
- 'X-Msp-Msisdn',
31
- 'X-Network-Info',
32
- 'X-Nokia-Imsi', # This is a VERY useful one... if you have it!
33
- 'X-Nokia-Msisdn',
34
- 'X-Nx-Clid',
35
- 'X-Orange-Cli',
36
- 'X-Up-Calling-Line',
37
- 'X-Up-Calling-Line-Id', # Not in referenced literature
38
- 'X-Up-Ch-Msisdn', # Not in referenced literature
39
- 'X-Up-Lsid',
40
- 'X-Up-Subno', # Not in referenced literature
41
- 'X-Wap-Fh-Subscriber-Info',
42
- 'X-Wap-Msisdn',
43
- 'X-Wap-Sesiones3g-Mdn', # Not in referenced literature
44
- 'X-Wsb-Cli',
45
- 'X-Ztgo-Beareraddress', # Not in referenced literature
46
-
47
- # Headers that contain bearer information:
48
- # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
49
- 'Bearer',
50
- 'Bearer-Indication',
51
- 'New-Bearer-Header',
52
- 'Nokia-Bearer',
53
- 'X-Nokia-Bearer',
54
- 'X-Nokia-Musicshop-Bearer',
55
- 'X-Up-Bear-Type', # NOT A TYPO
56
- 'X-Up-Bearer-Type',
57
- 'X-Bearer-Type',
58
-
59
- # Headers that contain roaming information:
60
- # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
61
- 'X-Orange-Roaming',
62
- 'X-Nokia-Roaming',
63
- 'X-Roaming',
64
- 'X-Sdp-Roaming'
65
- ].inject({}.with_indifferent_access) do |collected_headers, header_name|
66
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
67
-
68
- if env.has_key? header_env_key
69
- collected_headers[header_name] = env[header_env_key].strip
70
- end
71
-
72
- collected_headers
73
- end
74
-
75
- end
76
- end
77
- end
@@ -1,89 +0,0 @@
1
- require 'mobile_subscriber/dictionaries/mobile_and_iso_country_codes'
2
- require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
3
- require 'mobile_subscriber/dictionaries/operator_data'
4
-
5
- module MobileSubscriber
6
-
7
- class ISDN
8
-
9
- attr_reader :id, :mobile_country_code, :mobile_network_code, :http_request_info
10
- alias_method :to_s, :id
11
-
12
- extend MobileSubscriber::Detection::FromMsisdnHttpRequestHeader
13
- extend MobileSubscriber::Detection::FromXNokiaMsisdnHttpRequestHeader
14
- extend MobileSubscriber::Detection::FromXUpCallingLineIdHttpRequestHeader
15
- extend MobileSubscriber::Detection::FromXUpChMsisdnHttpRequestHeader
16
- extend MobileSubscriber::Detection::FromXUpSubnoHttpRequestHeader
17
- extend MobileSubscriber::Detection::FromXWapMsisdnHttpRequestHeader
18
- extend MobileSubscriber::Detection::FromXWapSesiones3gMdnHttpRequestHeader
19
- extend MobileSubscriber::Detection::FromXZtgoBeareraddressHttpRequestHeader
20
-
21
- def initialize(attributes={})
22
- @id = attributes.delete :id
23
- @mobile_country_code = attributes.delete :mobile_country_code
24
- @mobile_network_code = attributes.delete :mobile_network_code
25
- @http_request_info = attributes.delete :http_request_info
26
- end
27
-
28
- def dialing_code
29
- self.id[0,2]
30
- end
31
- alias_method :country_dialing_code, :dialing_code
32
-
33
- def iso_3166_country_code
34
- if self.mobile_country_code.present?
35
- MobileSubscriber::MCC_ISO_COUNTRY_CODES[self.mobile_country_code]
36
- end
37
- end
38
-
39
- def mobile_network_brand
40
- if self.mobile_country_code.present? && self.mobile_network_code.present?
41
- key = [self.mobile_country_code, self.mobile_network_code]
42
- MobileSubscriber::OPERATOR_DATA[key][:brand]
43
- end
44
- end
45
-
46
- def mobile_network_operator
47
- if self.mobile_country_code.present? && self.mobile_network_code.present?
48
- key = [self.mobile_country_code, self.mobile_network_code]
49
- MobileSubscriber::OPERATOR_DATA[key][:operator]
50
- end
51
- end
52
-
53
- def inspect
54
- "<MobileSubscriber::ISDN #{self.id} (#{self.http_validated? ? '' : 'not '}validated by HTTP)>"
55
- end
56
-
57
- def http_validated?
58
- @http_validated ||= false
59
- end
60
-
61
- # Creates a new MobileSubscriber::ISDN from a Rack::Request object
62
- def self.new_from_request(request)
63
- http_request_info = Detection::HttpRequestInfo.new request.env
64
-
65
- detection_results = self.methods.select do |x|
66
- x.to_s =~ /\Aextract_from_(\w+)_http_request_header\z/i
67
- end.map do |detection_method|
68
- self.send detection_method, http_request_info
69
- end.compact
70
-
71
- # TODO: Select first from a preference order:
72
- detection = detection_results.first if detection_results.any?
73
-
74
- if detection.present?
75
- validated_isdn = new(detection)
76
- validated_isdn.send :http_validated!
77
- validated_isdn
78
- end
79
- end
80
-
81
- protected
82
-
83
- def http_validated!
84
- @http_validated = true
85
- end
86
-
87
- end
88
-
89
- end