egov_utils 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +92 -2
- data/app/models/egov_utils/user.rb +8 -2
- data/lib/egov_utils/auth_source.rb +40 -2
- data/lib/egov_utils/user_utils/application_controller_patch.rb +4 -2
- data/lib/egov_utils/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 339e97078108e7d4fbad0dfb86b2dc8a2a4d0d22
|
4
|
+
data.tar.gz: 4d2b4bcba50f2c9ce67dd093bc7ca11f0578c535
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bf7ae24fa68490735043ea48270c571f747089fe58337a7e9cfcfa8a5ea4303bec9baf4bc95dd999ba97d435dbfaa392de40c4d213191345f97c9657b11238f
|
7
|
+
data.tar.gz: 34c12fba18edb08e23fb66f383d8d535991da85cd794c2e493015e7cfa4dfb53024a34145afc6ab5c643911a9c49513a58dfbcea9a88ccec5cc6f660af3d16c4
|
data/README.md
CHANGED
@@ -1,8 +1,98 @@
|
|
1
|
+
[![pipeline status](https://git.servis.justice.cz/libraries/egov_utils-rails/badges/master/pipeline.svg)](https://git.servis.justice.cz/libraries/egov_utils-rails/commits/master)
|
1
2
|
# EgovUtils
|
2
|
-
|
3
|
+
This gem is set of utilities commonly used in Czech egoverment for rails application.
|
4
|
+
|
5
|
+
Main features:
|
6
|
+
* User roles/permissions
|
7
|
+
* Ldap integration
|
8
|
+
* Addresses/people storing and validation trough Egsb - ( uses egsb_gate gem )
|
9
|
+
* Usefull additions for bootstrap ( will be separeted in feature )
|
10
|
+
* Data visualization and retrievement api ( uses azahara_schema gem )
|
11
|
+
|
12
|
+
To be done:
|
13
|
+
* NIA integration
|
14
|
+
* ISDS SSO integration
|
3
15
|
|
4
16
|
## Usage
|
5
|
-
|
17
|
+
Framework uses configuration in file config/config.yml
|
18
|
+
|
19
|
+
### LDAP
|
20
|
+
LDAP parameters has to be configured in framework config file under the key `ldap`.
|
21
|
+
You can configure more than one ldap source. Framework will try all of them. But groups and users are resolved just by the one ldap controller where user resides.
|
22
|
+
Following example is for Active Directory ldap using userPrincipalName as username (prefered - in case of multidomain ldap controller it should be mandatory)
|
23
|
+
```yaml
|
24
|
+
ldap:
|
25
|
+
main:
|
26
|
+
label: 'Lab'
|
27
|
+
# host: dc01.servis.resort.cz
|
28
|
+
domain: servis.resort.cz
|
29
|
+
resolve_host: true
|
30
|
+
port: 389
|
31
|
+
uid: 'userPrincipalName'
|
32
|
+
method: 'tls'
|
33
|
+
kerberos: true
|
34
|
+
bind_dn: 'CN=Uzivatel LDAP aplikace ABC,OU=Servisni,DC=servis,DC=resort,DC=cz'
|
35
|
+
password: 'heslo uzivatele LDAP aplikace'
|
36
|
+
active_directory: true #enables specific Active Directory functions
|
37
|
+
base: 'OU=Appname,DC=servis,DC=resort,DC=cz'
|
38
|
+
onthefly_register: members
|
39
|
+
attributes:
|
40
|
+
username: ['userPrincipalName']
|
41
|
+
email: ['mail', 'email']
|
42
|
+
name: 'cn'
|
43
|
+
first_name: 'givenName'
|
44
|
+
last_name: 'sn'
|
45
|
+
```
|
46
|
+
#### Authentication to reading ldap and security
|
47
|
+
Authentication options are made trough `bind_dn` and `password` options.
|
48
|
+
`bind_dn` id DN of user with read permissions for all ldap tree ( or the subtree wich relates to this application ) and `password` is a password for this user.
|
49
|
+
|
50
|
+
#### Defining host
|
51
|
+
Host can be defined in option `host`, but in bigger ldap installation you would prefer to use selection of the host on DNS for load balancing purposes.
|
52
|
+
|
53
|
+
It can be done by defining option `domain` and `resolve_host: true`.
|
54
|
+
Framework will let DNS resolve the servis record `_ldap._tcp.<domain>` and select the first record.
|
55
|
+
It relies on resolution of this record to be sorted from less busy controller to most busy.
|
56
|
+
It is prefered method for bigger ldaps with load balancing demands.
|
57
|
+
|
58
|
+
Option `port` has to be defined if you are using `host` option.
|
59
|
+
For `resolve_host` option, you can leave out the host option and framework will use the port returned by DNS server.
|
60
|
+
But you can wish to define it anyway, if you have global catalog running on another port.
|
61
|
+
|
62
|
+
Option `method` is for defining a security protocol, wich shoul be used for comunication with the ldap controller.
|
63
|
+
* plain
|
64
|
+
* ssl
|
65
|
+
* tls
|
66
|
+
You should always use encrypted connection, so please consider plain method to be just for testing purposes to connect to the test ldap controller.
|
67
|
+
|
68
|
+
#### Base and attributes
|
69
|
+
First you have to specify, where to look for records of users and groups related to the application.
|
70
|
+
`base` could be just domain like `DC=servis,DC=resort,DC=cz`, but you should consider to narrowing the scope for performance purposes, so if your users and groups are in specific Organization Unit, you should define DN of the OU as a base.
|
71
|
+
|
72
|
+
Attributes defines mapping for attributes in LDAP to attributes in the application database.
|
73
|
+
If you are using activedirectory, you probably will want to keep the attributes same as in the example.
|
74
|
+
But if you want to change them, you can do it. They are pretty self expanatory.
|
75
|
+
|
76
|
+
#### Onthefly registration
|
77
|
+
This parameter defines if administartor has to create the accounts (add users from AD) manually, or it can be created (added) with first login.
|
78
|
+
|
79
|
+
Parameter `onthefly_register` set to `true` basically saying, that any user in the scope defined by `base` is allowed to login to the application.
|
80
|
+
It can be usefull for easy applications, where you create organization unit for them and special account for every user of the application.
|
81
|
+
Or on the other hand if the application is for whole resort and you specify the roles and permissions in the application.
|
82
|
+
|
83
|
+
|
84
|
+
More interesting is an option `members`.
|
85
|
+
With this option, framework will look in all groups added as groups in application and if the user is member of at least one of them, application will create the account.
|
86
|
+
Other users can be added manually by administrator. Membership in groups is looked for recursively.
|
87
|
+
|
88
|
+
#### Groups
|
89
|
+
You can add LDAP groups to the application groups and define roles and permissions to the groups.
|
90
|
+
Group membership is solved on the fly for the user, so it does´t depens on the order of making user a memmber of group and adding the group to the application.
|
91
|
+
Group membership is looked for recursively, so you can add one big group, define permissions for that group, add other groups as members and end users to this groups.
|
92
|
+
This ordering can be useful for more sub organizations, where every organization is managing its users permissions and then it is connected to the global AD catalog, where the application is queriing.
|
93
|
+
|
94
|
+
#### Kerberos
|
95
|
+
To be documented.
|
6
96
|
|
7
97
|
## Installation
|
8
98
|
Add this lines to your application's Gemfile:
|
@@ -87,7 +87,9 @@ module EgovUtils
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def all_role_names
|
90
|
-
@all_role_names ||=
|
90
|
+
@all_role_names ||= Rails.cache.fetch("#{cache_key}/all_role_names", expires_in: 1.hours) do
|
91
|
+
groups.collect{|g| g.roles}.reduce([], :concat) + roles
|
92
|
+
end
|
91
93
|
end
|
92
94
|
|
93
95
|
def all_roles
|
@@ -98,9 +100,13 @@ module EgovUtils
|
|
98
100
|
ldap_groups || []
|
99
101
|
end
|
100
102
|
|
103
|
+
def ldap_dn
|
104
|
+
@ldap_dn = auth_source.send(:get_user_dn, login)[:dn]
|
105
|
+
end
|
106
|
+
|
101
107
|
def ldap_groups
|
102
108
|
if provider.present?
|
103
|
-
EgovUtils::Group.where(provider: provider).to_a.select{|g|
|
109
|
+
EgovUtils::Group.where(provider: provider).to_a.select{|g| auth_source.member?(ldap_dn, g.ldap_uid) }
|
104
110
|
end
|
105
111
|
end
|
106
112
|
|
@@ -46,12 +46,31 @@ module EgovUtils
|
|
46
46
|
@options ||= self.class.config[provider].dup
|
47
47
|
end
|
48
48
|
|
49
|
+
# Resolves host name - it is used only if option <tt>:resolve_host</tt> is set to true and expect <tt>:domain</tt> to be defined as well.
|
50
|
+
# ldap controller host is resolved by asking for the <tt>_ldap._tcp.<domain></tt> DNS record and takes first - solve the load balancing of ldap queries.
|
51
|
+
def host_dns
|
52
|
+
require 'resolv'
|
53
|
+
@host_dns = Resolv::DNS.open do |dns|
|
54
|
+
dns.getresouce('_ldap._tcp.'+options['domain'], Resolv::DNS::Resource::IN::SRV)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get host of ldap controller from options.
|
59
|
+
#
|
60
|
+
# * <tt>:host</tt> - this just give one host and EgovUtils just asks that host
|
61
|
+
# * <tt>:domain</tt> with <tt>:resolve_host</tt> set to true. Domain should be domain for your ldap users.
|
62
|
+
# in this configuration ldap controller host is resolved by asking for the <tt>_ldap._tcp.<domain></tt> DNS record and takes first - solve the load balancing of ldap queries.
|
49
63
|
def host
|
50
|
-
options['host']
|
64
|
+
if options['host']
|
65
|
+
options['host']
|
66
|
+
elsif options['resolve_host'] && options['domain']
|
67
|
+
host_dns.target.to_s
|
68
|
+
end
|
51
69
|
end
|
52
70
|
|
71
|
+
# Returns ldap controller port. If <tt>:resolve_host</tt> is set to true and option for port is not defined, it uses port from DNS response.
|
53
72
|
def port
|
54
|
-
options['port']
|
73
|
+
options['resolve_host'] ? (options['port'] || host_dns.port.to_i) : options['port']
|
55
74
|
end
|
56
75
|
|
57
76
|
def encryption
|
@@ -146,6 +165,25 @@ module EgovUtils
|
|
146
165
|
raise AuthSourceException.new(e.message)
|
147
166
|
end
|
148
167
|
|
168
|
+
def member?(user_dn, group_sid)
|
169
|
+
ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
|
170
|
+
group_dn = nil
|
171
|
+
Rails.logger.debug("Membership in group for #{user_dn}")
|
172
|
+
ldap_con.search(base: options['base'],
|
173
|
+
filter: base_group_filter & Net::LDAP::Filter.eq('objectSID', group_sid),
|
174
|
+
attributes: ['dn']) do |entry|
|
175
|
+
group_dn = get_attr(entry, 'dn')
|
176
|
+
end
|
177
|
+
if group_dn
|
178
|
+
ldap_con.search(base: user_dn,
|
179
|
+
filter: base_user_filter & Net::LDAP::Filter.ex('memberOf:1.2.840.113556.1.4.1941', group_dn),
|
180
|
+
attributes: ['dn']) do |entry|
|
181
|
+
return true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
return false
|
185
|
+
end
|
186
|
+
|
149
187
|
def group_members(group_sid)
|
150
188
|
ldap_con = initialize_ldap_con(options['bind_dn'], options['password'])
|
151
189
|
group_dn = nil
|
@@ -55,8 +55,10 @@ module EgovUtils
|
|
55
55
|
logger.info(" Trying kerberos: #{username}") if logger
|
56
56
|
attrs = EgovUtils::AuthSource.find_kerberos_user(username)
|
57
57
|
if attrs
|
58
|
-
|
59
|
-
|
58
|
+
user = User.active.find_by(login: attrs[:login])
|
59
|
+
logger.info(" Found kerberos user: #{attrs[:login]} and it is in database") if logger && user
|
60
|
+
logged_user = user
|
61
|
+
user
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
data/lib/egov_utils/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: egov_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ondřej Ezr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-10-
|
11
|
+
date: 2017-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|