ronin-db-activerecord 0.1.6 → 0.2.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +91 -0
  3. data/README.md +49 -1
  4. data/db/migrate/0037_add_created_at_column_to_ronin_ports_table.rb +40 -0
  5. data/db/migrate/0038_add_created_at_column_to_ronin_services_table.rb +40 -0
  6. data/db/migrate/0039_create_ronin_cert_names_table.rb +37 -0
  7. data/db/migrate/0040_create_ronin_cert_issuers_table.rb +52 -0
  8. data/db/migrate/0041_create_ronin_cert_subjects_table.rb +54 -0
  9. data/db/migrate/0042_create_ronin_cert_subject_alt_names_table.rb +42 -0
  10. data/db/migrate/0043_create_ronin_certs_table.rb +61 -0
  11. data/db/migrate/0044_add_cert_id_column_to_ronin_open_ports_table.rb +35 -0
  12. data/db/migrate/0045_create_ronin_notes_table.rb +120 -0
  13. data/db/migrate/0046_create_ronin_web_vulns_table.rb +61 -0
  14. data/db/migrate/0047_create_ronin_phone_numbers_table.rb +47 -0
  15. data/db/migrate/0048_create_ronin_street_addresses_table.rb +46 -0
  16. data/db/migrate/0049_create_ronin_people_table.rb +48 -0
  17. data/db/migrate/0050_create_ronin_personal_connections_table.rb +48 -0
  18. data/db/migrate/0051_create_ronin_personal_phone_numbers_table.rb +48 -0
  19. data/db/migrate/0052_create_ronin_personal_email_addresses_table.rb +45 -0
  20. data/db/migrate/0053_create_ronin_personal_street_addresses_table.rb +47 -0
  21. data/db/migrate/0054_add_type_column_to_ronin_organizations_table.rb +33 -0
  22. data/db/migrate/0055_add_parent_id_column_to_ronin_organizations_table.rb +43 -0
  23. data/db/migrate/0056_create_ronin_organization_departments_table.rb +59 -0
  24. data/db/migrate/0057_create_ronin_organization_members_table.rb +62 -0
  25. data/db/migrate/0058_create_ronin_organization_customers_table.rb +52 -0
  26. data/db/migrate/0059_create_ronin_organization_phone_numbers_table.rb +47 -0
  27. data/db/migrate/0060_create_ronin_organization_email_addresses_table.rb +45 -0
  28. data/db/migrate/0061_create_ronin_organization_street_addresses_table.rb +47 -0
  29. data/db/migrate/0062_add_source_ip_column_to_http_requests_table.rb +30 -0
  30. data/db/migrate/0063_create_ronin_dns_queries_table.rb +41 -0
  31. data/db/migrate/0064_create_ronin_dns_records_table.rb +42 -0
  32. data/db/migrate/0065_create_ronin_organization_host_names_table.rb +43 -0
  33. data/db/migrate/0066_create_ronin_organization_ip_addresses_table.rb +43 -0
  34. data/gemspec.yml +1 -1
  35. data/lib/ronin/db/address.rb +1 -1
  36. data/lib/ronin/db/advisory.rb +66 -1
  37. data/lib/ronin/db/arch.rb +1 -1
  38. data/lib/ronin/db/asn.rb +15 -1
  39. data/lib/ronin/db/cert.rb +501 -0
  40. data/lib/ronin/db/cert_issuer.rb +78 -0
  41. data/lib/ronin/db/cert_name.rb +107 -0
  42. data/lib/ronin/db/cert_organization.rb +127 -0
  43. data/lib/ronin/db/cert_subject.rb +81 -0
  44. data/lib/ronin/db/cert_subject_alt_name.rb +88 -0
  45. data/lib/ronin/db/credential.rb +10 -1
  46. data/lib/ronin/db/dns_query.rb +98 -0
  47. data/lib/ronin/db/dns_record.rb +76 -0
  48. data/lib/ronin/db/email_address.rb +139 -1
  49. data/lib/ronin/db/host_name.rb +45 -1
  50. data/lib/ronin/db/host_name_ip_address.rb +1 -1
  51. data/lib/ronin/db/http_header_name.rb +1 -1
  52. data/lib/ronin/db/http_query_param.rb +1 -1
  53. data/lib/ronin/db/http_query_param_name.rb +1 -1
  54. data/lib/ronin/db/http_request.rb +13 -1
  55. data/lib/ronin/db/http_request_header.rb +1 -1
  56. data/lib/ronin/db/http_response.rb +1 -1
  57. data/lib/ronin/db/http_response_header.rb +1 -1
  58. data/lib/ronin/db/ip_address.rb +46 -1
  59. data/lib/ronin/db/ip_address_mac_address.rb +1 -1
  60. data/lib/ronin/db/mac_address.rb +28 -1
  61. data/lib/ronin/db/migrations.rb +1 -1
  62. data/lib/ronin/db/model/has_name.rb +18 -1
  63. data/lib/ronin/db/model/has_unique_name.rb +1 -1
  64. data/lib/ronin/db/model/importable.rb +1 -1
  65. data/lib/ronin/db/model/last_scanned_at.rb +1 -1
  66. data/lib/ronin/db/model.rb +1 -1
  67. data/lib/ronin/db/models.rb +44 -2
  68. data/lib/ronin/db/note.rb +199 -0
  69. data/lib/ronin/db/open_port.rb +104 -3
  70. data/lib/ronin/db/organization.rb +237 -3
  71. data/lib/ronin/db/organization_customer.rb +73 -0
  72. data/lib/ronin/db/organization_department.rb +97 -0
  73. data/lib/ronin/db/organization_email_address.rb +66 -0
  74. data/lib/ronin/db/organization_host_name.rb +65 -0
  75. data/lib/ronin/db/organization_ip_address.rb +65 -0
  76. data/lib/ronin/db/organization_member.rb +158 -0
  77. data/lib/ronin/db/organization_phone_number.rb +66 -0
  78. data/lib/ronin/db/organization_street_address.rb +66 -0
  79. data/lib/ronin/db/os.rb +35 -1
  80. data/lib/ronin/db/os_guess.rb +1 -1
  81. data/lib/ronin/db/password.rb +84 -1
  82. data/lib/ronin/db/person.rb +455 -0
  83. data/lib/ronin/db/personal_connection.rb +110 -0
  84. data/lib/ronin/db/personal_email_address.rb +66 -0
  85. data/lib/ronin/db/personal_phone_number.rb +76 -0
  86. data/lib/ronin/db/personal_street_address.rb +66 -0
  87. data/lib/ronin/db/phone_number.rb +330 -0
  88. data/lib/ronin/db/port.rb +110 -1
  89. data/lib/ronin/db/service.rb +130 -1
  90. data/lib/ronin/db/service_credential.rb +1 -1
  91. data/lib/ronin/db/software.rb +37 -1
  92. data/lib/ronin/db/software_vendor.rb +1 -1
  93. data/lib/ronin/db/street_address.rb +340 -0
  94. data/lib/ronin/db/url.rb +37 -1
  95. data/lib/ronin/db/url_query_param.rb +1 -1
  96. data/lib/ronin/db/url_query_param_name.rb +9 -1
  97. data/lib/ronin/db/url_scheme.rb +1 -1
  98. data/lib/ronin/db/user_name.rb +58 -1
  99. data/lib/ronin/db/vulnerability.rb +1 -1
  100. data/lib/ronin/db/web_credential.rb +1 -1
  101. data/lib/ronin/db/web_vuln.rb +348 -0
  102. metadata +57 -2
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-db-activerecord is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/db/model'
22
+
23
+ module Ronin
24
+ module DB
25
+ #
26
+ # Base class for {CertIssuer} and {CertSubject}.
27
+ #
28
+ # @since 0.2.0
29
+ #
30
+ class CertOrganization < ActiveRecord::Base
31
+
32
+ include Model
33
+
34
+ self.abstract_class = true
35
+
36
+ # @!attribute [rw] id
37
+ # The primary key of the certificate organization.
38
+ #
39
+ # @return [Integer]
40
+ attribute :id, :integer
41
+
42
+ # @!attribute [rw] organization
43
+ # The organization name (`O`).
44
+ #
45
+ # @return [String]
46
+ attribute :organization, :string
47
+ validates :organization, presence: true
48
+
49
+ # @!attribute [rw] organizational_unit
50
+ # The organizational unit (`OU`).
51
+ #
52
+ # @return [String, nil]
53
+ attribute :organizational_unit, :string
54
+
55
+ # @!attribute [rw] locality
56
+ # The locality (`L`)..
57
+ #
58
+ # @return [String, nil]
59
+ attribute :locality, :string
60
+
61
+ # @!attribute [rw] state
62
+ # The state (`ST`).
63
+ #
64
+ # @return [String, nil]
65
+ attribute :state, :string
66
+
67
+ # @!attribute [rw] country
68
+ # The two letter country code (`C`).
69
+ #
70
+ # @return [String]
71
+ attribute :country, :string
72
+ validates :country, presence: true,
73
+ length: {is: 2}
74
+
75
+ # @!attribute [rw] created_at
76
+ # When the organization was first created.
77
+ #
78
+ # @return [Time]
79
+ attribute :created_at, :datetime
80
+
81
+ # Mapping of X509 names to Symbols.
82
+ #
83
+ # @api private
84
+ X509_ATTRIBUTES = {
85
+ 'CN' => :common_name,
86
+ 'emailAddress' => :email_address,
87
+ 'O' => :organization,
88
+ 'OU' => :organizational_unit,
89
+ 'L' => :locality,
90
+ 'ST' => :state,
91
+ 'C' => :country
92
+ }
93
+
94
+ #
95
+ # Parses an X509 Name into attributes.
96
+ #
97
+ # @param [OpenSSL::X509::Name, String] name
98
+ # The X509 name to parse.
99
+ #
100
+ # @return [Hash{Symbol => String}]
101
+ # The parsed attributes.
102
+ #
103
+ # @api private
104
+ #
105
+ def self.parse(name)
106
+ x509_name = case name
107
+ when OpenSSL::X509::Name then name
108
+ when String
109
+ OpenSSL::X509::Name.parse(name)
110
+ else
111
+ raise(ArgumentError,"value must be either an OpenSSL::X509::Name or a String: #{name.inspect}")
112
+ end
113
+
114
+ attributes = {}
115
+
116
+ x509_name.to_a.each do |(oid,value,type)|
117
+ if (key = X509_ATTRIBUTES[oid])
118
+ attributes[key] = value.force_encoding(Encoding::UTF_8)
119
+ end
120
+ end
121
+
122
+ return attributes
123
+ end
124
+
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-db-activerecord is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/db/cert_organization'
22
+
23
+ module Ronin
24
+ module DB
25
+ #
26
+ # Represents an subject of a SSL/TLS certificate.
27
+ #
28
+ # @since 0.2.0
29
+ #
30
+ class CertSubject < CertOrganization
31
+
32
+ # @!attribute [rw] common_name
33
+ # The subject's common name (`CN`).
34
+ #
35
+ # @return [CertName]
36
+ belongs_to :common_name, class_name: 'CertName',
37
+ required: true
38
+ validates :common_name, uniqueness: {
39
+ scope: [
40
+ :email_address,
41
+ :organization,
42
+ :organizational_unit,
43
+ :locality,
44
+ :state,
45
+ :country
46
+ ]
47
+ }
48
+
49
+ # @!attribute [rw] certs
50
+ # The certificates that share this subject information.
51
+ #
52
+ # @return [Array<Cert>]
53
+ has_many :certs, foreign_key: :subject_id,
54
+ dependent: :destroy
55
+
56
+ #
57
+ # Imports the certificate subject's X509 distinguished name.
58
+ #
59
+ # @param [OpenSSL::X509::Name, String] name
60
+ # The X509 name to parse and import.
61
+ #
62
+ # @return [CertSubject]
63
+ # The imported or pre-existing certificate subject.
64
+ #
65
+ # @api private
66
+ #
67
+ def self.import(name)
68
+ attributes = parse(name)
69
+ common_name = attributes.fetch(:common_name)
70
+
71
+ attributes[:common_name] = CertName.find_or_import(common_name)
72
+
73
+ return find_or_create_by(attributes)
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+
80
+ require 'ronin/db/cert_name'
81
+ require 'ronin/db/cert'
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-db-activerecord is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/db/model'
22
+
23
+ require 'ipaddr'
24
+
25
+ module Ronin
26
+ module DB
27
+ #
28
+ # Represents a `subjectAltName` value from a SSL/TLS certificate.
29
+ #
30
+ # @since 0.2.0
31
+ #
32
+ class CertSubjectAltName < ActiveRecord::Base
33
+
34
+ include Model
35
+
36
+ # @!attribute [rw] id
37
+ # The primary key of the certificate `subjectAltName` value.
38
+ #
39
+ # @return [Integer]
40
+ attribute :id, :integer
41
+
42
+ # @!attribute [rw] name
43
+ # A `DNS:`, `IP:`, or `Email:` name.
44
+ #
45
+ # @return [CertName]
46
+ belongs_to :name, class_name: 'CertName',
47
+ required: true
48
+
49
+ # @!attribute [rw] cert
50
+ # The parent certificate.
51
+ #
52
+ # @return [Cert]
53
+ belongs_to :cert, required: true
54
+
55
+ #
56
+ # Parses a `subjectAltName` string.
57
+ #
58
+ # @param [String] string
59
+ # The `subjectAltName` string.
60
+ #
61
+ # @return [Array<String>]
62
+ # The parsed `subjectAltName`s.
63
+ #
64
+ # @api private
65
+ #
66
+ def self.parse(string)
67
+ string.split(', ').map do |item|
68
+ _prefix, name = item.split(':',2)
69
+
70
+ name
71
+ end
72
+ end
73
+
74
+ #
75
+ # Converts the certificate `subjectAltName` to a String.
76
+ #
77
+ # @return [String]
78
+ #
79
+ def to_s
80
+ name.to_s
81
+ end
82
+
83
+ end
84
+ end
85
+ end
86
+
87
+ require 'ronin/db/cert_name'
88
+ require 'ronin/db/cert'
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
4
  #
5
- # Copyright (c) 2022-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Lesser General Public License as published
@@ -85,6 +85,14 @@ module Ronin
85
85
  # @return [Array<URL>]
86
86
  has_many :urls, through: :web_credentials
87
87
 
88
+ # @!attribute [rw] notes
89
+ # The associated notes.
90
+ #
91
+ # @return [Array<Note>]
92
+ #
93
+ # @since 0.2.0
94
+ has_many :notes, dependent: :destroy
95
+
88
96
  #
89
97
  # Searches for all credentials for a specific user.
90
98
  #
@@ -246,3 +254,4 @@ require 'ronin/db/email_address'
246
254
  require 'ronin/db/password'
247
255
  require 'ronin/db/service_credential'
248
256
  require 'ronin/db/web_credential'
257
+ require 'ronin/db/note'
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-db-activerecord is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/db/model'
22
+
23
+ require 'active_record'
24
+ require 'resolv'
25
+
26
+ module Ronin
27
+ module DB
28
+ #
29
+ # Represents a DNS query.
30
+ #
31
+ # @since 0.2.0
32
+ #
33
+ class DNSQuery < ActiveRecord::Base
34
+
35
+ include Model
36
+
37
+ # @!attribute [rw] id
38
+ # The primary ID for the DNS query.
39
+ #
40
+ # @return [Integer]
41
+ attribute :id, :integer
42
+
43
+ # @!attribute [rw] type
44
+ # The queried record type.
45
+ #
46
+ # @return [String]
47
+ enum type: {
48
+ a: 'A',
49
+ aaaa: 'AAAA',
50
+ any: 'ANY',
51
+ cname: 'CNAME',
52
+ hinfo: 'HINFO',
53
+ loc: 'LOC',
54
+ mx: 'MX',
55
+ ns: 'NS',
56
+ ptr: 'PTR',
57
+ soa: 'SOA',
58
+ srv: 'SRV',
59
+ txt: 'TXT',
60
+ wks: 'WKS'
61
+ }, _suffix: :query
62
+ validates :type, presence: true
63
+
64
+ # @!attribute [rw] label
65
+ # The queried domain label.
66
+ #
67
+ # @return [String]
68
+ attribute :label, :string
69
+ validates :label, presence: true
70
+
71
+ # @!attribute [rw] source_addr
72
+ # The source IP Address.
73
+ #
74
+ # @return [String]
75
+ attribute :source_addr, :string
76
+ validates :source_addr, length: { maximum: 39 },
77
+ format: {
78
+ with: /#{Resolv::IPv4::Regex}|#{Resolv::IPv6::Regex}/,
79
+ message: 'Must be a valid IP address'
80
+ }
81
+
82
+ # @!attribute [rw] created_at
83
+ # When the DNS query request was created.
84
+ #
85
+ # @return [Time]
86
+ attribute :created_at, :datetime
87
+
88
+ # @!attribute [rw] records
89
+ # The optional DNS records associated with the DNS query.
90
+ #
91
+ # @return [Array<DNSRecord>]
92
+ has_many :records, class_name: 'DNSRecord'
93
+
94
+ end
95
+ end
96
+ end
97
+
98
+ require 'ronin/db/dns_record'
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
+ #
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
+ #
7
+ # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-db-activerecord is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-db-activerecord. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'ronin/db/model'
22
+
23
+ require 'active_record'
24
+
25
+ module Ronin
26
+ module DB
27
+ #
28
+ # Represents a DNS record.
29
+ #
30
+ # @since 0.2.0
31
+ #
32
+ class DNSRecord < ActiveRecord::Base
33
+
34
+ include Model
35
+
36
+ # @!attribute [rw] id
37
+ # The primary ID for the DNS record.
38
+ #
39
+ # @return [Integer]
40
+ attribute :id, :integer
41
+
42
+ # @!attribute [rw] ttl
43
+ # The Time-To-Live (TTL) for the DNS record.
44
+ #
45
+ # @return [Integer]
46
+ attribute :ttl, :integer
47
+ validates :ttl, presence: true
48
+
49
+ # @!attribute [rw] value
50
+ # The value of the DNS record.
51
+ #
52
+ # @return [String]
53
+ attribute :value, :string
54
+ validates :value, presence: true,
55
+ length: {maximum: 255}
56
+
57
+ # @!attribute [rw] dns_query
58
+ # The DNS query that the record belongs to.
59
+ #
60
+ # @return [DNSQuery]
61
+ belongs_to :dns_query
62
+
63
+ #
64
+ # Converts the DNS records into a String.
65
+ #
66
+ # @return [String]
67
+ #
68
+ def to_s
69
+ value
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+
76
+ require 'ronin/db/dns_query'
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # ronin-db-activerecord - ActiveRecord backend for the Ronin Database.
4
4
  #
5
- # Copyright (c) 2022-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
5
+ # Copyright (c) 2022-2024 Hal Brodigan (postmodern.mod3 at gmail.com)
6
6
  #
7
7
  # ronin-db-activerecord is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Lesser General Public License as published
@@ -80,12 +80,84 @@ module Ronin
80
80
  # @return [Array<Credential>]
81
81
  has_many :credentials, dependent: :destroy
82
82
 
83
+ # @!attribute [rw] passwords
84
+ # Any passwords used with the email address.
85
+ #
86
+ # @return [Array<EmailAddress>]
87
+ #
88
+ # @since 0.2.0
89
+ has_many :passwords, through: :credentials
90
+
91
+ # @!attribute [rw] service_credentials
92
+ # The service credentials that use the email address.
93
+ #
94
+ # @return [Array<ServiceCredential>]
95
+ #
96
+ # @since 0.2.0
97
+ has_many :service_credentials, through: :credentials
98
+
99
+ # @!attribute [rw] web_credentials
100
+ # Any web credentials that use the email address.
101
+ #
102
+ # @return [Array<WebCredential>]
103
+ #
104
+ # @since 0.2.0
105
+ has_many :web_credentials, through: :credentials
106
+
83
107
  # @!attribute [rw] created_at
84
108
  # Tracks when the email address was created at.
85
109
  #
86
110
  # @return [Time]
87
111
  attribute :created_at, :datetime
88
112
 
113
+ # @!attribute [rw] personal_email_addresses
114
+ # The association between people and the email address.
115
+ #
116
+ # @return [Array<PersonalEmailAddress>]
117
+ #
118
+ # @since 0.2.0
119
+ has_many :personal_email_addresses, dependent: :destroy
120
+
121
+ # @!attribute [rw] people
122
+ # The people that use the email address.
123
+ #
124
+ # @return [Array<Person>]
125
+ #
126
+ # @since 0.2.0
127
+ has_many :people, through: :personal_email_addresses
128
+
129
+ # @!attribute [rw] organization_email_address
130
+ # The association of the organization that use the email address.
131
+ #
132
+ # @return [OrganizationEmailAddress, nil]
133
+ #
134
+ # @since 0.2.0
135
+ has_one :organization_email_address, dependent: :destroy
136
+
137
+ # @!attribute [rw] organization_department
138
+ # The organization department that uses the email address.
139
+ #
140
+ # @return [OrganizationDepartment, nil]
141
+ #
142
+ # @since 0.2.0
143
+ has_one :organization_department, dependent: :nullify
144
+
145
+ # @!attribute [rw] organization_members
146
+ # The organization member that uses the email address.
147
+ #
148
+ # @return [OrganizationMember, nil]
149
+ #
150
+ # @since 0.2.0
151
+ has_one :organization_member, dependent: :nullify
152
+
153
+ # @!attribute [rw] notes
154
+ # The associated notes.
155
+ #
156
+ # @return [Array<Note>]
157
+ #
158
+ # @since 0.2.0
159
+ has_many :notes, dependent: :destroy
160
+
89
161
  #
90
162
  # Searches for email addresses associated with the given host name(s).
91
163
  #
@@ -131,6 +203,67 @@ module Ronin
131
203
  joins(:user_name).where(user_name: {name: name})
132
204
  end
133
205
 
206
+ #
207
+ # Queries all email addresses that are associated with the password.
208
+ #
209
+ # @param [String] password
210
+ # The plain-text password.
211
+ #
212
+ # @return [Array<EmailAddress>]
213
+ # The email addresses that are associated with the password.
214
+ #
215
+ # @api public
216
+ #
217
+ # @since 0.2.0
218
+ #
219
+ def self.with_password(password)
220
+ joins(credentials: :password).where(
221
+ credentials: {
222
+ ronin_passwords: {
223
+ plain_text: password
224
+ }
225
+ }
226
+ )
227
+ end
228
+
229
+ #
230
+ # Queries all email addresses that are associated with the person.
231
+ #
232
+ # @param [String] full_name
233
+ # The person's full name to search for.
234
+ #
235
+ # @return [Array<EmailAddress>]
236
+ # The email addresses that are associated with the person.
237
+ #
238
+ # @api public
239
+ #
240
+ # @since 0.2.0
241
+ #
242
+ def self.for_person(full_name)
243
+ joins(:people).where(people: {full_name: full_name})
244
+ end
245
+
246
+ #
247
+ # Queries all email addresses that are associated with the organization.
248
+ #
249
+ # @param [String] name
250
+ # The organization name to search for.
251
+ #
252
+ # @return [Array<EmailAddress>]
253
+ # The email addresses that are associated with the organization.
254
+ #
255
+ # @api public
256
+ #
257
+ # @since 0.2.0
258
+ #
259
+ def self.for_organization(name)
260
+ joins(organization_email_address: :organization).where(
261
+ organization_email_address: {
262
+ ronin_organizations: {name: name}
263
+ }
264
+ )
265
+ end
266
+
134
267
  #
135
268
  # Looks up the email address.
136
269
  #
@@ -223,3 +356,8 @@ end
223
356
 
224
357
  require 'ronin/db/user_name'
225
358
  require 'ronin/db/host_name'
359
+ require 'ronin/db/personal_email_address'
360
+ require 'ronin/db/organization_department'
361
+ require 'ronin/db/organization_email_address'
362
+ require 'ronin/db/organization_member'
363
+ require 'ronin/db/note'