├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app
├── controllers
│ └── ldap_settings_controller.rb
├── helpers
│ └── ldap_settings_helper.rb
├── models
│ ├── ldap_setting.rb
│ └── ldap_test.rb
└── views
│ └── ldap_settings
│ ├── _ldap_settings.html.erb
│ ├── _synchronization_actions.html.erb
│ ├── _test.html.erb
│ ├── base_settings.js.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ ├── ldap_setting_invalid.text.erb
│ ├── ldap_test_invalid.text.erb
│ └── test.text.erb
├── assets
├── images
│ ├── disable.png
│ ├── enable.png
│ └── server_key.png
├── javascripts
│ └── ldap_settings.js
└── stylesheets
│ └── ldap_sync.css
├── config
├── Gemfile.travis
├── base_settings.yml
├── database.yml.travis
├── locales
│ ├── de.yml
│ ├── en.yml
│ ├── es.yml
│ ├── fr.yml
│ ├── ja.yml
│ ├── nl.yml
│ ├── pl.yml
│ ├── pt.yml
│ └── ru.yml
└── routes.rb
├── db
└── migrate
│ ├── 201108021245_change_settings_name.rb
│ ├── 201110050735_add_user_memberid_setting.rb
│ ├── 201111271700_add_group_membership_setting.rb
│ ├── 201201010043_create_ldap_cache_dir.rb
│ ├── 201201071359_update_attributes_to_sync.rb
│ ├── 201201291950_rename_must_be_member_of_and_add_to_group_settings.rb
│ ├── 201201302250_remove_attr_prefix_settings.rb
│ ├── 201202082153_add_account_flags_setting.rb
│ ├── 201211202050_update_check_box_values.rb
│ ├── 201302052050_update_user_group_fields.rb
│ ├── 201302202301_change_setting_id_from_name_to_auth_source_id.rb
│ ├── 201302212308_enable_sync_on_login.rb
│ ├── 201503252355_add_users_search_scope.rb
│ └── 20170524063056_rename_account_disabled_test.rb
├── doc
└── RUNNING_TESTS
├── init.rb
├── lib
├── ldap_sync
│ ├── core_ext.rb
│ ├── core_ext
│ │ ├── ber.rb
│ │ ├── file_store.rb
│ │ ├── ldap.rb
│ │ ├── ldap_entry.rb
│ │ ├── migration.rb
│ │ └── string.rb
│ ├── dry_run
│ │ ├── group.rb
│ │ └── user.rb
│ ├── entity_manager.rb
│ ├── hooks.rb
│ ├── infectors.rb
│ └── infectors
│ │ ├── auth_source_ldap.rb
│ │ ├── group.rb
│ │ └── user.rb
└── tasks
│ ├── ldap_sync.rake
│ └── testing.rake
├── script
└── ci.sh
└── test
├── fixtures
├── .gitkeep
├── auth_sources.yml
├── custom_fields.yml
├── email_addresses.yml
├── groups_users.yml
├── ldap
│ ├── large-ldap.lidf
│ ├── names.rb
│ ├── slapd.conf
│ └── test-ldap.ldif
├── member_roles.yml
├── members.yml
├── projects.yml
├── roles.yml
├── settings.yml
└── users.yml
├── functional
└── ldap_settings_controller_test.rb
├── integration
└── .gitkeep
├── performance
└── auth_source_ldap_performance_test.rb
├── test_helper.rb
├── ui
├── base.rb
├── ldap_setting_test.rb
└── login_test.rb
└── unit
├── auth_source_ldap_test.rb
├── helpers
└── ldap_settings_helper_test.rb
├── ldap_setting_test.rb
└── ldap_test_test.rb
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-ci
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage
2 | tmp
3 | Gemfile
4 | .svn
5 | .directory
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | sudo: false
3 | cache:
4 | directories:
5 | - workspace/redmine/vendor/bundle
6 | addons:
7 | apt:
8 | packages:
9 | - ldap-utils
10 | - slapd
11 | chrome: stable
12 | rvm:
13 | - 1.9.3
14 | - 2.3.6
15 | env:
16 | global: REDMINE_DIR=./workspace/redmine
17 | matrix:
18 | - REDMINE=3.2-stable
19 | - REDMINE=3.3-stable
20 | - REDMINE=master
21 | matrix:
22 | include:
23 | - rvm: 2.4.3
24 | env: REDMINE=3.4-stable
25 | - rvm: 2.4.3
26 | env: REDMINE=master
27 | exclude:
28 | - rvm: 1.9.3
29 | env: REDMINE=master
30 | gemfile: workspace/redmine/Gemfile
31 | bundler_args: --path vendor/bundle --gemfile workspace/redmine/Gemfile --without development rmagick
32 | before_install:
33 | - ./script/ci.sh clone_redmine --target $REDMINE_DIR
34 | - cp ./config/database.yml.travis $REDMINE_DIR/config/database.yml
35 | - ./script/ci.sh install_plugin_gemfile
36 | before_script:
37 | - mysql -e 'CREATE DATABASE redmine CHARACTER SET utf8;'
38 | - ./script/ci.sh prepare_redmine
39 | - ./script/ci.sh prepare_plugin
40 | - ./script/ci.sh start_ldap
41 | - 'phantomjs --webdriver 4444 2>&- 1>&- &'
42 | script:
43 | - ./script/ci.sh run_tests
44 | - ./script/ci.sh test_uninstall
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Redmine LDAP Sync
2 | --- forked from https://github.com/thorin/redmine_ldap_sync, which is unmaintained.
3 | This maintained version is tested working fine with Redmine4.x/Ruby2.6.x/Rails5.2.x
4 | Issues and PRs are welcome.
5 | Redmine site: http://www.redmine.org/plugins/redmine_ldap_sync
6 |
7 | Original readme:
8 | =================
9 |
10 | This redmine plugin extends the ldap authentication with user/group
11 | synchronization.
12 |
13 | __Features__:
14 |
15 | * Synchronization of user fields and groups on login.
16 | * Detects and disables users that have been removed from LDAP.
17 | * Detects and disables users that have been marked as disabled on Active
18 | Directory (see [MS KB Article 305144][uacf] for details).
19 | * Can detect and include nested groups. Upon login the nested groups are
20 | retrieved from disk cache. This cache can only be updated with the rake task.
21 | * A rake task is available for manual or periodic synchronization of groups and
22 | users.
23 |
24 | __Remarks__:
25 |
26 | * The plugin is prepared and intended to run with any LDAP directory. But, the
27 | author can only guarantee it to work correctly with Active Directory and
28 | Slapd.
29 | * An user will only be removed from groups that exist on LDAP. This behaviour
30 | is intended as it allows both ldap and non-ldap groups to coexist.
31 | * Deleted groups on LDAP will not be deleted on redmine.
32 |
33 | Installation & Upgrade
34 | ----------------------
35 |
36 | ### Install/Upgrade
37 |
38 | 1. **install.** - Copy your plugin directory into `#{RAILS_ROOT}/plugins`.
39 | If you are downloading the plugin directly from GitHub, you can do so by
40 | changing into the `#{RAILS_ROOT}/plugins` directory and issuing the command:
41 | ```
42 | git clone git://github.com/tainewoo/redmine_ldap_sync.git
43 | ```
44 |
45 | **upgrade** - Backup and replace the old plugin directory with the new
46 | plugin files. If you are downloading the plugin directly from GitHub, you
47 | can do so by changing into the plugin directory and issuing the command
48 | `git pull`.
49 |
50 | 2. Update the ruby gems by changing into the redmine's directory and run the
51 | following command.
52 | ```
53 | bundle install
54 | ```
55 |
56 | 3. **upgrade** - Still on the redmine's directory, run the following command
57 | to upgrade your database (make a db backup before).
58 | ```
59 | rake redmine:plugins:migrate RAILS_ENV=production
60 | ```
61 |
62 | 4. Change into redmine's directory `#{RAILS_ROOT}` and run the following
63 | command.
64 | ```
65 | rake -T redmine:plugins:ldap_sync RAILS_ENV=production
66 | ```
67 | If the installation/upgrade was successful you should now see the list of
68 | [Rake Tasks](#rake-tasks).
69 |
70 | 5. Restart Redmine.
71 |
72 | You should now be able to see **Redmine LDAP Sync** listed among the plugins in
73 | `Administration -> Plugins`.
74 |
75 | ### Uninstall
76 |
77 | 1. Change into redmine's directory `#{RAILS_ROOT}` and run the following
78 | command to downgrade the database (make a db backup before):
79 | ```
80 | rake redmine:plugins:migrate NAME=redmine_ldap_sync VERSION=0 RAILS_ENV=production
81 | ```
82 |
83 | 2. Remove the plugin from the plugins folder: `#{RAILS_ROOT}/plugins`
84 | 3. Restart Redmine.
85 |
86 | Usage
87 | -----
88 |
89 | ### Configuration
90 |
91 | Open `Administration > Ldap Synchronization` to access the plugin
92 | configuration:
93 |
94 | **LDAP settings:**
95 |
96 | + **Base settings** - Preloads the configuration with predefined settings.
97 | + **Group base DN** - The path to where the groups are located. Eg,
98 | `ou=people,dc=smokeyjoe,dc=com`.
99 | + **Groups objectclass** - The groups object class.
100 | + **Users objectclass** - The users object class.
101 | + **Users search scope** - One level or whole subtree.
102 | - **One level**: searches one level below the user base DN, i.e. all its immediate children only.
103 | - **Whole subtree**: searches the whole subtree rooted at user base DN.
104 | + **Group name pattern** - (optional) An RegExp that should match up with the
105 | name of the groups that should be imported. Eg, `\.team$`.
106 | + **Group search filter** - (optional) An LDAP search filter to be applied
107 | whenever search for groups.
108 | + **Account disabled test** - A ruby boolean expression that should evaluate an
109 | account's flags (the variable `flags`) and return `true` if the account is
110 | disabled. Eg., `flags.to_i & 2 != 0` or `flags.include? 'D'`.
111 | + **Group membership** - Specifies how to determine the user's group
112 | membership.
113 | The possible values are:
114 | - **On the group class**: membership determined from the list of users
115 | contained on the group.
116 | - **On the user class**: membership determined from the list of groups
117 | contained on the user.
118 | + **Enable nested groups** - Enables and specifies how to identify the groups
119 | nesting. When enabled the plugin will look for the groups' parent groups, and
120 | so on, and add those groups to the users. The possible values are:
121 | - **Membership on the parent class**: group membership determined from the
122 | list of groups contained on the parent group.
123 | - **Membership on the member class**: group membership determined from the
124 | list of groups contained on the member group.
125 |
126 | **LDAP attributes:**
127 |
128 | + **Group name (group)** - The ldap attribute from where to fetch the
129 | group's name. Eg, `sAMAccountName`.
130 | + **Account flags (user)** - The ldap attribute containing the account disabled
131 | flag. Eg., `userAccountControl`.
132 | + **Primary group (user)** - The ldap attribute that identifies the primary
133 | group of the user. This attribute will also be used as group id when
134 | searching for the group. Eg, `gidNumber`
135 | + **Members (group)** - The ldap attribute from where to fetch the
136 | group's members. Visible if the group membership is __on the group class__.
137 | Eg, `member`.
138 | + **Memberid (user)** - The ldap attribute from where to fetch the
139 | user's memberid. This attribute must match with the __members attribute__.
140 | Visible if the group membership is __on the group class__. Eg, `dn`.
141 | + **Groups (user)** - The ldap attribute from where to fetch the user's
142 | groups. Visible if the group membership is __on the user class__. Eg,
143 | `memberof`.
144 | + **Groupid (group)** - The ldap attribute from where to fetch the
145 | group's groupid. This attribute must match with the __groups attribute__.
146 | Visible if the group membership is __on the user class__. Eg,
147 | `distinguishedName`.
148 | + **Member groups (group)** - The ldap attribute from where to fetch the
149 | group's member groups. Visible if the nested groups __membership is on the
150 | parent class__. Eg, `member`.
151 | + **Memberid attribute (group)** - The ldap attribute from where to fetch the
152 | member group's memberid. This attribute must match with the __member groups
153 | attribute__. Eg, `distinguishedName`.
154 | + **Parent groups (group)** - The ldap attribute from where to fetch
155 | the group's parent groups. Visible if the nested groups __membership is on
156 | the member class__. Eg, `memberOf`.
157 | + **Parentid attribute (group)** - The ldap attribute from where to fetch the
158 | parent group's id. This attribute must match with the __parent groups
159 | attribute__. Eg, `distinguishedName`.
160 |
161 | **Synchronization actions:**
162 |
163 | + **Users must be members of** - (optional) A group to wich the users must
164 | belong to to have access enabled to redmine.
165 | + **Administrators group** - (optional) All members of this group will become
166 | redmine administrators.
167 | + **Add users to group** - (optional) A group to wich all the users created
168 | from this LDAP authentication will added upon creation. This group should not
169 | exist on LDAP.
170 | + **Create new groups** - If enabled, groups that don't already exist on
171 | redmine will be created.
172 | + **Create new users** - If enabled, users that don't already exist on redmine
173 | will be created when running the rake task.
174 | + **Synchronize on login** - Enables/Disables users synchronization on login.
175 | The possible values are:
176 | - **User fields and groups**: Both the fields and groups will be
177 | synchronized on login. If a user is disabled
178 | on LDAP or removed from the *users must be
179 | member of* group, the user will be locked and
180 | the access denied.
181 | - **User fields**: Only the fields will be synchronized on login. If a user
182 | is disabled on LDAP, the user will be locked and the
183 | access denied. Changes on groups will not lock the user.
184 | - **Disabled**: No synchronization is done on login.
185 | + **Dynamic groups**[¹](#license) - Enables/Disables dynamic groups. The
186 | possible values are:
187 | - **Enabled**: While searching for groups, *Ldap Sync* will also search for
188 | dynamic groups.
189 | - **Enabled with a ttl**: The dynamic groups cache[²](#license) will expire
190 | every **t** minutes.
191 | - **Disabled**: *Ldap Sync* will not search for dynamic groups.
192 | + **User/Group fields:**
193 | - **Synchronize** - If enabled, the selected field will be synchronized
194 | both on the rake tasks and after every login.
195 | - **LDAP attribute** - The ldap attribute to be used as reference on the
196 | synchronization.
197 | - **Default value** - Shows the value that will be used as default.
198 |
199 | ### Rake tasks
200 |
201 | The following tasks are available:
202 |
203 | # rake -T redmine:plugins:ldap_sync
204 | rake redmine:plugins:ldap_sync:sync_all # Synchronize both redmine's users and groups with LDAP
205 | rake redmine:plugins:ldap_sync:sync_groups # Synchronize redmine's groups fields with those on LDAP
206 | rake redmine:plugins:ldap_sync:sync_users # Synchronize redmine's users fields and groups with those on LDAP
207 |
208 | This tasks can be used to do periodic synchronization.
209 | For example:
210 |
211 | # Synchronize users with ldap @ every 60 minutes
212 | 35 * * * * www-data /usr/bin/rake -f /opt/redmine/Rakefile --silent redmine:plugins:ldap_sync:sync_users RAILS_ENV=production 2>&- 1>&-
213 |
214 | The tasks recognize three environment variables:
215 | + **DRY_RUN** - Performs a run without changing the database.
216 | + **ACTIVATE_USERS** - Activates users if they're active on LDAP.
217 | + **LOG_LEVEL** - Controls the rake task verbosity.
218 | The possible values are:
219 | - **silent**: Nothing is written to the output.
220 | - **error**: Only errors are written to the output.
221 | - **change**: Only writes errors and changes made to the user/group's base.
222 | - **debug**: Detailed information about the execution is visible to help
223 | identify errors. This is the default value.
224 |
225 | ### Base settings
226 |
227 | All the base settings are loaded from the plain YAML file
228 | `config/base_settings.yml`.
229 | Please be aware that those settings weren't tested and may not work.
230 | Saying so, I'll need your help to make these settings more accurate.
231 |
232 | License
233 | -------
234 | This plugin is released under the GPL v3 license. See LICENSE for more
235 | information.
236 |
237 | Unmaintained
238 | ------------
239 |
240 | I created this plugin to solve a need we had on my previous job.
241 | Things changed and now I no longer have the time or the need necessary to maintain it.
242 | Sorry for this. Please consider forking or using one of the existing forks.
243 | In a best scenario, an official fork might already exist.
244 |
245 | ---
246 | 1. For details about dynamic groups see
247 | [OpenLDAP Overlays - Dynamic Lists][overlays-dynlist] or
248 | [slapo-dynlist(5) - Linux man page][slapo-dynlist].
249 | 2. Searching for an user's dynamic groups is an costly task. To easy it up, a
250 | cache is used to store the relationship between dynamic groups and users.
251 | When running the rake task this cache will be refreshed.
252 |
253 | [uacf]: http://support.microsoft.com/kb/305144
254 | [overlays-dynlist]: http://www.openldap.org/doc/admin24/overlays.html#Dynamic%20Lists
255 | [slapo-dynlist]: http://www.openldap.org/software/man.cgi?query=slapo-dynlist
256 |
--------------------------------------------------------------------------------
/app/controllers/ldap_settings_controller.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | class LdapSettingsController < ApplicationController
19 | layout 'admin'
20 | menu_item :ldap_sync
21 |
22 | before_action :require_admin
23 | before_action :find_ldap_setting, :only => [:show, :edit, :update, :test, :enable, :disable]
24 | before_action :update_ldap_setting_from_params, :only => [:edit, :update, :test]
25 |
26 | if respond_to? :skip_before_action
27 | skip_before_action :verify_authenticity_token, :if => :js_request?
28 | end
29 |
30 | # GET /ldap_settings
31 | def index
32 | @ldap_settings = LdapSetting.all
33 |
34 | respond_to do |format|
35 | format.html # index.html.erb
36 | end
37 | end
38 |
39 | # GET /ldap_settings/base_settings.js
40 | def base_settings
41 | respond_to do |format|
42 | format.js # base_settings.js.erb
43 | end
44 | end
45 |
46 | # GET /ldap_settings/1
47 | def show
48 | redirect_to edit_ldap_setting_path(@ldap_setting)
49 | end
50 |
51 | # GET /ldap_settings/1/edit
52 | def edit
53 | respond_to do |format|
54 | format.html # edit.html.erb
55 | end
56 | end
57 |
58 | # PUT /ldap_settings/1/disable
59 | def disable
60 | @ldap_setting.disable!
61 |
62 | flash[:notice] = l(:text_ldap_setting_successfully_updated); redirect_to_referer_or ldap_settings_path
63 | end
64 |
65 | # PUT /ldap_settings/1/enable
66 | def enable
67 | @ldap_setting.active = true
68 |
69 | respond_to do |format|
70 | if @ldap_setting.save
71 | format.html { flash[:notice] = l(:text_ldap_setting_successfully_updated); redirect_to_referer_or ldap_settings_path }
72 | else
73 | format.html { flash[:error] = l(:error_cannot_enable_with_invalid_settings); redirect_to_referer_or ldap_settings_path }
74 | end
75 | end
76 | end
77 |
78 | # GET /ldap_settings/1/test
79 | def test
80 | return render 'ldap_setting_invalid' unless @ldap_setting.valid?
81 |
82 | ldap_test = params[:ldap_test]
83 | users = ldap_test.fetch(:test_users, '').split(',')
84 | groups = ldap_test.fetch(:test_groups, '').split(',')
85 | [users, groups].each {|l| l.map(&:strip).reject(&:blank?) }
86 |
87 |
88 | @test = LdapTest.new(@ldap_setting)
89 | @test.bind_user = ldap_test[:bind_user]
90 | @test.bind_password = ldap_test[:bind_password]
91 |
92 | if @test.valid?
93 | @test.run_with_users_and_groups(users, groups)
94 | else
95 | render 'ldap_test_invalid'
96 | end
97 | end
98 |
99 | # PUT /ldap_settings/1
100 | def update
101 | respond_to do |format|
102 | if @ldap_setting.save
103 | format.html { flash[:notice] = l(:text_ldap_setting_successfully_updated); redirect_to_referer_or ldap_settings_path }
104 | else
105 | format.html { render 'edit' }
106 | end
107 | end
108 | end
109 |
110 | private
111 |
112 | def js_request?
113 | request.format.js?
114 | end
115 |
116 | def update_ldap_setting_from_params
117 | %w(user group).each do |e|
118 | params[:ldap_setting]["#{e}_fields_to_sync"] = params["#{e}_fields_to_sync"]
119 | params[:ldap_setting]["#{e}_ldap_attrs"] = params["#{e}_ldap_attrs"]
120 | end if params[:ldap_setting]
121 | @ldap_setting.safe_attributes = params[:ldap_setting] if params[:ldap_setting]
122 | end
123 |
124 | def find_ldap_setting
125 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(params[:id])
126 | render_404 if @ldap_setting.nil?
127 | end
128 | end
129 |
--------------------------------------------------------------------------------
/app/helpers/ldap_settings_helper.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSettingsHelper
19 | def config_css_classes(config)
20 | "ldap_setting #{config.active? ? 'enabled' : 'disabled' }"
21 | end
22 |
23 | def change_status_link(config)
24 | if config.active?
25 | link_to l(:button_disable), disable_ldap_setting_path(config), :method => :put, :class => 'icon icon-disable'
26 | else
27 | link_to l(:button_enable), enable_ldap_setting_path(config), :method => :put, :class => 'icon icon-enable'
28 | end
29 | end
30 |
31 | def ldap_setting_tabs(form)
32 | [
33 | {:name => 'LdapSettings', :partial => 'ldap_settings', :label => :label_ldap_settings, :form => form},
34 | {:name => 'SynchronizationActions', :partial => 'synchronization_actions', :label => :label_synchronization_actions, :form => form},
35 | {:name => 'Test', :partial => 'test', :label => :label_test, :form => form}
36 | ]
37 | end
38 |
39 | def options_for_nested_groups
40 | [
41 | [l(:option_nested_groups_disabled), ''],
42 | [l(:option_nested_groups_on_parents), :on_parents],
43 | [l(:option_nested_groups_on_members), :on_members]
44 | ]
45 | end
46 |
47 | def options_for_group_membeship
48 | [
49 | [l(:option_group_membership_on_groups), :on_groups],
50 | [l(:option_group_membership_on_members), :on_members]
51 | ]
52 | end
53 |
54 | def options_for_dyngroups
55 | [
56 | [l(:option_dyngroups_disabled), ''],
57 | [l(:option_dyngroups_enabled), :enabled],
58 | [l(:option_dyngroups_enabled_with_ttl), :enabled_with_ttl]
59 | ]
60 | end
61 |
62 | def options_for_sync_on_login
63 | [
64 | [l(:option_sync_on_login_user_fields_and_groups), :user_fields_and_groups],
65 | [l(:option_sync_on_login_user_fields), :user_fields],
66 | [l(:option_sync_on_login_disabled), '']
67 | ]
68 | end
69 |
70 | def options_for_users_search_scope
71 | [
72 | [l(:option_users_search_subtree), :subtree],
73 | [l(:option_users_search_onelevel), :onelevel]
74 | ]
75 | end
76 |
77 | def group_fields
78 | has_group_ldap_attrs = @ldap_setting.has_group_ldap_attrs?
79 |
80 | GroupCustomField.all.map do |f|
81 | SyncField.new(
82 | f.id,
83 | f.name,
84 | f.is_required?,
85 | @ldap_setting.sync_group_fields? && @ldap_setting.group_fields_to_sync.include?(f.id.to_s),
86 | has_group_ldap_attrs ? @ldap_setting.group_ldap_attrs[f.id.to_s] : '',
87 | f.default_value
88 | )
89 | end
90 | end
91 |
92 | def user_fields
93 | has_user_ldap_attrs = @ldap_setting.has_user_ldap_attrs?
94 |
95 | (User::STANDARD_FIELDS + UserCustomField.all).map do |f|
96 | if f.is_a?(String)
97 | id = f
98 | name = l("field_#{f}")
99 | required = true
100 | ldap_attr = @ldap_setting.auth_source_ldap.send("attr_#{f}")
101 | default = ''
102 | else
103 | id = f.id
104 | name = f.name
105 | required = f.is_required?
106 | ldap_attr = has_user_ldap_attrs ? @ldap_setting.user_ldap_attrs[id.to_s] : ''
107 | default = f.default_value
108 | end
109 |
110 | sync = @ldap_setting.sync_user_fields? && @ldap_setting.user_fields_to_sync.include?(id.to_s)
111 |
112 | SyncField.new(id, name, required, sync, ldap_attr, default)
113 | end
114 | end
115 |
116 | def options_for_base_settings
117 | options = [[l(:option_custom), '']]
118 | options += base_settings.collect {|k, h| [h['name'], k] }.sort
119 | options_for_select(options, current_base)
120 | end
121 |
122 | def user_fields_list(fields, group_changes)
123 | text = fields.map do |(k, v)|
124 | " #{user_field_name k} = #{v}\n"
125 | end.join
126 | groups = group_changes[:added].to_a.inspect
127 | text << " #{l(:label_group_plural)} = #{groups}\n"
128 | end
129 |
130 | def group_fields_list(fields)
131 | return " #{l(:label_no_fields)}\n" if fields.empty?
132 |
133 | fields.map do |(k, v)|
134 | " #{group_field_name k} = #{v}\n"
135 | end.join
136 | end
137 |
138 | private
139 | def user_field_name(field)
140 | return l("field_#{field}") if field !~ /\A\d+\z/
141 |
142 | UserCustomField.find_by_id(field.to_i).name
143 | end
144 |
145 | def group_field_name(field)
146 | GroupCustomField.find_by_id(field.to_i).name
147 | end
148 |
149 | def baseable_fields
150 | LdapSetting::LDAP_ATTRIBUTES + LdapSetting::CLASS_NAMES + %w( group_membership nested_groups )
151 | end
152 |
153 | def current_base
154 | base_settings.each do |key, hash|
155 | return key if hash.slice(*baseable_fields).all? {|k,v| @ldap_setting.send(k) == (v || '') }
156 | end
157 | ''
158 | end
159 |
160 | def base_settings
161 | @base_settings if defined? @base_settings
162 |
163 | config_dir = File.join(Redmine::Plugin.find(:redmine_ldap_sync).directory, 'config')
164 | default = baseable_fields.inject({}) {|h, k| h[k] = ''; h }
165 | @base_settings = YAML::load_file(File.join(config_dir, 'base_settings.yml'))
166 | @base_settings.each {|k,h| h.reverse_merge!(default) }
167 | end
168 |
169 | class SyncField < Struct.new :id, :name, :required, :synchronize, :ldap_attribute, :default_value
170 | def synchronize?; synchronize; end
171 | def required?; required; end
172 | end
173 | end
174 |
--------------------------------------------------------------------------------
/app/models/ldap_setting.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | class LdapSetting
19 | include Redmine::SafeAttributes
20 | include Redmine::I18n
21 |
22 | include ActiveModel::Validations
23 | include ActiveModel::Validations::Callbacks
24 | include ActiveModel::Conversion
25 | extend ActiveModel::Naming
26 | include ActiveModel::AttributeMethods
27 |
28 | # LDAP_DESCRIPTORS
29 | LDAP_ATTRIBUTES = %w( groupname member user_memberid user_groups groupid parent_group primary_group group_parentid member_group group_memberid account_flags )
30 | CLASS_NAMES = %w( class_user class_group )
31 | FLAGS = %w( create_groups create_users active )
32 | COMBOS = %w( group_membership nested_groups sync_on_login dyngroups users_search_scope )
33 | OTHERS = %w( account_locked_test user_fields_to_sync group_fields_to_sync user_ldap_attrs group_ldap_attrs fixed_group admin_group required_group group_search_filter groupname_pattern groups_base_dn dyngroups_cache_ttl )
34 |
35 | validates_presence_of :auth_source_ldap_id
36 | validates_presence_of :class_user, :class_group, :groupname
37 | validates_presence_of :member, :user_memberid, :if => :membership_on_groups?
38 | validates_presence_of :user_groups, :groupid, :if => :membership_on_members?
39 | validates_presence_of :parent_group, :group_parentid, :if => :nested_on_members?
40 | validates_presence_of :member_group, :group_memberid, :if => :nested_on_parents?
41 | validates_presence_of :dyngroups_cache_ttl, :if => :dyngroups_enabled_with_ttl?
42 |
43 | validates_inclusion_of :nested_groups, :in => ['on_members', 'on_parents', '']
44 | validates_inclusion_of :group_membership, :in => ['on_groups', 'on_members']
45 | validates_inclusion_of :sync_on_login, :in => ['user_fields', 'user_fields_and_groups', '']
46 | validates_inclusion_of :dyngroups, :in => ['enabled', 'enabled_with_ttl', '']
47 | validates_inclusion_of :users_search_scope, :in => ['onelevel', 'subtree']
48 |
49 | validates_format_of *(LDAP_ATTRIBUTES + [{ :with => /\A[a-z][a-z0-9-]*\z/i, :allow_blank => true }])
50 |
51 | validates_numericality_of :dyngroups_cache_ttl, :only_integer => true, :allow_blank => true
52 |
53 | validate :validate_groupname_pattern
54 | validate :validate_account_locked_test
55 | validate :validate_group_filter
56 | validate :validate_user_fields_to_sync, :validate_user_ldap_attrs
57 | validate :validate_group_fields_to_sync, :validate_group_ldap_attrs
58 |
59 | before_validation :strip_names, :set_ldap_attrs, :set_fields_to_sync
60 |
61 | delegate :base_dn, :account, :account_password, :filter, :to => :auth_source_ldap
62 |
63 | attribute_method_affix :prefix => 'has_', :suffix => '?'
64 | attribute_method_suffix '?', '='
65 |
66 | safe_attributes *(LDAP_ATTRIBUTES + CLASS_NAMES + FLAGS + COMBOS + OTHERS)
67 | define_attribute_methods LDAP_ATTRIBUTES + CLASS_NAMES + FLAGS + COMBOS + OTHERS
68 | ::User::STANDARD_FIELDS = %w( firstname lastname mail )
69 |
70 | [:login, *User::STANDARD_FIELDS].each {|f| module_eval("def #{f}; auth_source_ldap.attr_#{f}; end") }
71 |
72 | def id
73 | @auth_source_ldap_id
74 | end
75 |
76 | def to_key
77 | return nil unless persisted?
78 | id ? [id] : nil
79 | end
80 |
81 | def name
82 | auth_source_ldap.name
83 | end
84 |
85 | def active?
86 | return @active if defined? @active
87 |
88 | @active = [true, '1', 'yes'].include? active
89 | end
90 |
91 | def active=(value)
92 | @active = value
93 | @attributes[:active] = value
94 | end
95 |
96 | def nested_groups_enabled?
97 | self.active? && nested_groups.present?
98 | end
99 |
100 | def nested_on_members?
101 | self.active? && nested_groups == 'on_members'
102 | end
103 |
104 | def nested_on_parents?
105 | self.active? && nested_groups == 'on_parents'
106 | end
107 |
108 | def membership_on_groups?
109 | self.active? && group_membership == 'on_groups'
110 | end
111 |
112 | def membership_on_members?
113 | self.active? && group_membership == 'on_members'
114 | end
115 |
116 | def sync_user_fields?
117 | has_user_fields_to_sync?
118 | end
119 |
120 | def sync_group_fields?
121 | has_group_fields_to_sync?
122 | end
123 |
124 | def sync_dyngroups?
125 | has_dyngroups?
126 | end
127 |
128 | def dyngroups_enabled_with_ttl?
129 | dyngroups == 'enabled_with_ttl'
130 | end
131 |
132 | def sync_on_login?
133 | active? && has_sync_on_login?
134 | end
135 |
136 | def sync_groups_on_login?
137 | sync_on_login == 'user_fields_and_groups'
138 | end
139 |
140 | def sync_fields_on_login?
141 | has_sync_on_login?
142 | end
143 |
144 | # Returns the evaluated proc of the account disabled test
145 | def account_locked_proc
146 | @account_locked_proc ||= if has_account_locked_test?
147 | eval("lambda { |flags| #{account_locked_test} }")
148 | end
149 | end
150 |
151 | # Returns the evaluated regular expression of groupname pattern
152 | def groupname_regexp
153 | @groupname_regexp ||= /#{groupname_pattern}/i
154 | end
155 |
156 | # Returns an array of ldap attributes to used when syncing the user fields
157 | def user_ldap_attrs_to_sync(fields = user_fields_to_sync)
158 | (fields||[]).map {|f| user_ldap_attrs[f] || (send(f.to_sym) if respond_to?(f.to_sym)) }
159 | end
160 |
161 | # Returns an array of ldap attributes to used when syncing the group fields
162 | def group_ldap_attrs_to_sync
163 | (group_fields_to_sync||[]).map {|f| group_ldap_attrs[f] }
164 | end
165 |
166 | # Returns the ldap attributes for the given fields
167 | # (not valid for custom fields)
168 | def ldap_attributes(*names)
169 | names.map {|n| send(n) }
170 | end
171 |
172 | # Returns the group field name for the given ldap attribute
173 | def group_field(ldap_attr)
174 | ldap_attr = ldap_attr.to_s
175 | group_ldap_attrs.find {|(k, v)| v.downcase == ldap_attr }.try(:first)
176 | end
177 |
178 | # Returns the user field name for the given ldap attribute
179 | def user_field(ldap_attr)
180 | ldap_attr = ldap_attr.to_s
181 | result = @user_standard_ldap_attrs.find {|(k, v)| v.downcase == ldap_attr }.try(:first)
182 | result ||= user_ldap_attrs.find {|(k, v)| v.downcase == ldap_attr }.try(:first)
183 | end
184 |
185 | def test
186 | @ldap_test ||= LdapTest.new(self)
187 | end
188 |
189 | def ldap_filter
190 | auth_source_ldap.send :ldap_filter
191 | end
192 |
193 | def users_search_onelevel?
194 | users_search_scope == 'onelevel'
195 | end
196 |
197 | # Creates a new ldap setting for the given ldap authentication source
198 | def initialize(source)
199 | @attributes = HashWithIndifferentAccess.new
200 |
201 | self.auth_source_ldap = source
202 | @attributes.merge!(settings)
203 | @user_standard_ldap_attrs = User::STANDARD_FIELDS.each_with_object({}) {|f, h| h[f] = (send(f)||'').downcase }
204 | end
205 |
206 | def auth_source_ldap_id=(id)
207 | @auth_source_ldap_id = id
208 | source = AuthSourceLdap.find_by_id(id)
209 | self.auth_source_ldap = source unless source.nil?
210 | end
211 |
212 | def auth_source_ldap
213 | @auth_source_ldap
214 | end
215 |
216 | def auth_source_ldap=(source)
217 | @auth_source_ldap = source
218 | @auth_source_ldap_id = source.id
219 | @attributes[:auth_source_ldap_id] = source.id
220 | end
221 |
222 | # Sets attributes from attrs that are safe
223 | # attrs is a Hash with string keys
224 | def safe_attributes=(attrs, user = User.current)
225 | if attrs.respond_to?(:to_unsafe_hash)
226 | attrs = attrs.to_unsafe_hash
227 | end
228 | @attributes.merge!(delete_unsafe_attributes(attrs, user))
229 | end
230 |
231 | def save
232 | return false if invalid?
233 |
234 | self.settings = delete_unsafe_attributes(@attributes, User.current)
235 | end
236 |
237 | # Disables this ldap auth source
238 | # A disabled ldap auth source will not be synchronized
239 | def disable!
240 | self.active = false
241 | self.settings = settings.merge(:active => false)
242 | end
243 |
244 | # Overriden to enable validation (see ActiveModel::Validations#read_attribute_for_validation)
245 | def read_attribute_for_validation(key)
246 | @attributes[key]
247 | end
248 |
249 | # LdapSettings are always persisted because its authsource exists
250 | # (see ActiveModel::Lint::Tests::test_persisted?)
251 | def persisted?
252 | true
253 | end
254 |
255 | # Returns the name of an attribute to be displayed on the edit page
256 | def self.human_attribute_name(attr, *args)
257 | attr = attr.to_s.sub(/_id$/, '')
258 |
259 | l("field_#{name.underscore.gsub('/', '_')}_#{attr}", :default => ["field_#{attr}".to_sym, attr])
260 | end
261 |
262 | # Find the ldap setting for a given ldap auth source
263 | def self.find_by_auth_source_ldap_id(id)
264 | return unless source = AuthSourceLdap.find_by_id(id)
265 |
266 | LdapSetting.new(source)
267 | end
268 |
269 | # Find all the available ldap settings
270 | def self.all(options = {})
271 | AuthSourceLdap.where(options).
272 | map {|source| find_by_auth_source_ldap_id(source.id) }.
273 | compact
274 | end
275 |
276 | protected
277 |
278 | def validate_account_locked_test
279 | if account_locked_test.present?
280 | eval "lambda { |flags| #{account_locked_test} }"
281 | end
282 | rescue Exception => e
283 | errors.add :account_locked_test, :invalid_expression, :error_message => e.message.gsub(/^(\(eval\):1: )?(.*?)(lambda.*|$)/m, '\2')
284 | Rails.logger.error "#{e.message}\n #{e.backtrace.join("\n ")}"
285 | end
286 |
287 | def validate_groupname_pattern
288 | /#{groupname_pattern}/ if groupname_pattern.present?
289 | rescue Exception => e
290 | errors.add :groupname_pattern, :invalid_regexp, :error_message => e.message
291 | end
292 |
293 | def validate_group_filter
294 | Net::LDAP::Filter.construct(group_search_filter) if group_search_filter.present?
295 | rescue Net::LDAP::Error
296 | errors.add :group_search_filter, :invalid
297 | end
298 |
299 | def validate_user_ldap_attrs
300 | validate_ldap_attrs user_ldap_attrs, UserCustomField.all
301 | end
302 |
303 | def validate_user_fields_to_sync
304 | validate_fields user_fields_to_sync, (User::STANDARD_FIELDS + UserCustomField.all), user_ldap_attrs
305 | end
306 |
307 | def validate_group_ldap_attrs
308 | validate_ldap_attrs group_ldap_attrs, GroupCustomField.all
309 | end
310 |
311 | def validate_group_fields_to_sync
312 | validate_fields group_fields_to_sync, GroupCustomField.all, group_ldap_attrs
313 | end
314 |
315 | def validate_ldap_attrs(ldap_attrs, fields)
316 | field_ids = fields.map {|f| f.id.to_s }
317 | ldap_attrs.each do |k, v|
318 | if !field_ids.include?(k)
319 | errors.add :user_group_fields, :invalid unless errors.added? :user_group_fields, :invalid
320 |
321 | elsif v.present? && v !~ /\A[a-z][a-z0-9-]*\z/i
322 | field_name = fields.find {|f| f.id == k.to_i }.name
323 | errors.add :base, :invalid_ldap_attribute, :field => field_name
324 | end
325 | end
326 | end
327 |
328 | def validate_fields(fields_to_sync, fields, attrs)
329 | fields_ids = fields.map {|f| f.is_a?(String) ? f : f.id.to_s }
330 | if (fields_to_sync - fields_ids).present?
331 | errors.add :user_group_fields, :invalid unless errors.added? :user_group_fields, :invalid
332 | end
333 | fields_to_sync.each do |f|
334 | if f =~ /\A\d+\z/ && attrs[f].blank?
335 | field_name = fields.find {|c| !c.is_a?(String) && c.id.to_s == f }.name
336 | errors.add :base, :must_have_ldap_attribute, :field => field_name
337 | end
338 | end
339 | end
340 |
341 | private
342 |
343 | def set_fields_to_sync
344 | self.user_fields_to_sync ||= []
345 | self.group_fields_to_sync ||= []
346 | end
347 |
348 | def set_ldap_attrs
349 | self.user_ldap_attrs ||= {}
350 | self.group_ldap_attrs ||= {}
351 | end
352 |
353 | def strip_names
354 | LDAP_ATTRIBUTES.each {|a| @attributes[a].strip! unless @attributes[a].nil? }
355 | CLASS_NAMES.each {|a| @attributes[a].strip! unless @attributes[a].nil? }
356 | end
357 |
358 | def attributes
359 | @attributes
360 | end
361 |
362 | def attribute(attr)
363 | @attributes[attr]
364 | end
365 |
366 | def attribute=(attr, value)
367 | @attributes[attr] = value
368 | end
369 |
370 | def attribute?(attr)
371 | [true, '1', 'yes'].include? @attributes[attr]
372 | end
373 |
374 | def has_attribute?(attr)
375 | self.send("#{attr}").present?
376 | end
377 |
378 | def self.settings(source)
379 | Setting.plugin_redmine_ldap_sync.fetch(source.id, HashWithIndifferentAccess.new)
380 | end
381 |
382 | def settings
383 | LdapSetting.settings(@auth_source_ldap)
384 | end
385 |
386 | def settings=(attrs)
387 | Setting.plugin_redmine_ldap_sync = Setting.plugin_redmine_ldap_sync.merge!(@auth_source_ldap.id => attrs)
388 | end
389 | end
390 |
--------------------------------------------------------------------------------
/app/models/ldap_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | class LdapTest
19 | include Redmine::I18n
20 | include LdapSync::EntityManager
21 | include ActiveModel::Conversion
22 | include ActiveModel::Validations
23 | extend ActiveModel::Naming
24 |
25 | attr_accessor :setting, :bind_user, :bind_password, :test_users, :test_groups, :messages, :user_attrs, :group_attrs, :users_at_ldap, :groups_at_ldap, :non_dynamic_groups, :dynamic_groups, :users_locked_by_group, :admin_users, :user_changes
26 |
27 | delegate :auth_source_ldap, :to => :setting
28 | delegate :users, :to => :auth_source_ldap
29 |
30 | validates_presence_of :bind_user, :bind_password, :if => :connect_as_user?
31 |
32 | def initialize(setting)
33 | setting.active = true
34 |
35 | @setting = setting
36 | @messages = ''
37 | @user_changes = {:enabled => [], :locked => [], :deleted => []}
38 | @users_at_ldap = {}
39 | @groups_at_ldap = {}
40 | @non_dynamic_groups = []
41 | @dynamic_groups = {}
42 | @users_locked_by_group = []
43 | @admin_users = []
44 | end
45 |
46 | def initialize_ldap_con(login, password)
47 | auth_source_ldap.send(:initialize_ldap_con, login, password)
48 | end
49 |
50 | def run_with_users_and_groups(users, groups)
51 | with_ldap_connection(@bind_user, @bind_password) do |ldap|
52 | @user_changes = ldap_users
53 | users.each do |login|
54 | user_data = find_user(ldap, login, nil)
55 | if user_data
56 | @user_attrs ||= user_data
57 | users_at_ldap[login] = {
58 | :fields => get_user_fields(login, user_data, :include_required => true),
59 | :groups => groups_changes(User.new {|u| u.login = login })
60 | }
61 | else
62 | users_at_ldap[login] = :not_found
63 | end
64 | end
65 |
66 | user_changes[:enabled].each do |login|
67 | group_changes = groups_changes(User.new {|u| u.login = login })
68 | enabled_groups = group_changes[:added].map(&:downcase)
69 |
70 | if setting.has_admin_group?
71 | admin_users << login if enabled_groups.include? setting.admin_group.downcase
72 | end
73 |
74 | if setting.has_required_group?
75 | users_locked_by_group << login unless enabled_groups.include? setting.required_group.downcase
76 | end
77 | end if setting.has_admin_group? || setting.has_required_group?
78 |
79 | groups.each do |name|
80 | group_data = find_group(ldap, name, nil)
81 | if group_data
82 | @group_attrs ||= group_data
83 | groups_at_ldap[name] = {
84 | :fields => get_group_fields(name, group_data)
85 | }
86 | else
87 | groups_at_ldap[name] = :not_found
88 | end
89 | end
90 |
91 | find_all_groups(ldap, nil, n(:groupname)) do |entry|
92 | if !setting.has_groupname_pattern? || entry.first =~ /#{setting.groupname_pattern}/
93 | non_dynamic_groups << entry.first
94 | end
95 | end
96 | if setting.sync_dyngroups?
97 | find_all_dyngroups(ldap, :update_cache => true)
98 | dynamic_groups.reject! {|(k, v)| k !~ /#{setting.groupname_pattern}/ } if setting.has_groupname_pattern?
99 | end
100 | end
101 | rescue Exception => e
102 | error(e.message + e.backtrace.join("\n "))
103 | end
104 |
105 | def self.human_attribute_name(attr, *args)
106 | attr = attr.to_s.sub(/_id$/, '')
107 |
108 | l("field_#{name.underscore.gsub('/', '_')}_#{attr}", :default => ["field_#{attr}".to_sym, attr])
109 | end
110 |
111 | def persisted?; true; end
112 |
113 | private
114 | def update_dyngroups_cache!(mem_cache)
115 | @dynamic_groups = Hash.new{|h,k| h[k] = Set.new}
116 | mem_cache.each do |(login, groups)|
117 | dyngroups_cache.write(login, groups)
118 |
119 | groups.each {|group| @dynamic_groups[group] << login }
120 | end
121 | end
122 |
123 | def closure_cache
124 | @closure_cache ||= ActiveSupport::Cache.lookup_store(:memory_store)
125 | end
126 |
127 | def dyngroups_cache
128 | @dyngroups_cache ||= ActiveSupport::Cache.lookup_store(:memory_store)
129 | end
130 |
131 | def parents_cache
132 | @parents_cache ||= ActiveSupport::Cache.lookup_store(:memory_store)
133 | end
134 |
135 | def trace(msg = "", options = {})
136 | @messages += "#{msg}\n" if msg
137 | end
138 |
139 | def running_rake?; true; end
140 | def dyngroups_fresh?; false; end
141 | end
142 |
--------------------------------------------------------------------------------
/app/views/ldap_settings/_ldap_settings.html.erb:
--------------------------------------------------------------------------------
1 | <% f = tab[:form] %>
2 | <%= error_messages_for 'ldap_setting' %>
3 |
4 |
<%= label_tag :base_settings, l(:field_base_settings) %>
5 | <%= select_tag :base_settings, options_for_base_settings %>
6 |
<%= f.text_field :groups_base_dn, :size => 50 %>
7 |
<%= f.text_field :class_user, :required => true, :size => 15 %>
8 |
<%= f.select :users_search_scope, options_for_users_search_scope %>
9 |
<%= f.text_field :class_group, :required => true, :size => 15 %>
10 |
<%= f.text_field :groupname_pattern, :size => 50 %>
11 |
<%= f.text_field :group_search_filter, :size => 50 %>
12 |
13 |
<%= f.text_field :account_locked_test, :size => 50 %>
14 |
<%= f.select :group_membership, options_for_group_membeship %>
15 |
<%= f.select :nested_groups, options_for_nested_groups %>
16 |
17 |
43 |
--------------------------------------------------------------------------------
/app/views/ldap_settings/_synchronization_actions.html.erb:
--------------------------------------------------------------------------------
1 | <% f = tab[:form] %>
2 | <%= error_messages_for 'ldap_setting' %>
3 |
4 |
<%= f.select :sync_on_login, options_for_sync_on_login %>
5 |
<%= f.text_field :required_group %>
6 |
<%= f.text_field :admin_group %>
7 |
<%= f.text_field :fixed_group, :size => 15 %>
8 |
<%= f.check_box :create_users %>
9 |
<%= f.check_box :create_groups %>
10 |
<%= f.select :dyngroups, options_for_dyngroups %>
11 | <%= f.text_field :dyngroups_cache_ttl, :required => true, :size => 5 %> <%= l(:label_minutes) %>
12 |
13 |
14 |
15 |
63 |
64 |
--------------------------------------------------------------------------------
/app/views/ldap_settings/_test.html.erb:
--------------------------------------------------------------------------------
1 | <% f = tab[:form] %>
2 | <%= error_messages_for 'ldap_test' %>
3 |
4 | <%= labelled_fields_for f.object.test do |t| -%>
5 |
<%= t.label :test_users %><%= t.text_field :test_users %>
6 |
<%= t.label :test_groups %><%= t.text_field :test_groups %>
7 |
8 | <% if t.object.connect_as_user? -%>
9 |
<%= t.label :bind_user %><%= t.text_field :bind_user %>
10 |
<%= t.label :bind_password %><%= t.text_field :bind_password %>
11 | <% end -%>
12 |
13 |
<%= link_to l(:button_execute), { :action => 'test', :format => 'text' },
14 | :remote => true, :method => 'put', :id => 'commit-test' %>
15 |
22 | <% end -%>
23 |
--------------------------------------------------------------------------------
/app/views/ldap_settings/base_settings.js.erb:
--------------------------------------------------------------------------------
1 | var base_settings = <%= raw base_settings.to_json %>;
--------------------------------------------------------------------------------
/app/views/ldap_settings/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= change_status_link(@ldap_setting) %>
3 |
4 |
5 | <%= link_to l(:label_ldap_servers), ldap_settings_path %> » <%=h @ldap_setting.name %>
6 |
7 | <%= labelled_form_for @ldap_setting, :html => {:class => 'tabular'} do |f| -%>
8 |
9 | <%= render_tabs ldap_setting_tabs(f) %>
10 |
11 | <%= submit_tag l(:button_save), :id => 'commit-save' %>
12 | <% end -%>
13 |
14 | <% html_title(l(:label_ldap_synchronization)) -%>
15 |
16 | <% content_for :header_tags do %>
17 | <%= javascript_include_tag base_settings_ldap_settings_path(:format => 'js') %>
18 | <%= javascript_include_tag 'ldap_settings.js', :plugin => 'redmine_ldap_sync' %>
19 | <% end %>
--------------------------------------------------------------------------------
/app/views/ldap_settings/index.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:label_ldap_servers) %>
2 |
3 |
--------------------------------------------------------------------------------
/app/views/ldap_settings/ldap_setting_invalid.text.erb:
--------------------------------------------------------------------------------
1 | Validation errors on the ldap settings:
2 | <% @ldap_setting.errors.full_messages.each do |msg| -%>
3 | - <%= msg %>
4 | <% end -%>
--------------------------------------------------------------------------------
/app/views/ldap_settings/ldap_test_invalid.text.erb:
--------------------------------------------------------------------------------
1 | Validation errors on the test:
2 | <% @test.errors.full_messages.each do |msg| -%>
3 | - <%= msg %>
4 | <% end -%>
--------------------------------------------------------------------------------
/app/views/ldap_settings/test.text.erb:
--------------------------------------------------------------------------------
1 | <% @test.users_at_ldap.each do |(login, data)| -%>
2 | <%= "#{l(:label_user)} \"#{login}\"" %>: <%= data == :not_found ?
3 | "#{l(:label_not_found)}\n" :
4 | "\n#{user_fields_list data[:fields], data[:groups]}" %>
5 | <% end -%>
6 | <% @test.groups_at_ldap.each do |(name, data)| -%>
7 | <%= "#{l(:label_group)} \"#{name}\"" %>: <%= data == :not_found ?
8 | "#{l(:label_not_found)}\n" :
9 | "\n#{group_fields_list data[:fields]}" %>
10 | <% end -%>
11 | <%=l :label_users_enabled %>: <%=l :label_a_total_of, @test.user_changes[:enabled].size %>
12 | <%= @test.user_changes[:enabled].to_a.inspect %>
13 | <% if @ldap_setting.has_account_flags? -%>
14 |
15 | <%=l :label_users_locked_by_flag %>: <%=l :label_a_total_of, @test.user_changes[:locked].size %>
16 | <%= @test.user_changes[:locked].to_a.inspect %>
17 | <% end -%>
18 | <% if @ldap_setting.has_required_group? -%>
19 |
20 | <%=l :label_users_locked_by_group %>: <%=l :label_a_total_of, @test.users_locked_by_group.size %>
21 | <%= @test.users_locked_by_group.inspect %>
22 | <% end -%>
23 | <% if @ldap_setting.has_admin_group? -%>
24 |
25 | <%=l :label_admin_users %>: <%=l :label_a_total_of, @test.admin_users.size %>
26 | <%= @test.admin_users.inspect %>
27 | <% end -%>
28 |
29 | <%=l :label_group_plural %>: <%=l :label_a_total_of, @test.non_dynamic_groups.size %>
30 | <%= @test.non_dynamic_groups.inspect %>
31 |
32 | <% if @ldap_setting.sync_dyngroups? -%>
33 | <%=l :label_dynamic_groups %>: <%=l :label_a_total_of, @test.dynamic_groups.size %>
34 | <% @test.dynamic_groups.each do |(k, v)| %>
35 | <%= k %>: <%= v.to_a.inspect %>
36 | <% end -%>
37 |
38 | <% end -%>
39 | <% if @test.user_attrs.present? -%>
40 | <%=l :label_ldap_attributes_on_a_user %>:
41 | <%= @test.user_attrs.map {|(k, v)| k }.inspect %>
42 |
43 | <% end -%>
44 | <% if @test.group_attrs.present? -%>
45 | <%=l :label_ldap_attributes_on_a_group %>:
46 | <%= @test.group_attrs.map {|(k, v)| k }.inspect %>
47 |
48 | <% end -%>
49 | <%=l :label_log_messages %>:
50 | <%= @test.messages %>
--------------------------------------------------------------------------------
/assets/images/disable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tainewoo/redmine_ldap_sync/95219d5f0ab007db9975a6d0f8e32e78c1f36728/assets/images/disable.png
--------------------------------------------------------------------------------
/assets/images/enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tainewoo/redmine_ldap_sync/95219d5f0ab007db9975a6d0f8e32e78c1f36728/assets/images/enable.png
--------------------------------------------------------------------------------
/assets/images/server_key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tainewoo/redmine_ldap_sync/95219d5f0ab007db9975a6d0f8e32e78c1f36728/assets/images/server_key.png
--------------------------------------------------------------------------------
/assets/javascripts/ldap_settings.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | *
4 | * This file is part of Redmine LDAP Sync.
5 | *
6 | * Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Redmine LDAP Sync. If not, see .
18 | */
19 | $(function() {
20 | "use strict";
21 |
22 | function show_options(elem, ambit) {
23 | var selected = $(elem).val();
24 | var prefix = '#ldap_attributes div.' + ambit;
25 |
26 | $(prefix).hide();
27 |
28 | // Remove required for hidden elements
29 | $(prefix + ' input').removeAttr('required');
30 |
31 | if (selected !== '') {
32 | $(prefix + '.' + selected).show();
33 |
34 | // Add required for visible and required inputs
35 | $(prefix + '.' + selected + ' input').each(function(){
36 |
37 | if($('label[for="' + this.id + '"]').hasClass('required'))
38 | $(this).attr('required', 'required');
39 |
40 | });
41 | }
42 | }
43 |
44 | function show_dyngroups_ttl(elem) {
45 | if ($(elem).val() == 'enabled_with_ttl')
46 | $('#dyngroups-cache-ttl').show();
47 | else
48 | $('#dyngroups-cache-ttl').hide();
49 | }
50 |
51 | show_options($('#ldap_setting_group_membership'), 'membership');
52 | $('#ldap_setting_group_membership')
53 | .bind('change keyup', function() { show_options(this, 'membership'); });
54 |
55 | show_options($('#ldap_setting_nested_groups'), 'nested');
56 | $('#ldap_setting_nested_groups')
57 | .bind('change keyup', function() { show_options(this, 'nested'); });
58 |
59 | $('#base_settings').bind('change keyup', function() {
60 | var id = $(this).val();
61 | if (!base_settings[id]) return;
62 |
63 | var hash = base_settings[id];
64 | for (var k in hash) if (hash.hasOwnProperty(k)) {
65 | if (k === 'name' || hash[k] === $('#ldap_setting_' + k).val()) continue;
66 |
67 | $('#ldap_setting_' + k).val(hash[k]).change()
68 | .effect('highlight', {easing: 'easeInExpo'}, 500);
69 | }
70 | });
71 |
72 | show_dyngroups_ttl($('#ldap_setting_dyngroups'));
73 | $('#ldap_setting_dyngroups')
74 | .bind('change keyup', function() { show_dyngroups_ttl(this); });
75 |
76 | $('input[name^="ldap_test"]').keydown(function (e) {
77 | if (e.which == 13) {
78 | $('#commit-test').click();
79 | e.preventDefault();
80 | }
81 | });
82 |
83 | $('form[id^="edit_ldap_setting"]').submit(function() {
84 | var current_tab = $('a[id^="tab-"].selected').attr('id').substring(4);
85 | $('form[id^="edit_ldap_setting"]').append(
86 | ''
87 | );
88 | });
89 |
90 | $('#commit-test')
91 | .bind('ajax:before', function() {
92 | var data = $('form[id^="edit_ldap_setting"]').serialize();
93 | $(this).data('params', data);
94 | })
95 | .bind('ajax:success', function(event, data) {
96 | $('#test-result').text(data);
97 | });
98 | });
--------------------------------------------------------------------------------
/assets/stylesheets/ldap_sync.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | *
4 | * This file is part of Redmine LDAP Sync.
5 | *
6 | * Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Redmine LDAP Sync. If not, see .
18 | */
19 | fieldset.box legend { padding-left: 2px; background-image: none; cursor: default; }
20 |
21 | #admin-menu a.ldap-sync { background-image:url('../images/server_key.png'); }
22 |
23 | tr.ldap_setting.disabled { color: #AAAAAA; }
24 |
25 | tr.ldap_setting.disabled a { color: #AAAAAA; }
26 |
27 | .icon-disable { background-image: url("../images/disable.png"); }
28 |
29 | .icon-enable { background-image: url("../images/enable.png"); }
30 |
31 | .paragraph { padding-left: 300px; }
32 |
33 | #dyngroups-cache-ttl { display: none; }
34 |
35 | #dyngroups-cache-ttl label { float: none; margin-left: 25px; margin-right: 3px; }
36 |
37 | pre#test-result { white-space: pre-wrap; word-wrap: break-word; }
--------------------------------------------------------------------------------
/config/Gemfile.travis:
--------------------------------------------------------------------------------
1 | group :test do
2 | gem 'chromedriver-helper', '~> 1.1'
3 | if RUBY_VERSION >= '2.0'
4 | gem 'coveralls', :require => false
5 | elsif RUBY_VERSION < '1.9'
6 | gem 'i18n', '~> 0.6.11'
7 | gem 'rack-cache', '= 1.2'
8 | gem 'test-unit', '~> 3.0.0'
9 | end
10 | if ENV['REDMINE'] == 'master'
11 | gem 'rails-controller-testing', '~> 1.0.2'
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/config/base_settings.yml:
--------------------------------------------------------------------------------
1 | active_directory:
2 | name: Active Directory
3 | class_user: user
4 | class_group: group
5 | account_locked_test: "flags.to_i & 2 != 0"
6 | group_membership: on_members
7 | nested_groups: ""
8 | groupname: samaccountname
9 | account_flags: useraccountcontrol
10 | user_groups: memberof
11 | groupid: distinguishedname
12 | active_directory_nested:
13 | name: Active Directory (with nested groups)
14 | class_user: user
15 | class_group: group
16 | account_locked_test: "flags.to_i & 2 != 0"
17 | group_membership: on_members
18 | nested_groups: on_parents
19 | groupname: samaccountname
20 | account_flags: useraccountcontrol
21 | user_groups: memberof
22 | groupid: distinguishedname
23 | member_group: member
24 | group_memberid: distinguishedname
25 | open_ds:
26 | name: OpenDS
27 | class_user: person
28 | class_group: groupOfUniqueNames
29 | group_membership: on_members
30 | groupname: cn
31 | user_groups: isMemberOf
32 | groupid: entryDN
33 | lotus_notes_ldap:
34 | name: Lotus Notes LDAP
35 | class_user: dominoPerson
36 | class_group: dominoGroup
37 | group_membership: on_groups
38 | groupname: cn
39 | member: member
40 | user_memberid: dn
41 | open_ldap_posix_groups:
42 | name: Open LDAP (with posixGroups)
43 | class_user: posixAccount
44 | class_group: posixGroup
45 | group_membership: on_groups
46 | groupname: cn
47 | primary_group: gidNumber
48 | member: memberUid
49 | user_memberid: uid
50 | samba_ldap:
51 | name: Samba LDAP
52 | class_user: sambaSamAccount
53 | class_group: sambaGroupMapping
54 | account_locked_test: "flags.include? 'D'"
55 | group_membership: on_groups
56 | groupname: cn
57 | account_flags: sambaAcctFlags
58 | member: member
59 | user_memberid: dn
60 | novell_edirectory_nn:
61 | name: Novell eDirectory (not nested)
62 | class_user: organizationalPerson
63 | class_group: groupOfNames
64 | nested_groups: ""
65 | group_membership: on_groups
66 | groupname: cn
67 | member: member
68 | groupid: entryDN
69 | user_memberid: entryDN
70 | user_groups: groupMembership
71 |
--------------------------------------------------------------------------------
/config/database.yml.travis:
--------------------------------------------------------------------------------
1 | test:
2 | adapter: <%= RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql' %>
3 | database: redmine
4 | username: travis
5 | encoding: utf8
--------------------------------------------------------------------------------
/config/locales/de.yml:
--------------------------------------------------------------------------------
1 | de:
2 | label_ldap_synchronization: "LDAP synchronization"
3 | label_ldap_settings: "LDAP Einstellungen"
4 | label_ldap_servers: "LDAP servers"
5 | label_synchronization_actions: "Syncronizationsaktionen"
6 | label_synchronize: "Synchronize"
7 | label_ldap_attribute: "LDAP Attribut"
8 | label_default_value: "Standardeinstellung"
9 | label_test: "Testen"
10 | label_result: "Resultate"
11 | label_minutes: "minutes"
12 |
13 | label_not_executed: "Not executed"
14 | label_no_fields: "No fields"
15 | label_not_found: "Not found"
16 | label_users_enabled: "Users enabled"
17 | label_a_total_of: "a total of %{count}"
18 | label_users_locked_by_flag: "Users locked by flag"
19 | label_users_locked_by_group: "Users locked by group"
20 | label_admin_users: "Admin users"
21 | label_dynamic_grous: "Dynamic groups"
22 | label_ldap_attributes_on_a_user: "LDAP attributes on a user"
23 | label_ldap_attributes_on_a_group: "LDAP attributes on a group"
24 | label_log_messages: "Log messages"
25 |
26 | button_test: "Testen"
27 | button_execute: "Execute"
28 | button_enable: "Enable"
29 | button_disable: "Disable"
30 |
31 | header_create_groups: "Create groups"
32 | header_create_users: "Create users"
33 | header_sync_user_fields: "Benutzerattribute sync"
34 | header_sync_group_fields: "Sync group fields"
35 |
36 | field_nested_groups: "Nested groups"
37 | field_create_groups: "Neue Gruppe erstellen"
38 | field_create_users: "Create users"
39 | field_sync_on_login: "Synchronize on login"
40 | field_dyngroups: "Dynamic groups"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Gruppen DN"
44 | field_group_membership: "Group membership"
45 | field_class_user: "Benutzerobjektklasse"
46 | field_users_search_scope: "Users search scope"
47 | field_class_group: "Gruppenobjektklasse"
48 | field_account_locked_test: "Account Deaktivierungsbedingung"
49 |
50 | field_groupname_pattern: "Regular Expression für den Gruppenfilter"
51 | field_group_search_filter: "Gruppensuchfilfer"
52 |
53 | field_groupname: "Gruppenname (group)"
54 | field_member: "Gruppenteilnehmer (group)"
55 | field_member_group: "Member groups (group)"
56 | field_parent_group: "Parent groups (group)"
57 | field_user_memberid: "Memberid (user)"
58 | field_group_memberid: "Memberid (group)"
59 | field_group_parentid: "Parentid (group)"
60 | field_user_groups: "Groups (user)"
61 | field_groupid: "Groupid (group)"
62 | field_account_flags: "Account flags (user)"
63 | field_primary_group: "Primary group (user)"
64 |
65 | field_required_group: "Benutzer müssen Gruppenteilnehmer sein"
66 | field_admin_group: "Administrators group"
67 | field_fixed_group: "Benutzer zur Gruppe hinzufügen"
68 |
69 | field_user_group_fields: "User/Group fields"
70 | field_firstname: "Vorname"
71 | field_lastname: "Nachname"
72 | field_mail: "Email Adresse"
73 |
74 | field_test_users: "Benutzer"
75 | field_test_groups: "Gruppen"
76 |
77 | option_users_search_subtree: "Whole subtree"
78 | option_users_search_onelevel: "One level"
79 |
80 | option_group_membership_on_groups: "On the group class"
81 | option_group_membership_on_members: "On the user class"
82 |
83 | option_nested_groups_disabled: "Disabled"
84 | option_nested_groups_on_parents: "Membership on the parent class"
85 | option_nested_groups_on_members: "Membership on the member class"
86 |
87 | option_dyngroups_disabled: "Disabled"
88 | option_dyngroups_enabled: "Enabled"
89 | option_dyngroups_enabled_with_ttl: "Enabled with a TTL"
90 |
91 | option_sync_on_login_disabled: "Disabled"
92 | option_sync_on_login_user_fields: "User fields"
93 | option_sync_on_login_user_fields_and_groups: "User fields and groups"
94 |
95 | text_ldap_setting_successfully_updated: "Ldap configuration successfully updated."
96 |
97 | field_base_settings: "Base settings"
98 | option_custom: "Customized"
99 |
100 | error_cannot_enable_with_invalid_settings: "Cannot enable synchronization with invalid settings. Please revise the configuration."
101 |
102 | errors:
103 | messages:
104 | invalid_ldap_attribute: "%{value} has an invalid LDAP attribute"
105 | must_have_ldap_attribute: "%{value} must have an LDAP attribute for it to be synchronized"
106 | invalid_expression: "contains an invalid expression: %{error_message}"
107 | invalid_regexp: "contains an invalid regular expression: %{error_message}"
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | label_ldap_synchronization: "LDAP synchronization"
3 | label_ldap_settings: "LDAP settings"
4 | label_ldap_servers: "LDAP servers"
5 | label_synchronization_actions: "Synchronization actions"
6 | label_synchronize: "Synchronize"
7 | label_ldap_attribute: "LDAP attribute"
8 | label_default_value: "Default value"
9 | label_test: "Test"
10 | label_result: "Result"
11 | label_minutes: "minutes"
12 |
13 | label_not_executed: "Not executed"
14 | label_no_fields: "No fields"
15 | label_not_found: "Not found"
16 | label_users_enabled: "Users enabled"
17 | label_a_total_of: "a total of %{count}"
18 | label_users_locked_by_flag: "Users locked by flag"
19 | label_users_locked_by_group: "Users locked by group"
20 | label_admin_users: "Admin users"
21 | label_dynamic_groups: "Dynamic groups"
22 | label_ldap_attributes_on_a_user: "LDAP attributes on a user"
23 | label_ldap_attributes_on_a_group: "LDAP attributes on a group"
24 | label_log_messages: "Log messages"
25 |
26 | button_test: "Test"
27 | button_execute: "Execute"
28 | button_enable: "Enable"
29 | button_disable: "Disable"
30 |
31 | header_create_groups: "Create groups"
32 | header_create_users: "Create users"
33 | header_sync_user_fields: "Sync user fields"
34 | header_sync_group_fields: "Sync groups fields"
35 |
36 | field_nested_groups: "Nested groups"
37 | field_create_groups: "Create groups"
38 | field_create_users: "Create users"
39 | field_sync_on_login: "Synchronize on login"
40 | field_dyngroups: "Dynamic groups"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Groups base DN"
44 | field_group_membership: "Group membership"
45 | field_class_user: "Users objectclass"
46 | field_users_search_scope: "Users search scope"
47 | field_class_group: "Groups objectclass"
48 | field_account_locked_test: "Account disabled test"
49 |
50 | field_groupname_pattern: "Group name pattern"
51 | field_group_search_filter: "Group search filter"
52 |
53 | field_groupname: "Group name (group)"
54 | field_member: "Member users (group)"
55 | field_member_group: "Member groups (group)"
56 | field_parent_group: "Parent groups (group)"
57 | field_user_memberid: "Memberid (user)"
58 | field_group_memberid: "Memberid (group)"
59 | field_group_parentid: "Parentid (group)"
60 | field_user_groups: "Groups (user)"
61 | field_groupid: "Groupid (group)"
62 | field_account_flags: "Account flags (user)"
63 | field_primary_group: "Primary group (user)"
64 |
65 | field_required_group: "Users must be members of"
66 | field_admin_group: "Administrators group"
67 | field_fixed_group: "Add users to group"
68 |
69 | field_user_group_fields: "User/Group fields"
70 | field_firstname: "First name"
71 | field_lastname: "Last name"
72 | field_mail: "Email"
73 |
74 | field_test_users: "Users"
75 | field_test_groups: "Groups"
76 | field_bind_user: "Bind user"
77 | field_bind_password: "Bind password"
78 |
79 | option_users_search_subtree: "Whole subtree"
80 | option_users_search_onelevel: "One level"
81 |
82 | option_group_membership_on_groups: "On the group class"
83 | option_group_membership_on_members: "On the user class"
84 |
85 | option_nested_groups_disabled: "Disabled"
86 | option_nested_groups_on_parents: "Membership on the parent class"
87 | option_nested_groups_on_members: "Membership on the member class"
88 |
89 | option_dyngroups_disabled: "Disabled"
90 | option_dyngroups_enabled: "Enabled"
91 | option_dyngroups_enabled_with_ttl: "Enabled with a TTL"
92 |
93 | option_sync_on_login_disabled: "Disabled"
94 | option_sync_on_login_user_fields: "User fields"
95 | option_sync_on_login_user_fields_and_groups: "User fields and groups"
96 |
97 | text_ldap_setting_successfully_updated: "Ldap configuration successfully updated."
98 |
99 | field_base_settings: "Base settings"
100 | option_custom: "Customized"
101 |
102 | error_cannot_enable_with_invalid_settings: "Cannot enable synchronization with invalid settings. Please revise the configuration."
103 |
104 | errors:
105 | messages:
106 | invalid_ldap_attribute: "%{field} has an invalid LDAP attribute"
107 | must_have_ldap_attribute: "%{field} must have an LDAP attribute for it to be synchronized"
108 | invalid_expression: "contains an invalid expression: %{error_message}"
109 | invalid_regexp: "contains an invalid regular expression: %{error_message}"
--------------------------------------------------------------------------------
/config/locales/es.yml:
--------------------------------------------------------------------------------
1 | es:
2 | label_ldap_synchronization: "Sincronización LDAP"
3 | label_ldap_settings: "Configuración LDAP"
4 | label_ldap_servers: "Servidores LDAP"
5 | label_synchronization_actions: "Acciones de sincronización"
6 | label_synchronize: "Sincronizar"
7 | label_ldap_attribute: "Atributo LDAP"
8 | label_default_value: "Valor por defecto"
9 | label_test: "Probar"
10 | label_result: "Resultado"
11 | label_minutes: "minutos"
12 |
13 | label_not_executed: "No ejecutado"
14 | label_no_fields: "Sin campos"
15 | label_not_found: "No encontrado"
16 | label_users_enabled: "Usuarios activos"
17 | label_a_total_of: "un total de %{count}"
18 | label_users_locked_by_flag: "Usuarios inhabilitados por indicadores"
19 | label_users_locked_by_group: "Usuarios inhabilitados por grupo"
20 | label_admin_users: "Administradores redmine"
21 | label_dynamic_grous: "Grupos dinámicos"
22 | label_ldap_attributes_on_a_user: "Atributos LDAP en un usuario"
23 | label_ldap_attributes_on_a_group: "Atributos LDAP en un grupo"
24 | label_log_messages: "Mensajes de log"
25 |
26 | button_test: "Probar"
27 | button_execute: "Ejecutar"
28 | button_enable: "Activar"
29 | button_disable: "Inhabilitar"
30 |
31 | header_create_groups: "Crear grupos"
32 | header_create_users: "Crear usuarios"
33 | header_sync_user_fields: "Sinc atrib usuarios"
34 | header_sync_group_fields: "Sinc atrib grupos"
35 |
36 | field_nested_groups: "Grupos anidados"
37 | field_create_groups: "Crear grupos"
38 | field_create_users: "Crear usuarios"
39 | field_sync_on_login: "Sincronizar en el inicio de sesión"
40 | field_dyngroups: "Grupos dinámicos"
41 | field_dyngroups_cache_ttl: "Caché TTL"
42 |
43 | field_groups_base_dn: "Base DN de grupos"
44 | field_group_membership: "Pertenencia al grupo"
45 | field_class_user: "Objectclass de usuarios"
46 | field_users_search_scope: "Ámbito de búsqueda de usuarios"
47 | field_class_group: "Objectclass de grupos"
48 | field_account_locked_test: "Prueba de cuenta inhabilitada"
49 |
50 | field_groupname_pattern: "Filtro regex de grupos"
51 | field_group_search_filter: "Filtro de búsqueda de grupos"
52 |
53 | field_groupname: "Nombre del grupo (grupo)"
54 | field_member: "Miembros (grupo)"
55 | field_member_group: "Grupos miembros (grupo)"
56 | field_parent_group: "Grupos padres (grupo)"
57 | field_user_memberid: "Memberid (usuario)"
58 | field_group_memberid: "Memberid (grupo)"
59 | field_group_parentid: "Parentid (grupo)"
60 | field_user_groups: "Grupos (usuario)"
61 | field_groupid: "Groupid (grupo)"
62 | field_account_flags: "Indicadores de cuenta (usuario)"
63 | field_primary_group: "Grupo primario (usuario)"
64 |
65 | field_required_group: "Bloquear si no pertenece al grupo"
66 | field_admin_group: "Administradores son miembros del grupo"
67 | field_fixed_group: "Añadir nuevos usuarios al grupo"
68 |
69 | field_user_group_fields: "Campos usuario/grupo"
70 | field_firstname: "Nombre"
71 | field_lastname: "Apellido"
72 | field_mail: "Correo electrónico"
73 |
74 | field_test_users: "Usuarios"
75 | field_test_groups: "Grupos"
76 |
77 | option_users_search_subtree: "Toda subárbol"
78 | option_users_search_onelevel: "Un nivel"
79 |
80 | option_group_membership_on_groups: "En la clase grupo"
81 | option_group_membership_on_members: "En la clase usuario"
82 |
83 | option_nested_groups_disabled: "Inhabilitado"
84 | option_nested_groups_on_parents: "Pertenencia en el padre"
85 | option_nested_groups_on_members: "Pertenencia en el miembro"
86 |
87 | option_dyngroups_disabled: "Inhabilitado"
88 | option_dyngroups_enabled: "Habilitado"
89 | option_dyngroups_enabled_with_ttl: "Habilitado con un TTL"
90 |
91 | option_sync_on_login_disabled: "Inhabilitado"
92 | option_sync_on_login_user_fields: "Campos de los usuarios"
93 | option_sync_on_login_user_fields_and_groups: "Campos y grupos de los usuarios"
94 |
95 | text_ldap_setting_successfully_updated: "Configuración LDAP actualizada con éxito."
96 |
97 | field_base_settings: "Configuración base"
98 | option_custom: "Personalizado"
99 |
100 | error_cannot_enable_with_invalid_settings: "No es posible activar la sincronización mientras haga errores en la configuración"
101 |
102 | errors:
103 | messages:
104 | invalid_ldap_attribute: "%{value} tiene un atributo LDAP no válido"
105 | must_have_ldap_attribute: "%{value} debe tener un atributo LDAP para que se pueda sincronizar"
106 | invalid_expression: "contiene una expresión no válida: %{error_message}"
107 | invalid_regexp: "contiene una expresión regular no válida: %{error_message}"
108 |
--------------------------------------------------------------------------------
/config/locales/fr.yml:
--------------------------------------------------------------------------------
1 | fr:
2 | label_ldap_synchronization: "Synchronisation LDAP"
3 | label_ldap_settings: "Paramètres LDAP"
4 | label_ldap_servers: "Serveurs LDAP"
5 | label_synchronization_actions: "Actions de synchro."
6 | label_synchronize: "Synchroniser"
7 | label_ldap_attribute: "Attribut LDAP"
8 | label_default_value: "Valeur par défaut"
9 | label_test: "Test"
10 | label_result: "Résultat"
11 | label_minutes: "minutes"
12 |
13 | label_not_executed: "Non executé"
14 | label_no_fields: "Pas de champ"
15 | label_not_found: "Pas trouvé"
16 | label_users_enabled: "Utilisateurs activés"
17 | label_a_total_of: "un total de %{count}"
18 | label_users_locked_by_flag: "Utilisateurs désactivés par statut"
19 | label_users_locked_by_group: "Utilisateurs désactivés par groupes"
20 | label_admin_users: "Administrateurs"
21 | label_dynamic_groups: "Groupes Dynamiques"
22 | label_ldap_attributes_on_a_user: "Attributs LDAP sur un utilisateur"
23 | label_ldap_attributes_on_a_group: "Attributs LDAP sur un groupe"
24 | label_log_messages: "Messages de log"
25 |
26 | button_test: "Test"
27 | button_execute: "Executer"
28 | button_enable: "Activer"
29 | button_disable: "Désactiver"
30 |
31 | header_create_groups: "Créer groupes"
32 | header_create_users: "Créer utilisateurs"
33 | header_sync_user_fields: "Sync. champs utilisateurs"
34 | header_sync_group_fields: "Sync. champs groupes"
35 |
36 | field_nested_groups: "Groupes imbriqués"
37 | field_create_groups: "Créer des groupes"
38 | field_create_users: "Créer des utilisateurs"
39 | field_sync_on_login: "Synchroniser à la connexion"
40 | field_dyngroups: "Groupes dynamiques"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Groupes base DN"
44 | field_group_membership: "Adhésion au groupe"
45 | field_class_user: "Utilisateurs objectclass"
46 | field_users_search_scope: "Profondeur de la recherche des utilisateurs"
47 | field_class_group: "Groupes objectclass"
48 | field_account_locked_test: "Compte désactivé test"
49 |
50 | field_groupname_pattern: "Modèle de nom de groupe"
51 | field_group_search_filter: "Filtre de recherche de groupes"
52 |
53 | field_groupname: "Nom du groupe (groupe)"
54 | field_member: "Utilisateurs membres (groupe)"
55 | field_member_group: "Groupes membres (groupe)"
56 | field_parent_group: "Groupes parents (groupe)"
57 | field_user_memberid: "Memberid (utilisateur)"
58 | field_group_memberid: "Memberid (groupe)"
59 | field_group_parentid: "Parentid (groupe)"
60 | field_user_groups: "Groupes (utilisateur)"
61 | field_groupid: "Groupid (groupe)"
62 | field_account_flags: "Account flags (utilisateur)"
63 | field_primary_group: "Groupe principal (utilisateur)"
64 |
65 | field_required_group: "L'utilisateur doit être membre de"
66 | field_admin_group: "Groupe des administrateurs"
67 | field_fixed_group: "Ajouter des utilisateurs aux groupes"
68 |
69 | field_user_group_fields: "Champs utilisateur/groupe"
70 | field_firstname: "Prénom"
71 | field_lastname: "Nom"
72 | field_mail: "Email"
73 |
74 | field_test_users: "Utilisateurs"
75 | field_test_groups: "Groupes"
76 |
77 | option_users_search_subtree: "Tout le sous-arbre"
78 | option_users_search_onelevel: "Un niveau en dessous"
79 |
80 | option_group_membership_on_groups: "Sur la classe Groupe"
81 | option_group_membership_on_members: "Sur la classe Utilisateur"
82 |
83 | option_nested_groups_disabled: "Désactivé"
84 | option_nested_groups_on_parents: "Adhésion à la classe parent"
85 | option_nested_groups_on_members: "Adhésion à la classe membre"
86 |
87 | option_dyngroups_disabled: "Désactivé"
88 | option_dyngroups_enabled: "Activé"
89 | option_dyngroups_enabled_with_ttl: "Activé avec un TTL"
90 |
91 | option_sync_on_login_disabled: "Désactivé"
92 | option_sync_on_login_user_fields: "Champs utilisateurs"
93 | option_sync_on_login_user_fields_and_groups: "Champs utilisateurs et groupes"
94 |
95 | text_ldap_setting_successfully_updated: "Configuration LDAP mise à jour avec succés"
96 |
97 | field_base_settings: "Paramètres de base"
98 | option_custom: "Personnalisée"
99 |
100 | error_cannot_enable_with_invalid_settings: "Impossible d'activer la synchronisation avec des paramètres invalides. Veuillez revoir la configuration."
101 |
102 | errors:
103 | messages:
104 | invalid_ldap_attribute: "%{field} a un attribut LDAP non valide"
105 | must_have_ldap_attribute: "%{field} doit avoir un attribut LDAP pour être synchronisé"
106 | invalid_expression: "contient une expression non valide: %{error_message}"
107 | invalid_regexp: "contient une expression régulière non valide: %{error_message}"
108 |
--------------------------------------------------------------------------------
/config/locales/ja.yml:
--------------------------------------------------------------------------------
1 | ja:
2 | label_ldap_synchronization: "LDAP同期" # "LDAP synchronization"
3 | label_ldap_settings: "LDAP設定" # "LDAP settings"
4 | label_ldap_servers: "LDAPサーバー" # "LDAP servers"
5 | label_synchronization_actions: "同期動作" # "Synchronization actions"
6 | label_synchronize: "同期" # "Synchronize"
7 | label_ldap_attribute: "LDAP属性" # "LDAP attribute"
8 | label_default_value: "デフォルト値" # "Default value"
9 | label_test: "テスト" # "Test"
10 | label_result: "リザルト" # "Result"
11 | label_minutes: "分" # "minutes"
12 |
13 | label_not_executed: "未実行" # "Not executed"
14 | label_no_fields: "フィールド無し" # "No fields"
15 | label_not_found: "見つかりません" # "Not found"
16 | label_users_enabled: "有効ユーザー" # "Users enabled"
17 | label_a_total_of: "%{count} 個" # "a total of %{count}"
18 | label_users_locked_by_flag: "フラグによって無効化されたユーザー" # "Users disabled by flag"
19 | label_users_locked_by_group: "グループによって無効化されたユーザー"
20 | label_admin_users: "管理者" # "Admin users"
21 | label_dynamic_groups: "ダイナミックグループ" # "Dynamic groups"
22 | label_ldap_attributes_on_a_user: "ユーザー中に在るLDAP属性" # "LDAP attributes on a user"
23 | label_ldap_attributes_on_a_group: "グループ中に在るLDAP属性" # "LDAP attributes on a group"
24 | label_log_messages: "ログメッセージ" # "Log messages"
25 |
26 | button_test: "テスト" # "Test"
27 | button_execute: "実行" # "Execute"
28 | button_enable: "有効" # "Enable"
29 | button_disable: "無効" # "Disable"
30 |
31 | header_create_groups: "グループを作成する" # "Create groups"
32 | header_create_users: "ユーザーを作成する" # "Create users"
33 | header_sync_user_fields: "ユーザーフィールドを同期する" # "Sync user fields"
34 | header_sync_group_fields: "グループフィールドを同期する" # "Sync groups fields"
35 |
36 | field_nested_groups: "ネストされたグループ" # "Nested groups"
37 | field_create_groups: "グループを作成する" # "Create groups"
38 | field_create_users: "ユーザーを作成する" # "Create users"
39 | field_sync_on_login: "ログイン時に同期" # "Synchronize on login"
40 | field_dyngroups: "ダイナミックグループ" # "Dynamic groups"
41 | field_dyngroups_cache_ttl: "キャッシュTTL" # "Cache TTL"
42 |
43 | field_groups_base_dn: "グループベースDN" # "Groups base DN"
44 | field_group_membership: "グループ メンバーシップ" # "Group membership"
45 | field_class_user: "ユーザー オブジェクトクラス" # "Users objectclass"
46 | field_users_search_scope: "Users search scope"
47 | field_class_group: "グループ オブジェクトクラス" # "Groups objectclass"
48 | field_account_locked_test: "無効アカウントの判別方法" # "Account disabled test"
49 |
50 | field_groupname_pattern: "グループネームパターン" # "Group name pattern"
51 | field_group_search_filter: "グループフィルター" # "Group search filter"
52 |
53 | field_groupname: "グループ名(group)" # "Group name (group)"
54 | field_member: "メンバーユーザー(group)" # "Member users (group)"
55 | field_member_group: "メンバーグループ(group)" # "Member groups (group)"
56 | field_parent_group: "親グループ(group)" # "Parent groups (group)"
57 | field_user_memberid: "メンバーID(user)" # "Memberid (user)"
58 | field_group_memberid: "メンバーID(group)" # "Memberid (group)"
59 | field_group_parentid: "親ID(group)" # "Parentid (group)"
60 | field_user_groups: "グループ(user)" # "Groups (user)"
61 | field_groupid: "グループID(group)" # "Groupid (group)"
62 | field_account_flags: "アカウントフラグ(user)" # "Account flags (user)"
63 | field_primary_group: "プライマリーグループ(user)" # "Primary group (user)"
64 |
65 | field_required_group: "登録必須グループ" # "Users must be members of"
66 | field_admin_group: "管理者グループ" # "Administrators group"
67 | field_fixed_group: "ユーザ追加先グループ" # "Add users to group"
68 |
69 | field_user_group_fields: "ユーザー/グループ フィールド" # "User/Group fields"
70 | field_firstname: "名前" # "First name"
71 | field_lastname: "名字" # "Last name"
72 | field_mail: "メールアドレス" # "Email"
73 |
74 | field_test_users: "ユーザー" # "Users"
75 | field_test_groups: "グループ" # "Groups"
76 |
77 | option_users_search_subtree: "Whole subtree"
78 | option_users_search_onelevel: "One level"
79 |
80 | option_group_membership_on_groups: "グループ情報中" # "On the group class"
81 | option_group_membership_on_members: "ユーザー情報中" # "On the user class"
82 |
83 | option_nested_groups_disabled: "無効" # "Disabled"
84 | option_nested_groups_on_parents: "メンバーシップは親情報中" # "Membership on the parent class"
85 | option_nested_groups_on_members: "メンバーシップは子情報中" # "Membership on the member class"
86 |
87 | option_dyngroups_disabled: "無効" # "Disabled"
88 | option_dyngroups_enabled: "有効" # "Enabled"
89 | option_dyngroups_enabled_with_ttl: "有効+持続時間指定" # "Enabled with a TTL"
90 |
91 | option_sync_on_login_disabled: "無効" # "Disabled"
92 | option_sync_on_login_user_fields: "ユーザーフィールド" # "User fields"
93 | option_sync_on_login_user_fields_and_groups: "ユーザーフィールドとグループ" # "User fields and groups"
94 |
95 | text_ldap_setting_successfully_updated: "LDAP同期設定の更新に成功しました" # "Ldap configuration successfully updated."
96 |
97 | field_base_settings: "ベースセッティング" # "Base settings"
98 | option_custom: "カスタマイズ" # "Customized"
99 |
100 | error_cannot_enable_with_invalid_settings: "設定に誤りがあり同期を有効化できませんでした、設定を修正してください。" # "Cannot enable synchronization with invalid settings. Please revise the configuration."
101 |
102 | errors:
103 | messages:
104 | invalid_ldap_attribute: "%{field} に不正なLDAP属性が在ります" # "%{field} has an invalid LDAP attribute"
105 | must_have_ldap_attribute: "同期するにはLDAP属性に %{field} が必須です" # "%{field} must have an LDAP attribute for it to be synchronized"
106 | invalid_expression: "不正な式が含まれてます: %{error_message}" # "contains an invalid expression: %{error_message}"
107 | invalid_regexp: "不正な正規表現が含まれてます: %{error_message}" # "contains an invalid regular expression: %{error_message}"
108 |
--------------------------------------------------------------------------------
/config/locales/nl.yml:
--------------------------------------------------------------------------------
1 | nl:
2 | label_ldap_synchronization: "LDAP synchronisatie"
3 | label_ldap_settings: "LDAP instellingen"
4 | label_ldap_servers: "LDAP servers"
5 | label_synchronization_actions: "Synchronisatie-acties"
6 | label_synchronize: "Synchroniseren"
7 | label_ldap_attribute: "LDAP-attribuut"
8 | label_default_value: "Standaardwaarde"
9 | label_test: "Test"
10 | label_result: "Resultaat"
11 | label_minutes: "minuten"
12 |
13 | label_not_executed: "Niet uitgevoerd"
14 | label_no_fields: "Geen velden"
15 | label_not_found: "Niet gevonden"
16 | label_users_enabled: "Ingeschakelde gebruikers"
17 | label_a_total_of: "een totaal van %{count}"
18 | label_users_locked_by_flag: "Gebruikers uitgeschakeld door vlag"
19 | label_users_locked_by_group: "Gebruikers uitgeschakeld door groep"
20 | label_admin_users: "Beheerders"
21 | label_dynamic_groups: "Dynamische groepen"
22 | label_ldap_attributes_on_a_user: "LDAP-attributen voor een gebruiker"
23 | label_ldap_attributes_on_a_group: "LDAP-attributen voor een groep"
24 | label_log_messages: "Logberichten"
25 |
26 | button_test: "Test"
27 | button_execute: "Uitvoeren"
28 | button_enable: "Inschakelen"
29 | button_disable: "Uitschakelen"
30 |
31 | header_create_groups: "Groepen aanmaken"
32 | header_create_users: "Gebruikers aanmaken"
33 | header_sync_user_fields: "Sync gebruikersvelden"
34 | header_sync_group_fields: "Sync groepsvelden"
35 |
36 | field_nested_groups: "Geneste groepen"
37 | field_create_groups: "Groepen aanmaken"
38 | field_create_users: "Gebruikers aanmaken"
39 | field_sync_on_login: "Synchroniseren bij aanmelden"
40 | field_dyngroups: "Dynamische groepen"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Base-DN voor groepen"
44 | field_group_membership: "Groep-lidmaatschap"
45 | field_class_user: "ObjectClass gebruikers"
46 | field_users_search_scope: "Zoekbereik gebruikers"
47 | field_class_group: "ObjectClass groepen"
48 | field_account_locked_test: "Gebruikersaccount uitgeschakeld test"
49 |
50 | field_groupname_pattern: "Groepsnaam-patroon"
51 | field_group_search_filter: "Zoekfilter groepen"
52 |
53 | field_groupname: "Groepsnaam (groep)"
54 | field_member: "Groepslid (groep)"
55 | field_member_group: "Ledengroepen (groep)"
56 | field_parent_group: "Oudergroepen (groep)"
57 | field_user_memberid: "Groepslid-ID (gebruiker)"
58 | field_group_memberid: "Groepslid-ID (groep)"
59 | field_group_parentid: "Ouder-id (groep)"
60 | field_user_groups: "Groepen (gebruiker)"
61 | field_groupid: "Groeps-id (groep)"
62 | field_account_flags: "Gebruikersaccount vlag (gebruiker)"
63 | field_primary_group: "Hoofdgroep (gebruiker)"
64 |
65 | field_required_group: "Gebruikers moeten lid zijn van"
66 | field_admin_group: "Beheerders-groep"
67 | field_fixed_group: "Gebruikers toevoegen aan groep"
68 |
69 | field_user_group_fields: "Gebruiker/Groepsvelden"
70 | field_firstname: "Voornaam"
71 | field_lastname: "Achternaam"
72 | field_mail: "E-mailadres"
73 |
74 | field_test_users: "Gebruikers"
75 | field_test_groups: "Groepen"
76 |
77 | field_bind_user: "Bind gebruiker"
78 | field_bind_password: "Bind wachtwoord"
79 |
80 | option_users_search_subtree: "Volledige vertakking (subtree)"
81 | option_users_search_onelevel: "Enkel niveau"
82 |
83 | option_group_membership_on_groups: "Van de groepsklasse"
84 | option_group_membership_on_members: "Van de gebruikersklasse"
85 |
86 | option_nested_groups_disabled: "Uitgeschakeld"
87 | option_nested_groups_on_parents: "Lidmaatschap van de ouderklasse"
88 | option_nested_groups_on_members: "Lidmaatschap van de ledenklasse"
89 |
90 | option_dyngroups_disabled: "Uitgeschakeld"
91 | option_dyngroups_enabled: "Ingeschakeld"
92 | option_dyngroups_enabled_with_ttl: "Ingeschakeld met TTL"
93 |
94 | option_sync_on_login_disabled: "Uitgeschakeld"
95 | option_sync_on_login_user_fields: "Gebruikersvelden"
96 | option_sync_on_login_user_fields_and_groups: "Gebruikersvelden en -groepen"
97 |
98 | text_ldap_setting_successfully_updated: "LDAP configuratie is succesvol aangepast."
99 |
100 | field_base_settings: "Basisinstellingen"
101 | option_custom: "Gepersonaliseerd"
102 |
103 | error_cannot_enable_with_invalid_settings: "Synchronisatie kan niet worden ingeschakeld door ongeldige instellingen. Controleer de configuratie-instellingen."
104 |
105 | errors:
106 | messages:
107 | invalid_ldap_attribute: "%{field} heeft een ongeldig LDAP-attribuut"
108 | must_have_ldap_attribute: "%{field} moet een LDAP-attribuut hebben dat kan worden gesynchroniseerd"
109 | invalid_expression: "bevat een ongeldige expressie: %{error_message}"
110 | invalid_regexp: "bevat een ongeldige reguliere expressie: %{error_message}"
--------------------------------------------------------------------------------
/config/locales/pl.yml:
--------------------------------------------------------------------------------
1 | pl:
2 | label_ldap_synchronization: "Synchronizacja LDAP"
3 | label_ldap_settings: "Ustawienia LDAP"
4 | label_ldap_servers: "Serwery LDAP"
5 | label_synchronization_actions: "Akcje synchronizacji"
6 | label_synchronize: "Synchronizuj"
7 | label_ldap_attribute: "Atrybuty LDAP"
8 | label_default_value: "Domyślna wartość"
9 | label_test: "Test"
10 | label_result: "Wynik"
11 | label_minutes: "minuty"
12 |
13 | label_not_executed: "Nie uruchomione"
14 | label_no_fields: "Brak pól"
15 | label_not_found: "Nie znaleziono"
16 | label_users_enabled: "Włączeni użytkownicy"
17 | label_a_total_of: "łącznie %{count}"
18 | label_users_locked_by_flag: "Użytkownicy wyłączeni poprzez flagi"
19 | label_users_locked_by_group: "Użytkownicy wyłączeni przez grupy"
20 | label_admin_users: "Administratorzy"
21 | label_dynamic_groups: "Dynamiczne grupy"
22 | label_ldap_attributes_on_a_user: "Atrybuty LDAP użytkownika"
23 | label_ldap_attributes_on_a_group: "Atrybuty LDAP grupy"
24 | label_log_messages: "Wiadomości z Logów"
25 |
26 | button_test: "Test"
27 | button_execute: "Uruchom"
28 | button_enable: "Włącz"
29 | button_disable: "Wyłącz"
30 |
31 | header_create_groups: "Utwórz grupy"
32 | header_create_users: "Utwórz użytkowników"
33 | header_sync_user_fields: "Synchronizuj pola użytkowników"
34 | header_sync_group_fields: "Synchronizuj pola grup"
35 |
36 | field_nested_groups: "Grupy zagnieżdżone"
37 | field_create_groups: "Utwórz grupy"
38 | field_create_users: "Utwórz użytkowników"
39 | field_sync_on_login: "Synchronizuj przy logowaniu"
40 | field_dyngroups: "Dynamiczne grupy"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Bazowy DN grup"
44 | field_group_membership: "Członkowstwo grupy"
45 | field_class_user: "ObjectClass użytkowników"
46 | field_users_search_scope: "Ścieżka szukania użytkowników"
47 | field_class_group: "ObjectClass grup"
48 | field_account_locked_test: "Test na konto wyłączone"
49 |
50 | field_groupname_pattern: "Wzór nazwy grup"
51 | field_group_search_filter: "Filtr szukania grup"
52 |
53 | field_groupname: "Nazwa grupy"
54 | field_member: "Członek (użytkownik)"
55 | field_member_group: "Grupy członka (grupa)"
56 | field_parent_group: "Grupy rodzica (grupa)"
57 | field_user_memberid: "ID członka (użytkownik)"
58 | field_group_memberid: "ID członka grupy"
59 | field_group_parentid: "ID rodzica grupy"
60 | field_user_groups: "Grupy użytkownika"
61 | field_groupid: "ID grupy"
62 | field_account_flags: "Flagi konta użytkownika"
63 | field_primary_group: "Podstawowa grupa użytkownika"
64 |
65 | field_required_group: "Użytkownicy muszą być członkami"
66 | field_admin_group: "Administratorzy grupy"
67 | field_fixed_group: "Dodaj użytkowników do grupy"
68 |
69 | field_user_group_fields: "Pola użytkownik/grupa"
70 | field_firstname: "Imię"
71 | field_lastname: "Nazwisko"
72 | field_mail: "Email"
73 |
74 | field_test_users: "Użytkownicy"
75 | field_test_groups: "Grupy"
76 | field_bind_user: "Binduj użytkownika"
77 | field_bind_password: "Binduj hasło"
78 |
79 | option_users_search_subtree: "Całe drzewo"
80 | option_users_search_onelevel: "Jeden poziom"
81 |
82 | option_group_membership_on_groups: "W klasie grupy"
83 | option_group_membership_on_members: "W klasie użytkownika"
84 |
85 | option_nested_groups_disabled: "Wyłączone"
86 | option_nested_groups_on_parents: "Członkowstwo w klasie nadrzędnej"
87 | option_nested_groups_on_members: "Członkowstwo w klasie członka"
88 |
89 | option_dyngroups_disabled: "Wyłączone"
90 | option_dyngroups_enabled: "Włączone"
91 | option_dyngroups_enabled_with_ttl: "Włączone z TTL"
92 |
93 | option_sync_on_login_disabled: "Wyłączone"
94 | option_sync_on_login_user_fields: "Pola użytkownika"
95 | option_sync_on_login_user_fields_and_groups: "Pola użytkowników i grup"
96 |
97 | text_ldap_setting_successfully_updated: "Konfiguracja LDAP zapisana pomyślnie."
98 |
99 | field_base_settings: "Ustawienia podstawowe"
100 | option_custom: "Dostosowane"
101 |
102 | error_cannot_enable_with_invalid_settings: "Nie można włączyć synchronizacji z nieprawidłowymi ustawieniami. Proszę poprawić konfigurację."
103 |
104 | errors:
105 | messages:
106 | invalid_ldap_attribute: "%{field} posiada nieprawidłowy atrybut LDAP"
107 | must_have_ldap_attribute: "%{field} musi posiadać atrybut LDAP, aby można było synchronizować"
108 | invalid_expression: "zawiera nieprawidłowe wyrażenie: %{error_message}"
109 | invalid_regexp: "zawiera nieprawidłowe wyrażenie regularne: %{error_message}"
110 |
--------------------------------------------------------------------------------
/config/locales/pt.yml:
--------------------------------------------------------------------------------
1 | pt:
2 | label_ldap_synchronization: "Syncronização LDAP"
3 | label_ldap_settings: "Definições LDAP"
4 | label_ldap_servers: "Servidores LDAP"
5 | label_synchronization_actions: "Acções de sincronização"
6 | label_synchronize: "Sincronizar"
7 | label_ldap_attribute: "Atributo LDAP"
8 | label_default_value: "Valor por omissão"
9 | label_test: "Teste"
10 | label_result: "Resultado"
11 | label_minutes: "minutos"
12 |
13 | label_not_executed: "Não executado"
14 | label_no_fields: "Sem dados"
15 | label_not_found: "Não encontrado"
16 | label_users_enabled: "Utilizadores activos"
17 | label_a_total_of: "no total de %{count}"
18 | label_users_locked_by_flag: "Utilizadores inactivos por flag"
19 | label_users_locked_by_group: "Utilizadores inactivos por grupo"
20 | label_admin_users: "Administradores redmine"
21 | label_dynamic_grous: "Grupos dinâmicos"
22 | label_ldap_attributes_on_a_user: "Atributos LDAP num utilizador"
23 | label_ldap_attributes_on_a_group: "Atributos LDAP num group"
24 | label_log_messages: "Messagens de log"
25 |
26 | button_test: "Testar"
27 | button_execute: "Executar"
28 | button_enable: "Activar"
29 | button_disable: "Desactivar"
30 |
31 | header_create_groups: "Criar grupos"
32 | header_create_users: "Criar util."
33 | header_sync_user_fields: "Sinc. dados util."
34 | header_sync_group_fields: "Sinc. dados grupos"
35 |
36 | field_nested_groups: "Hierarquia de grupos"
37 | field_create_groups: "Criar grupos"
38 | field_create_users: "Criar utilizadores"
39 | field_sync_on_login: "Sincronizar no login"
40 | field_dyngroups: "Grupos dinâmicos"
41 | field_dyngroups_cache_ttl: "Cache TTL"
42 |
43 | field_groups_base_dn: "Base DN dos grupos"
44 | field_group_membership: "Relação grupo-membro"
45 | field_class_user: "Objectclass de utilizadores"
46 | field_users_search_scope: "Âmbito da pesquisa de utilizadores"
47 | field_class_group: "Objectclass de grupos"
48 | field_account_locked_test: "Teste de conta desactivada"
49 |
50 | field_groupname_pattern: "Filtro regex de grupos"
51 | field_group_search_filter: "Filtro de pesquisa de grupos"
52 |
53 | field_groupname: "Nome do grupo (grupo)"
54 | field_member: "Membros (grupo)"
55 | field_member_group: "Grupos membros (grupo)"
56 | field_parent_group: "Grupos pais (grupo)"
57 | field_user_memberid: "ID do membro (utilizador)"
58 | field_group_memberid: "ID do grupo membro (grupo)"
59 | field_group_parentid: "ID do grupo pai (grupo)"
60 | field_user_groups: "Grupos (utilizador)"
61 | field_groupid: "ID do grupo (grupo)"
62 | field_account_flags: "Flags de controlo (utilizador)"
63 | field_primary_group: "Grupo primário (utilizador)"
64 |
65 | field_required_group: "Bloquear não membros do grupo"
66 | field_admin_group: "Administradores são membros do grupo"
67 | field_fixed_group: "Adicionar novos utilizadores ao grupo"
68 |
69 | field_user_group_fields: "Dados de utilizadores/grupos"
70 | field_firstname: "Nome"
71 | field_lastname: "Apelido"
72 | field_mail: "E-mail"
73 |
74 | field_test_users: "Utilizadores"
75 | field_test_groups: "Grupos"
76 |
77 | option_users_search_subtree: "Toda a subarvore"
78 | option_users_search_onelevel: "Um nível"
79 |
80 | option_group_membership_on_groups: "No grupo"
81 | option_group_membership_on_members: "No utilizador"
82 |
83 | option_nested_groups_disabled: "Desactivada"
84 | option_nested_groups_on_parents: "Relação no grupo pai"
85 | option_nested_groups_on_members: "Relação no grupo membro"
86 |
87 | option_dyngroups_disabled: "Desactivado"
88 | option_dyngroups_enabled: "Activo"
89 | option_dyngroups_enabled_with_ttl: "Activo com um TTL"
90 |
91 | option_sync_on_login_disabled: "Desactivado"
92 | option_sync_on_login_user_fields: "Dados dos utilizadores"
93 | option_sync_on_login_user_fields_and_groups: "Dados e grupos dos utilizadores"
94 |
95 | text_ldap_setting_successfully_updated: "Definições LDAP actualizadas com sucesso."
96 |
97 | field_base_settings: "Configuração base"
98 | option_custom: "Personalizado"
99 |
100 | error_cannot_enable_with_invalid_settings: "Não é possivel activar a sincronização enquanto houverem erros na configuração. Deverá rever a configuração."
101 |
102 | errors:
103 | messages:
104 | invalid_ldap_attribute: "%{value} tem um atributo LDAP inválido"
105 | must_have_ldap_attribute: "%{value} requere um atributo LDAP para ser sincronizado"
106 | invalid_expression: "contém uma expressão não válida: %{error_message}"
107 | invalid_regexp: "contém uma expressão regular não válida: %{error_message}"
--------------------------------------------------------------------------------
/config/locales/ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | label_ldap_synchronization: "Синхронизация с LDAP"
3 | label_ldap_settings: "Настройки LDAP"
4 | label_ldap_servers: "Серверы LDAP"
5 | label_synchronization_actions: "Действия синхронизации"
6 | label_synchronize: "Синхронизировать"
7 | label_ldap_attribute: "Атрибут LDAP"
8 | label_default_value: "Значение по умолчанию"
9 | label_test: "Проверка"
10 | label_result: "Результат"
11 | label_minutes: "минут"
12 |
13 | label_not_executed: "Не выполнялась"
14 | label_no_fields: "Нет полей"
15 | label_not_found: "Не найден"
16 | label_users_enabled: "пользователей разблокировано"
17 | label_a_total_of: "Всего %{count}"
18 | label_users_locked_by_flag: "пользователей заблокировано по флагу"
19 | label_users_locked_by_group: "пользователей заблокировано по группе"
20 | label_admin_users: "Администраторы"
21 | label_dynamic_groups: "Динамические группы"
22 | label_ldap_attributes_on_a_user: "Атрибуты LDAP пользователя"
23 | label_ldap_attributes_on_a_group: "Атрибуты LDAP группы"
24 | label_log_messages: "Сообщения журнала"
25 |
26 | button_test: "Проверка"
27 | button_execute: "Выполнить"
28 | button_enable: "Включить"
29 | button_disable: "Выключить"
30 |
31 | header_create_groups: "Создание групп"
32 | header_create_users: "Создание пользователей"
33 | header_sync_user_fields: "Синх. пользователей"
34 | header_sync_group_fields: "Синх. группы"
35 |
36 | field_nested_groups: "Вложенные группы"
37 | field_create_groups: "Создавать группы"
38 | field_create_users: "Создавать пользователей"
39 | field_sync_on_login: "Синхронизировать при входе"
40 | field_dyngroups: "Динамические группы"
41 | field_dyngroups_cache_ttl: "TTL кеша"
42 |
43 | field_groups_base_dn: "Базовый DN для групп"
44 | field_group_membership: "Членство в группах"
45 | field_class_user: "objectclass пользователей"
46 | field_users_search_scope: "Users search scope"
47 | field_class_group: "objectclass групп"
48 | field_account_locked_test: "Проверка заблокированности учетной записи"
49 |
50 | field_groupname_pattern: "Шаблон имени группы"
51 | field_group_search_filter: "Фильтр поиска групп"
52 |
53 | field_groupname: "Название группы (группа)"
54 | field_member: "Подчиненные пользователи (группа)"
55 | field_member_group: "Подчиненные группы (группа)"
56 | field_parent_group: "Родительские группы (группа)"
57 | field_user_memberid: "id подчиненного (пользователь)"
58 | field_group_memberid: "id подчиненного (группа)"
59 | field_group_parentid: "id родителя (группа)"
60 | field_user_groups: "Группы (пользователь)"
61 | field_groupid: "id группы (группа)"
62 | field_account_flags: "Флаги учетной записи (пользователь)"
63 | field_primary_group: "Основная группа (пользователь)"
64 |
65 | field_required_group: "Пользователи должны входить в группу"
66 | field_admin_group: "Группа администраторов"
67 | field_fixed_group: "Добавлять пользователей в группы"
68 | field_group_prefix: "Добавлять префикс к имени группы"
69 |
70 | field_user_group_fields: "Поля пользователя/группы"
71 | field_firstname: "Имя"
72 | field_lastname: "Фамилия"
73 | field_mail: "Email"
74 |
75 | field_test_users: "Пользователи"
76 | field_test_groups: "Группы"
77 |
78 | option_users_search_subtree: "Whole subtree"
79 | option_users_search_onelevel: "One level"
80 |
81 | option_group_membership_on_groups: "Список пользователей содержится в группе "
82 | option_group_membership_on_members: "Список групп содержится в пользователе"
83 |
84 | option_nested_groups_disabled: "Выключены"
85 | option_nested_groups_on_parents: "Список подчиненных групп содержится в родительской группе"
86 | option_nested_groups_on_members: "Список родительских групп содержится в подчиненной группе"
87 |
88 | option_dyngroups_disabled: "Выключены"
89 | option_dyngroups_enabled: "Включены"
90 | option_dyngroups_enabled_with_ttl: "Включены с TTL"
91 |
92 | option_sync_on_login_disabled: "Ничего"
93 | option_sync_on_login_user_fields: "Данные пользователя"
94 | option_sync_on_login_user_fields_and_groups: "Данные и группы пользователя"
95 |
96 | text_ldap_setting_successfully_updated: "Конфигурация Ldap успешно обновлена."
97 |
98 | field_base_settings: "Базовые настройки"
99 | option_custom: "Вручную"
100 |
101 | error_cannot_enable_with_invalid_settings: "Нельзя включить синхронизацию с неправильными настройками. Пожалуйста проверьте настройки."
102 |
103 | errors:
104 | messages:
105 | invalid_ldap_attribute: "Поле '%{field}' имеет неправильный атрибут LDAP"
106 | must_have_ldap_attribute: "Для синхронизации поле '%{field}' должно иметь атрибут LDAP"
107 | invalid_expression: "содержит неправильное выражение: %{error_message}"
108 | invalid_regexp: "содержит неправильное регулярное выражение: %{error_message}"
109 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | resources :ldap_settings, :path => 'admin/ldap_sync', :only => [:show, :edit, :update, :index] do
19 | member do
20 | put 'test'
21 | put 'disable'
22 | put 'enable'
23 | end
24 | get 'base_settings', :constraints => { :format => /js/ }, :on => :collection
25 | end
26 |
--------------------------------------------------------------------------------
/db/migrate/201108021245_change_settings_name.rb:
--------------------------------------------------------------------------------
1 | class ChangeSettingsName < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:add_to_group] = settings.delete(:domain_group)
12 | settings[:groupname_pattern] = settings.delete(:groupname_filter)
13 | settings[:create_groups] = true
14 | settings[:create_users] = true
15 | settings[:sync_user_attributes] = false
16 | settings[:attr_member] = 'member'
17 | settings[:class_group] = 'group'
18 | settings[:class_user] = 'user'
19 | Setting.plugin_redmine_ldap_sync = all_settings
20 | end if settings
21 | end
22 | end
23 |
24 | def self.down
25 | # Nothing to do here
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/db/migrate/201110050735_add_user_memberid_setting.rb:
--------------------------------------------------------------------------------
1 | class AddUserMemberidSetting < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:attr_user_memberid] = 'dn'
12 | Setting.plugin_redmine_ldap_sync = all_settings
13 | end if settings
14 | end
15 | end
16 |
17 | def self.down
18 | # Nothing to do here
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/db/migrate/201111271700_add_group_membership_setting.rb:
--------------------------------------------------------------------------------
1 | class AddGroupMembershipSetting < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:group_membership] = 'on_groups'
12 | settings[:attr_user_groups] = 'memberof'
13 | settings[:attr_groupid] = 'distinguishedName'
14 | Setting.plugin_redmine_ldap_sync = all_settings
15 | end if settings
16 | end
17 | end
18 |
19 | def self.down
20 | # Nothing to do here
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/db/migrate/201201010043_create_ldap_cache_dir.rb:
--------------------------------------------------------------------------------
1 | class CreateLdapCacheDir < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | cache_dir = Rails.root.join("tmp/ldap_cache")
5 | say_with_time "Creating path '#{cache_dir}'" do
6 | FileUtils.mkdir_p cache_dir
7 | end
8 | end
9 |
10 | def self.down
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/201201071359_update_attributes_to_sync.rb:
--------------------------------------------------------------------------------
1 | class UpdateAttributesToSync < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings.delete(:sync_user_attributes)
12 | settings[:user_fields_to_sync] = settings[:attributes_to_sync]
13 | settings.delete(:attributes_to_sync)
14 | Setting.plugin_redmine_ldap_sync = all_settings
15 | end if settings
16 | end
17 | end
18 |
19 | def self.down
20 | # nothing to do
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/db/migrate/201201291950_rename_must_be_member_of_and_add_to_group_settings.rb:
--------------------------------------------------------------------------------
1 | class RenameMustBeMemberOfAndAddToGroupSettings < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:required_group] = settings[:must_be_member_of]
12 | settings[:fixed_group] = settings[:add_to_group]
13 | Setting.plugin_redmine_ldap_sync = all_settings
14 | end if settings
15 | end
16 | end
17 |
18 | def self.down
19 | all_settings = Setting.plugin_redmine_ldap_sync
20 | return unless all_settings
21 |
22 | AuthSourceLdap.all.each do |as|
23 | settings = all_settings[as.name]
24 |
25 | say_with_time "Updating settings for '#{as.name}'" do
26 | settings[:must_be_member_of] = settings[:required_group]
27 | settings[:add_to_group] = settings[:fixed_group]
28 | Setting.plugin_redmine_ldap_sync = all_settings
29 | end if settings
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/db/migrate/201201302250_remove_attr_prefix_settings.rb:
--------------------------------------------------------------------------------
1 | class RemoveAttrPrefixSettings < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:groupname] = settings[:attr_groupname]
12 | settings[:member] = settings[:attr_member]
13 | settings[:user_memberid] = settings[:attr_user_memberid]
14 | settings[:user_groups] = settings[:attr_user_groups]
15 | settings[:groupid] = settings[:attr_groupid]
16 | settings[:member_group] = settings[:attr_member_group]
17 | settings[:goup_memberid] = settings[:attr_group_memberid]
18 | Setting.plugin_redmine_ldap_sync = all_settings
19 | end if settings
20 | end
21 | end
22 |
23 | def self.down
24 | all_settings = Setting.plugin_redmine_ldap_sync
25 | return unless all_settings
26 |
27 | AuthSourceLdap.all.each do |as|
28 | settings = all_settings[as.name]
29 |
30 | say_with_time "Updating settings for '#{as.name}'" do
31 | settings[:attr_groupname] = settings[:groupname]
32 | settings[:attr_member] = settings[:member]
33 | settings[:attr_user_memberid] = settings[:user_memberid]
34 | settings[:attr_user_groups] = settings[:user_groups]
35 | settings[:attr_groupid]= settings[:groupid]
36 | settings[:attr_member_group] = settings[:member_group]
37 | settings[:attr_group_memberid] = settings[:goup_memberid]
38 | Setting.plugin_redmine_ldap_sync = all_settings
39 | end if settings
40 | end
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/db/migrate/201202082153_add_account_flags_setting.rb:
--------------------------------------------------------------------------------
1 | class AddAccountFlagsSetting < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:account_flags] = 'userAccountControl'
12 | settings[:account_disabled_test] = 'flags.to_i & 2 != 0'
13 | Setting.plugin_redmine_ldap_sync = all_settings
14 | end if settings
15 | end
16 | end
17 |
18 | def self.down
19 | # nothing to do
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/db/migrate/201211202050_update_check_box_values.rb:
--------------------------------------------------------------------------------
1 | class UpdateCheckBoxValues < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:active] = (['yes', '1'].include?(settings[:active])? '1': '0')
12 | settings[:create_groups] = (['yes', '1'].include?(settings[:create_groups])? '1': '0')
13 | settings[:create_users] = (['yes', '1'].include?(settings[:create_users])? '1': '0')
14 | settings[:sync_user_attributes] = (['yes', '1'].include?(settings[:sync_user_attributes])? '1': '0')
15 | Setting.plugin_redmine_ldap_sync = all_settings
16 | end if settings
17 | end
18 | end
19 |
20 | def self.down
21 | # nothing to do
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/db/migrate/201302052050_update_user_group_fields.rb:
--------------------------------------------------------------------------------
1 | class UpdateUserGroupFields < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:group_fields_to_sync] ||= []
12 | settings[:user_fields_to_sync] ||= []
13 | settings[:user_ldap_attrs] ||= {}
14 | settings[:group_ldap_attrs] ||= {}
15 | Setting.plugin_redmine_ldap_sync = all_settings
16 | end if settings
17 | end
18 | end
19 |
20 | def self.down
21 | # nothing to do
22 | end
23 | end
--------------------------------------------------------------------------------
/db/migrate/201302202301_change_setting_id_from_name_to_auth_source_id.rb:
--------------------------------------------------------------------------------
1 | class ChangeSettingIdFromNameToAuthSourceId < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.name]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | all_settings[as.id] = settings
12 | all_settings.delete as.name
13 |
14 | Setting.plugin_redmine_ldap_sync = all_settings
15 | end if settings
16 | end
17 | end
18 |
19 | def self.down
20 | all_settings = Setting.plugin_redmine_ldap_sync
21 | return unless all_settings
22 |
23 | AuthSourceLdap.all.each do |as|
24 | settings = all_settings[as.id]
25 |
26 | say_with_time "Updating settings for '#{as.name}'" do
27 | all_settings[as.name] = settings
28 | all_settings.delete as.id
29 |
30 | Setting.plugin_redmine_ldap_sync = all_settings
31 | end if settings
32 | end
33 | end
34 | end
--------------------------------------------------------------------------------
/db/migrate/201302212308_enable_sync_on_login.rb:
--------------------------------------------------------------------------------
1 | class EnableSyncOnLogin < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.id]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:sync_on_login] = 'user_fields_and_groups'
12 |
13 | Setting.plugin_redmine_ldap_sync = all_settings
14 | end if settings
15 | end
16 | end
17 |
18 | def self.down
19 | # nothing to do
20 | end
21 | end
--------------------------------------------------------------------------------
/db/migrate/201503252355_add_users_search_scope.rb:
--------------------------------------------------------------------------------
1 | class AddUsersSearchScope < ActiveRecord::Migration[4.2]
2 |
3 | def self.up
4 | all_settings = Setting.plugin_redmine_ldap_sync
5 | return unless all_settings
6 |
7 | AuthSourceLdap.all.each do |as|
8 | settings = all_settings[as.id]
9 |
10 | say_with_time "Updating settings for '#{as.name}'" do
11 | settings[:users_search_scope] = 'subtree'
12 |
13 | Setting.plugin_redmine_ldap_sync = all_settings
14 | end if settings
15 | end
16 | end
17 |
18 | def self.down
19 | # nothing to do
20 | end
21 |
22 | end
--------------------------------------------------------------------------------
/db/migrate/20170524063056_rename_account_disabled_test.rb:
--------------------------------------------------------------------------------
1 | class RenameAccountDisabledTest < ActiveRecord::Migration[4.2]
2 | def self.up
3 | all_settings = Setting.plugin_redmine_ldap_sync
4 | return unless all_settings
5 |
6 | AuthSourceLdap.all.each do |as|
7 | settings = all_settings[as.id]
8 |
9 | say_with_time "Updating settings for '#{as.name}'" do
10 | settings[:account_locked_test] = settings[:account_disabled_test]
11 | settings.delete(:account_disabled_test)
12 | Setting.plugin_redmine_ldap_sync = all_settings
13 | end if settings
14 | end
15 | end
16 |
17 | def self.down
18 | all_settings = Setting.plugin_redmine_ldap_sync
19 | return unless all_settings
20 |
21 | AuthSourceLdap.all.each do |as|
22 | settings = all_settings[as.id]
23 |
24 | say_with_time "Updating settings for '#{as.name}'" do
25 | settings[:account_disabled_test] = settings[:account_locked_test]
26 | settings.delete(:account_locked_test)
27 | Setting.plugin_redmine_ldap_sync = all_settings
28 | end if settings
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/doc/RUNNING_TESTS:
--------------------------------------------------------------------------------
1 | Running the tests
2 | =================
3 |
4 | Run `NAME=redmine_ldap_sync rake redmine:plugins:test` to execute all
5 | the tests.
6 |
7 |
8 | Creating a test ldap database
9 | =============================
10 |
11 | Install slapd and make sure the server can be reached at 127.0.0.1 on port 389.
12 |
13 | Initialize the config database with:
14 | `slaptest -f redmine_ldap_sync/test/fixtures/ldap/slapd.conf -F /etc/ldap/slapd.d/`
15 | `chown -R openldap:openldap /etc/ldap/slapd.d /var/lib/ldap`
16 |
17 | Restart slapd and load the sample data with:
18 | `ldapadd -Dcn=admin,dc=redmine,dc=org -w password -f redmine_ldap_sync/test/fixtures/ldap/test-ldap.ldif -c`
19 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | require 'redmine'
2 |
3 | Redmine::Plugin.register :redmine_ldap_sync do
4 | name 'Redmine LDAP Sync'
5 | author 'Ricardo Santos, Taine Woo'
6 | author_url 'https://github.com/tainewoo'
7 | description 'Syncs users and groups with ldap'
8 | url 'https://github.com/tainewoo/redmine_ldap_sync'
9 | version '2.2.0'
10 | requires_redmine :version_or_higher => '2.1.0'
11 |
12 | settings :default => HashWithIndifferentAccess.new()
13 | menu :admin_menu, :ldap_sync, { :controller => 'ldap_settings', :action => 'index' }, :caption => :label_ldap_synchronization,
14 | :html => {:class => 'icon icon-ldap-sync'}
15 | end
16 |
17 | #RedmineApp::Application.config.after_initialize do
18 | Rails.application.config.to_prepare do
19 | require_dependency 'ldap_sync/core_ext'
20 | require_dependency 'ldap_sync/infectors'
21 | end
22 |
23 | # hooks
24 | require_dependency 'ldap_sync/hooks'
25 |
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/ber.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | if ('0.12.0'..'0.13.0') === Gem.loaded_specs['net-ldap'].version.to_s
19 | require 'net/ber'
20 |
21 | ##
22 | # A String object with a BER identifier attached.
23 | #
24 | class Net::BER::BerIdentifiedString < String
25 | attr_accessor :ber_identifier
26 |
27 | # The binary data provided when parsing the result of the LDAP search
28 | # has the encoding 'ASCII-8BIT' (which is basically 'BINARY', or 'unknown').
29 | #
30 | # This is the kind of a backtrace showing how the binary `data` comes to
31 | # BerIdentifiedString.new(data):
32 | #
33 | # @conn.read_ber(syntax)
34 | # -> StringIO.new(self).read_ber(syntax), i.e. included from module
35 | # -> Net::BER::BERParser.read_ber(syntax)
36 | # -> (private)Net::BER::BERParser.parse_ber_object(syntax, id, data)
37 | #
38 | # In the `#parse_ber_object` method `data`, according to its OID, is being
39 | # 'casted' to one of the Net::BER:BerIdentifiedXXX classes.
40 | #
41 | # As we are using LDAP v3 we can safely assume that the data is encoded
42 | # in UTF-8 and therefore the only thing to be done when instantiating is to
43 | # switch the encoding from 'ASCII-8BIT' to 'UTF-8'.
44 | #
45 | # Unfortunately, there are some ActiveDirectory specific attributes
46 | # (like `objectguid`) that should remain binary (do they really?).
47 | # Using the `#valid_encoding?` we can trap this cases. Special cases like
48 | # Japanese, Korean, etc. encodings might also profit from this. However
49 | # I have no clue how this encodings function.
50 | def initialize args
51 | super
52 | #
53 | # Check the encoding of the newly created String and set the encoding
54 | # to 'UTF-8' (NOTE: we do NOT change the bytes, but only set the
55 | # encoding to 'UTF-8').
56 | current_encoding = encoding
57 | if current_encoding == Encoding::BINARY
58 | force_encoding('UTF-8')
59 | force_encoding(current_encoding) unless valid_encoding?
60 | end
61 | end
62 | end
63 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/file_store.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | class ActiveSupport::Cache::FileStore
19 | def delete_unless
20 | options = merged_options(options)
21 | search_dir(cache_path) do |path|
22 | key = file_path_key(path)
23 | delete_entry(key, options) unless yield(key)
24 | end
25 | end
26 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/ldap.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require 'net/ldap'
19 |
20 | class Net::LDAP
21 | if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0')
22 | Error = LdapError
23 | end
24 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/ldap_entry.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require 'net/ldap'
19 |
20 | class Net::LDAP
21 | class Entry
22 | include Enumerable
23 | end
24 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/migration.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | class ActiveRecord::Migration
19 | unless defined? self.[]
20 |
21 | # Enables the use of versioned migrations on rails < 5
22 | def self.[](version)
23 | self
24 | end
25 | end
26 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/core_ext/string.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require 'net/ldap'
19 |
20 | module Net::BER::Extensions::String
21 | if Gem.loaded_specs['net-ldap'].version < Gem::Version.new('0.12.0')
22 | def raw_utf8_encoded
23 | if self.respond_to?(:encode) && self.encoding.name != 'ASCII-8BIT'
24 | self.encode('UTF-8').force_encoding('ASCII-8BIT')
25 | else
26 | self
27 | end
28 | end
29 | end
30 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/dry_run/group.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSync::DryRun::Group
19 |
20 | module InstanceMethods
21 | def find_or_create_by_lastname(lastname, attributes = {})
22 | group = find_by_lastname(lastname)
23 | return group if group.present?
24 |
25 | group = ::Group.new(attributes.merge(:lastname => lastname))
26 | puts " !! New group '#{lastname}'" if (group.valid?)
27 |
28 | group
29 | end
30 | end
31 |
32 | def self.included(receiver)
33 | receiver.send(:include, InstanceMethods)
34 |
35 | receiver.instance_eval do
36 | has_and_belongs_to_many :users do
37 | def <<(users)
38 | puts " !! Added to group '#{proxy_association.owner.lastname}'"
39 | end
40 | end
41 | end
42 | end
43 |
44 | end
45 |
--------------------------------------------------------------------------------
/lib/ldap_sync/dry_run/user.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSync::DryRun::User
19 |
20 | module ClassMethods
21 | def create(attributes)
22 | user = User.new(attributes)
23 | yield user if block_given?
24 | user
25 | end
26 | end
27 |
28 | module InstanceMethods
29 | def lock!();end
30 |
31 | def activate!(); end
32 |
33 | def update_attributes(attrs = {}); end
34 |
35 | def save(*args); end
36 | end
37 |
38 | def self.included(receiver)
39 | receiver.extend(ClassMethods)
40 | receiver.send(:include, InstanceMethods)
41 |
42 | receiver.instance_eval do
43 | has_and_belongs_to_many :groups do
44 | def <<(groups)
45 | puts " !! Added to groups '#{groups.map(&:lastname).join("', '")}'" unless groups.empty?
46 | end
47 |
48 | def delete(*groups)
49 | puts " !! Removed from groups '#{groups.map(&:lastname).join("', '")}'" unless groups.empty?
50 | end
51 | end
52 |
53 | remove_method :lock!, :activate!
54 | end
55 |
56 | end
57 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/hooks.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSync
19 | class Hooks < Redmine::Hook::ViewListener
20 |
21 | # Add a question CSS class
22 | def view_layouts_base_html_head(context = { })
23 | stylesheet_link_tag 'ldap_sync.css', :plugin => 'redmine_ldap_sync'
24 | end
25 |
26 | end
27 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/infectors.rb:
--------------------------------------------------------------------------------
1 | module LdapSync::Infectors
2 | Dir[File.join(File.dirname(__FILE__), "infectors", "*.rb")].each do |file|
3 | require_dependency file;
4 | infected_name = File.basename(file, ".rb").classify
5 | _module = const_get(infected_name)
6 | _class = Kernel.const_get(infected_name)
7 | _class.send(:include, _module) unless _class.included_modules.include? _module
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/ldap_sync/infectors/group.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSync::Infectors::Group
19 |
20 | module InstanceMethods
21 | def set_default_values
22 | custom_fields = GroupCustomField.where("default_value is not null")
23 |
24 | self.custom_field_values = custom_fields.each_with_object({}) do |f, h|
25 | h[f.id] = f.default_value
26 | end
27 | end
28 |
29 | def synced_fields=(attrs)
30 | self.custom_field_values = attrs
31 | end
32 | end
33 |
34 | def self.included(receiver)
35 | receiver.send(:include, InstanceMethods)
36 | end
37 |
38 | end
--------------------------------------------------------------------------------
/lib/ldap_sync/infectors/user.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | module LdapSync::Infectors::User
19 | #::User::STANDARD_FIELDS = %w( firstname lastname mail )
20 |
21 | module InstanceMethods
22 | def add_to_fixed_group
23 | return unless auth_source.try :has_fixed_group?
24 |
25 | self.groups << ::Group.where(:lastname => auth_source.fixed_group).first_or_create
26 | end
27 |
28 | def sync_fields_and_groups
29 | return unless sync_on_create?
30 |
31 | auth_source.sync_user(self, false, :login => login, :password => password, :try_to_login => true)
32 | end
33 |
34 | def set_default_values
35 | custom_fields = UserCustomField.where("default_value is not null")
36 | self.custom_field_values = custom_fields.each_with_object({}) do |f, h|
37 | h[f.id] = f.default_value
38 | end
39 |
40 | self.language = Setting.default_language
41 | self.mail_notification = Setting.default_notification_option
42 | end
43 |
44 | def synced_fields=(attrs)
45 | self.attributes = attrs.slice(*::User::STANDARD_FIELDS)
46 | self.custom_field_values = attrs.except(*::User::STANDARD_FIELDS)
47 | end
48 |
49 | def member_of_group?(groupname)
50 | self.groups.exists?(:lastname => groupname)
51 | end
52 |
53 | def set_admin!
54 | self.update_attribute(:admin, true)
55 | end
56 |
57 | def unset_admin!
58 | self.update_attribute(:admin, false)
59 | end
60 |
61 | def archive!
62 | self.groups.destroy_all
63 | self.memberships.each {|m| m.member_roles.destroy_all}
64 | self.lock!
65 | end
66 |
67 | def sync_on_create!; @sync_on_create = true; end
68 | def sync_on_create?; @sync_on_create == true; end
69 |
70 | # Compatibility with redmine 2.x
71 | def email_is_taken
72 | if respond_to?(:email_address)
73 | # Redmine > 3.x
74 | email_address.errors.added? :address, :taken
75 | else
76 | # Redmine < 3.x
77 | errors.added? :mail, :taken
78 | end
79 | end
80 | end
81 |
82 | module ClassMethods
83 | def try_to_login_with_ldap_sync(*args)
84 | user = try_to_login_without_ldap_sync(*args)
85 | return user unless user.try(:sync_on_login?)
86 |
87 | login, password = *args
88 | if user.new_record?
89 | user.sync_on_create!
90 | user unless user.auth_source.locked_on_ldap?(user,
91 | :login => login,
92 | :password => password)
93 | else
94 | user.auth_source.sync_user(user, false, :login => login, :password => password, :try_to_login => true)
95 | user if user.active?
96 | end
97 | rescue => text
98 | raise text
99 | end
100 | end
101 |
102 | def self.included(receiver)
103 | receiver.extend(ClassMethods)
104 | receiver.send(:include, InstanceMethods)
105 |
106 | receiver.instance_eval do
107 | after_create :add_to_fixed_group, :sync_fields_and_groups
108 | delegate :sync_on_login?, :to => :auth_source, :allow_nil => true
109 | end
110 | receiver.class_eval do
111 | class << self
112 | alias_method :try_to_login_without_ldap_sync, :try_to_login
113 | alias_method :try_to_login, :try_to_login_with_ldap_sync
114 | end
115 | end
116 | end
117 | end
118 |
--------------------------------------------------------------------------------
/lib/tasks/ldap_sync.rake:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | namespace :redmine do
19 | namespace :plugins do
20 | namespace :ldap_sync do
21 |
22 | desc "Synchronize redmine's users fields and groups with those on LDAP"
23 | task :sync_users => :environment do |t, args|
24 | init_task
25 |
26 | AuthSourceLdap.activate_users! unless ENV['ACTIVATE_USERS'].nil?
27 | AuthSourceLdap.all.each do |as|
28 | trace "Synchronizing '#{as.name}' users..."
29 | as.sync_users
30 | end
31 | end
32 |
33 | desc "Synchronize redmine's groups fields with those on LDAP"
34 | task :sync_groups => :environment do |t, args|
35 | init_task
36 |
37 | AuthSourceLdap.all.each do |as|
38 | trace "Synchronizing '#{as.name}' groups..."
39 | as.sync_groups
40 | end
41 | end
42 |
43 | desc "Synchronize both redmine's users and groups with LDAP"
44 | task :sync_all => [:sync_groups, :sync_users]
45 |
46 | def init_task
47 | AuthSourceLdap.running_rake!
48 |
49 | if defined?(ActiveRecord::Base)
50 | ActiveRecord::Base.logger = Logger.new(STDOUT)
51 | ActiveRecord::Base.logger.level = Logger::WARN
52 | end
53 |
54 | if %w(debug error change silent).include? ENV['LOG_LEVEL']
55 | AuthSourceLdap.trace_level = ENV['LOG_LEVEL'].to_sym
56 | end
57 |
58 | unless ENV['DRY_RUN'].nil?
59 | trace "\n!!! Dry-run execution !!!\n"
60 |
61 | User.send :include, LdapSync::DryRun::User
62 | Group.send :include, LdapSync::DryRun::Group
63 | end
64 | end
65 | end
66 |
67 | def trace(msg)
68 | return if [:silent, :error, :change].include?(AuthSourceLdap.trace_level)
69 |
70 | puts msg
71 | end
72 |
73 | namespace :redmine_ldap_sync do
74 | task :sync_users => 'redmine:plugins:ldap_sync:sync_users'
75 | end
76 | end
77 | end
--------------------------------------------------------------------------------
/lib/tasks/testing.rake:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require 'rake/testtask'
19 |
20 | namespace :redmine do
21 | namespace :plugins do
22 | namespace :ldap_sync do
23 | LDAP_SYNC='redmine_ldap_sync'
24 |
25 | desc 'Runs the ldap_sync tests.'
26 | task :test do
27 | require 'redmine/version'
28 | Rake::Task["redmine:plugins:ldap_sync:test:units"].invoke
29 | Rake::Task["redmine:plugins:ldap_sync:test:functionals"].invoke
30 | Rake::Task["redmine:plugins:ldap_sync:test:integration"].invoke
31 |
32 | if RUBY_VERSION >= '1.9.3' && Redmine::VERSION.to_s >= '2.3.0'
33 | Rake::Task["redmine:plugins:ldap_sync:test:ui"].invoke
34 | end
35 | end
36 |
37 | namespace :test do
38 | desc 'Runs the plugins ui tests.'
39 | Rake::TestTask.new :ui => "db:test:prepare" do |t|
40 | t.libs << "test"
41 | t.verbose = true
42 | t.pattern = "plugins/#{LDAP_SYNC}/test/ui/**/*_test.rb"
43 | end
44 |
45 | desc 'Runs the plugins unit tests.'
46 | Rake::TestTask.new :units => "db:test:prepare" do |t|
47 | t.libs << "test"
48 | t.verbose = true
49 | t.pattern = "plugins/#{LDAP_SYNC}/test/unit/**/*_test.rb"
50 | end
51 |
52 | desc 'Runs the plugins functional tests.'
53 | Rake::TestTask.new :functionals => "db:test:prepare" do |t|
54 | t.libs << "test"
55 | t.verbose = true
56 | t.pattern = "plugins/#{LDAP_SYNC}/test/functional/**/*_test.rb"
57 | end
58 |
59 | desc 'Runs the plugins integration tests.'
60 | Rake::TestTask.new :integration => "db:test:prepare" do |t|
61 | t.libs << "test"
62 | t.verbose = true
63 | t.pattern = "plugins/#{LDAP_SYNC}/test/integration/**/*_test.rb"
64 | end
65 | end
66 |
67 | namespace :coveralls do
68 | desc "Push latest coverage results to Coveralls.io"
69 | task :test => 'redmine:plugins:ldap_sync:test' do
70 | require 'simplecov'
71 | ::SimpleCov.root Rails.root.join('plugins', "#{LDAP_SYNC}")
72 |
73 | require 'coveralls'
74 | Coveralls.push!
75 | end
76 | end
77 | end
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/script/ci.sh:
--------------------------------------------------------------------------------
1 | #/bin/bash
2 | set -e # exit if any command fails
3 |
4 | setenv() {
5 | export RAILS_ENV=test
6 | export RUBYOPT=-W1
7 | export IN_RBL_TESTENV=true
8 | export PATH_TO_LDAPSYNC=$(pwd)
9 | export RUBY_VERSION=$(ruby -e 'print RUBY_VERSION')
10 | if [[ -z "$REDMINE" ]]; then
11 | echo "You have not set REDMINE"
12 | exit 1
13 | fi
14 | if [ "$VERBOSE" = "yes" ]; then export TRACE=--trace; fi
15 | if [ ! "$VERBOSE" = "yes" ]; then export QUIET=--quiet; fi
16 |
17 | case $REDMINE in
18 | 2.*.*) export PATH_TO_PLUGINS=./plugins # for redmine 2.x.x
19 | export REDMINE_TARBALL=https://github.com/edavis10/redmine/archive/$REDMINE.tar.gz
20 | ;;
21 | *.*-stable) export PATH_TO_PLUGINS=./plugins # for redmine 2.x-stable
22 | export REDMINE_SVN_REPO=http://svn.redmine.org/redmine/branches/$REDMINE
23 | ;;
24 | master) export PATH_TO_PLUGINS=./plugins
25 | export REDMINE_SVN_REPO=http://svn.redmine.org/redmine/trunk/
26 | ;;
27 | *) echo "Unsupported platform $REDMINE"
28 | exit 1
29 | ;;
30 | esac
31 | }
32 |
33 | extract_args() {
34 | while :; do
35 | case "$1" in
36 | --target) export TARGET="$2"; shift; shift;;
37 | -*) echo "Invalid argument $1"; exit 2;;
38 | *) break;;
39 | esac
40 | done
41 | }
42 |
43 | trace() {
44 | if [ "$VERBOSE" = "yes" ]; then echo $@; fi
45 | }
46 |
47 | clone_redmine()
48 | {
49 | setenv; extract_args $@
50 |
51 | if [[ -z "$TARGET" ]]; then
52 | echo "You have not set a target directory"; exit 1
53 | fi
54 |
55 | rm -rf $TARGET
56 | if [ -n "${REDMINE_GIT_REPO}" ]; then
57 | git clone -b $REDMINE_GIT_TAG --depth=100 $QUIET $REDMINE_GIT_REPO $TARGET
58 | pushd $TARGET 1> /dev/null
59 | git checkout $REDMINE_GIT_TAG
60 | popd 1> /dev/null
61 | elif [ -n "${REDMINE_HG_REPO}" ]; then
62 | hg clone -r $REDMINE_HG_TAG $QUIET $REDMINE_HG_REPO $TARGET
63 | elif [ -n "${REDMINE_SVN_REPO}" ]; then
64 | svn co $QUIET $REDMINE_SVN_REPO $TARGET
65 | else
66 | mkdir -p $TARGET
67 | wget $REDMINE_TARBALL -O- | tar -C $TARGET -xz --strip=1 --show-transformed -f -
68 | fi
69 | }
70 |
71 | install_plugin_gemfile()
72 | {
73 | setenv
74 |
75 | mkdir $REDMINE_DIR/$PATH_TO_PLUGINS/redmine_ldap_sync
76 | ln -s "$PATH_TO_LDAPSYNC/config/Gemfile.travis" "$REDMINE_DIR/$PATH_TO_PLUGINS/redmine_ldap_sync/Gemfile"
77 |
78 | if [ "$RUBY_VERSION" == "1.8.7" ]; then
79 | sed -i.bak '/test-unit/d' "$REDMINE_DIR/Gemfile"
80 | fi
81 | }
82 |
83 | prepare_redmine()
84 | {
85 | setenv
86 |
87 | pushd $REDMINE_DIR 1> /dev/null
88 |
89 | trace 'Database migrations'
90 | bundle exec rake db:migrate $TRACE
91 |
92 | trace 'Load defaults'
93 | bundle exec rake redmine:load_default_data REDMINE_LANG=en $TRACE
94 |
95 | trace 'Session token'
96 | bundle exec rake generate_secret_token $TRACE
97 |
98 | popd 1> /dev/null
99 | }
100 |
101 | prepare_plugin()
102 | {
103 | setenv
104 |
105 | pushd $REDMINE_DIR 1> /dev/null
106 |
107 | ln -s $PATH_TO_LDAPSYNC/* $PATH_TO_PLUGINS/redmine_ldap_sync
108 |
109 | trace 'Prepare plugins'
110 | bundle exec rake redmine:plugins NAME=redmine_ldap_sync $TRACE
111 |
112 | popd 1> /dev/null
113 | }
114 |
115 | start_ldap()
116 | {
117 | export LDAPNOINIT=yes
118 |
119 | LDAPBASE=$(mktemp --tmpdir=/tmp -d ldapsyncldap.XXXXX)
120 | LDAPCONF=test/fixtures/ldap
121 |
122 | if [ -f /etc/openldap/schema/core.schema ]; then
123 | SCHEMABASE=/etc/openldap/schema
124 | else
125 | SCHEMABASE=/etc/ldap/schema
126 | fi
127 |
128 | echo ${LDAPBASE} > .ldapbase
129 |
130 | mkdir ${LDAPBASE}/db
131 | cp ${LDAPCONF}/slapd.conf ${LDAPBASE}/
132 |
133 | sed -i "s|/var/run/slapd/slapd.pid|${LDAPBASE}/slapd.pid|" ${LDAPBASE}/slapd.conf
134 | sed -i "s|/var/run/slapd/slapd.args|${LDAPBASE}/slapd.pid|" ${LDAPBASE}/slapd.conf
135 | sed -i "s|/var/lib/ldap|${LDAPBASE}/db|" ${LDAPBASE}/slapd.conf
136 | sed -i "s|/etc/ldap/schema|${SCHEMABASE}|" ${LDAPBASE}/slapd.conf
137 |
138 | nohup slapd -d3 -f ${LDAPBASE}/slapd.conf -h 'ldap://localhost:3389/' &> ${LDAPBASE}/slapd.log &
139 |
140 | # Give LDAP a few seconds to start
141 | sleep 3
142 |
143 | if [ ! -z "$VERBOSE" ]; then
144 | cat ${LDAPBASE}/slapd.log
145 | fi
146 |
147 | ldapadd -x -D 'cn=admin,dc=redmine,dc=org' -w password -H 'ldap://localhost:3389/' -f ${LDAPCONF}/test-ldap.ldif > /dev/null
148 | trace "LDAP Started"
149 | }
150 |
151 | run_tests()
152 | {
153 | setenv
154 |
155 | pushd $REDMINE_DIR 1> /dev/null
156 |
157 | if [ "$REDMINE" == "master" ] && [ "$RUBY_VERSION" == "2.4.3" ]; then
158 | bundle exec rake redmine:plugins:ldap_sync:coveralls:test $TRACE
159 | else
160 | bundle exec rake redmine:plugins:ldap_sync:test $TRACE
161 | fi
162 |
163 | popd 1> /dev/null
164 | }
165 |
166 | test_uninstall()
167 | {
168 | setenv
169 |
170 | pushd $REDMINE_DIR 1> /dev/null
171 |
172 | bundle exec rake $TRACE redmine:plugins NAME=redmine_ldap_sync VERSION=0
173 |
174 | popd 1> /dev/null
175 | }
176 |
177 | case "$1" in
178 | "clone_redmine") shift; clone_redmine $@;;
179 | "install_plugin_gemfile") shift; install_plugin_gemfile $@;;
180 | "prepare_redmine") shift; prepare_redmine $@;;
181 | "prepare_plugin") shift; prepare_plugin $@;;
182 | "start_ldap") shift; start_ldap $@;;
183 | "run_tests") shift; run_tests $@;;
184 | "test_uninstall") shift; test_uninstall $@;;
185 | *) echo "clone_redmine; install_plugin_gemfile; prepare_redmine; prepare_plugin; start_ldap; run_tests; test_uninstall";;
186 | esac
187 |
--------------------------------------------------------------------------------
/test/fixtures/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tainewoo/redmine_ldap_sync/95219d5f0ab007db9975a6d0f8e32e78c1f36728/test/fixtures/.gitkeep
--------------------------------------------------------------------------------
/test/fixtures/auth_sources.yml:
--------------------------------------------------------------------------------
1 | ---
2 | auth_sources_001:
3 | id: 1
4 | type: AuthSourceLdap
5 | name: 'LDAP test server'
6 | host: '127.0.0.1'
7 | port: 3389
8 | base_dn: 'DC=redmine,DC=org'
9 | account: 'cn=admin,dc=redmine,dc=org'
10 | account_password: password
11 | attr_login: uid
12 | attr_firstname: givenName
13 | attr_lastname: sn
14 | attr_mail: mail
15 | onthefly_register: true
16 | auth_sources_002:
17 | id: 2
18 | type: AuthSourceLdap
19 | name: 'LDAP test server 2'
20 | host: '127.0.0.2'
21 | port: 3389
22 | base_dn: 'OU=Person,DC=localhost,DC=net'
23 | attr_login: uid
24 | attr_firstname: givenName
25 | attr_lastname: sn
26 | attr_mail: mail
27 | onthefly_register: false
28 |
--------------------------------------------------------------------------------
/test/fixtures/custom_fields.yml:
--------------------------------------------------------------------------------
1 | ---
2 | preferred_language:
3 | name: Preferred Language
4 | min_length: 0
5 | regexp: ""
6 | is_for_all: false
7 | type: UserCustomField
8 | max_length: 0
9 | possible_values: ""
10 | id: 1
11 | is_required: false
12 | field_format: string
13 | default_value: "en"
14 | editable: true
15 | position: 1
16 | uid_number:
17 | name: Uid Number
18 | min_length: 0
19 | regexp: ""
20 | is_for_all: false
21 | type: UserCustomField
22 | max_length: 0
23 | possible_values: ""
24 | id: 2
25 | is_required: true
26 | field_format: int
27 | default_value: 0
28 | editable: false
29 | position: 2
30 | custom_fields_003:
31 | name: Description
32 | min_length: 0
33 | regexp: ""
34 | is_for_all: false
35 | type: GroupCustomField
36 | max_length: 0
37 | possible_values: ""
38 | id: 3
39 | is_required: false
40 | field_format: string
41 | default_value: 'no description'
42 | editable: true
43 | position: 2
--------------------------------------------------------------------------------
/test/fixtures/email_addresses.yml:
--------------------------------------------------------------------------------
1 | ---
2 | email_address_001:
3 | id: 1
4 | user_id: 1
5 | address: admin@somenet.foo
6 | is_default: true
7 | created_on: 2006-07-19 19:34:07 +02:00
8 | updated_on: 2006-07-19 19:34:07 +02:00
9 | email_address_002:
10 | id: 2
11 | user_id: 2
12 | address: rhill@somenet.foo
13 | is_default: true
14 | created_on: 2006-07-19 19:34:07 +02:00
15 | updated_on: 2006-07-19 19:34:07 +02:00
16 | email_address_003:
17 | id: 3
18 | user_id: 3
19 | address: jsmith@somenet.foo
20 | is_default: true
21 | created_on: 2006-07-19 19:34:07 +02:00
22 | updated_on: 2006-07-19 19:34:07 +02:00
23 | email_address_004:
24 | id: 4
25 | user_id: 4
26 | address: dlopper@somenet.foo
27 | is_default: true
28 | created_on: 2006-07-19 19:34:07 +02:00
29 | updated_on: 2006-07-19 19:34:07 +02:00
30 | email_address_005:
31 | id: 5
32 | user_id: 5
33 | address: dlopper2@somenet.foo
34 | is_default: true
35 | created_on: 2006-07-19 19:34:07 +02:00
36 | updated_on: 2006-07-19 19:34:07 +02:00
37 | email_address_007:
38 | id: 7
39 | user_id: 7
40 | address: someone@foo.bar
41 | is_default: true
42 | created_on: 2006-07-19 19:34:07 +02:00
43 | updated_on: 2006-07-19 19:34:07 +02:00
44 | email_address_008:
45 | id: 8
46 | user_id: 8
47 | address: miscuser8@foo.bar
48 | is_default: true
49 | created_on: 2006-07-19 19:34:07 +02:00
50 | updated_on: 2006-07-19 19:34:07 +02:00
51 | email_address_009:
52 | id: 9
53 | user_id: 9
54 | address: miscuser9@foo.bar
55 | is_default: true
56 | created_on: 2006-07-19 19:34:07 +02:00
57 | updated_on: 2006-07-19 19:34:07 +02:00
58 | email_address_010:
59 | id: 10
60 | user_id: 12
61 | address: rubycalm@fakemail.com
62 | is_default: true
63 | created_on: 2006-07-19 19:34:07 +02:00
64 | updated_on: 2006-07-19 19:34:07 +02:00
--------------------------------------------------------------------------------
/test/fixtures/groups_users.yml:
--------------------------------------------------------------------------------
1 | ---
2 | rynever_loadgeek:
3 | group_id: 11
4 | user_id: 8
5 | rynever_someone:
6 | group_id: 11
7 | user_id: 7
8 | rynever_rubycalm:
9 | group_id: 11
10 | user_id: 12
11 | therb_someone:
12 | group_id: 10
13 | user_id: 7
14 | issue_149_someone:
15 | group_id: 13
16 | user_id: 12
--------------------------------------------------------------------------------
/test/fixtures/ldap/names.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 | # encoding: utf-8
3 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
4 | #
5 | # This file is part of Redmine LDAP Sync.
6 | #
7 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # Redmine LDAP Sync 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 General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with Redmine LDAP Sync. If not, see .
19 | rng = Random.new(12345)
20 | USERS = 5
21 | GROUPS = 10
22 |
23 | puts "dn: dc=redmine,dc=org
24 | objectClass: top
25 | objectClass: dcObject
26 | objectClass: organization
27 | o: redmine.org
28 | dc: redmine
29 |
30 | dn: cn=admin,dc=redmine,dc=org
31 | objectClass: simpleSecurityObject
32 | objectClass: organizationalRole
33 | cn: admin
34 | description: LDAP administrator
35 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
36 |
37 | dn: ou=Person,dc=redmine,dc=org
38 | ou: Person
39 | objectClass: organizationalUnit
40 |
41 | dn: ou=Group,dc=redmine,dc=org
42 | ou: Group
43 | objectClass: organizationalUnit\n\n"
44 |
45 | user =
46 | 'dn: uid=%{username},ou=Person,dc=redmine,dc=org
47 | mail: %{mail}
48 | uid: %{username}
49 | cn: %{cn}
50 | preferredLanguage: %{language}
51 | uidNumber: %{uidNumber}
52 | gidNumber: 100
53 | homeDirectory: /home/%{homeDir}
54 | objectClass: posixAccount
55 | objectClass: person
56 | objectClass: inetOrgPerson
57 | givenName: %{givenName}
58 | sn: %{sn}
59 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
60 | loginShell: /bin/sh
61 | '
62 |
63 | group_member = "member: cn=%{groupname},ou=Group,dc=redmine,dc=org\n"
64 | user_member = "member: uid=%{username},ou=Person,dc=redmine,dc=org\n"
65 | user_group = "o: %{gidNumber}\n"
66 | group_group = "o: %{gidNumber}\n"
67 |
68 | group =
69 | 'dn: cn=%{groupname},ou=Group,dc=redmine,dc=org
70 | objectClass: groupOfNames
71 | objectClass: posixAccount
72 | homeDirectory: /nonexistent
73 | gidNumber: %{gidNumber}
74 | uidNumber: %{gidNumber}
75 | uid: %{groupname}
76 | cn: %{groupname}
77 | %{members}'
78 |
79 | groups = %w(
80 | Säyeldas Iardum Bluil Anbely Issekin Briklør Enden
81 | Rynever Worathest Therß Meyl Oany Whod Tiaris
82 | Belecer Rill Strycheser Ustuq Issk Hatosentan Llant
83 | Ghaoll Kimshy Irenth Swien Endash Denardon Hatcer
84 | Aughny Kibyno Tonage Serende Bietroth Engech Aseta
85 | Tanusk Umf Danasho Rakm Honeld Maedtas Skelmos
86 | Sulgard Tonid Leris Rothit Awkin Sand Delusk
87 | Warad Dihen Otiao Therkal Wage Emum Veaw
88 | Inequa Lyeack Agecerat Achkim Enrak Gulut Oveso
89 | Toniv Kalq Tiaorm Calltia Ascerem Kaltia Seraufst
90 | Honibi Quadeny Ridasi Tegh Teguno Sewarhat Poltiaeld
91 | Polhini Liwaren Atler Tinenhin Quever Tanhtor Nysos
92 | Brint Ageaughtor Lleef Yiew Arbche Perusul Ghash
93 | Etum Itxash Lamur Richit Smuaddan Fyzin Endeves
94 | Iuski Tinrothu Lododu Iuste Dimyn Podynen Lopisy
95 | Untros Igara Emique Ruperash Awend Slyaugh Ackrandel
96 | Ustech Anarr Ightwor Aleing Nyrak Cheash Itora
97 | )
98 |
99 | users = %w( LoadGeek
100 | tweetmicro
101 | systemhack
102 | tweetsave
103 | microunit
104 | browserclient
105 | webfiber
106 | cabledrive
107 | graphicsfiber
108 | drivechip
109 | iconfiber
110 | corescript
111 | opticipod
112 | blogarray
113 | processipod
114 | waremicro
115 | digiprocess
116 | digiware
117 | iconoptic
118 | scripttweet
119 | clickturtle
120 | ringshark
121 | popsnake
122 | clickowl
123 | tockgiraffe
124 | itchgiraffe
125 | itchdonkey
126 | clickworm
127 | blowgorilla
128 | scratcheagle
129 | yellowcruel
130 | rubycalm
131 | golldhorror
132 | rubyhopeless
133 | blackhappy
134 | whitecross
135 | limegrumpy
136 | lilacgrim
137 | mauvecrrazy
138 | rosemap
139 | leetbroccoli
140 | banana
141 | carrot
142 | winnuts
143 | lolchips
144 | wthfrogs
145 | lmaococonut
146 | winpie
147 | lmaobanana
148 | failcoconut )
149 |
150 | names = ['Christián Earheart',
151 | 'Rae Croll',
152 | 'Darryl Ditto',
153 | 'Nelson Meriwether',
154 | 'Elnora Gershon',
155 | 'Odessa Stingley',
156 | 'Kelly Cafferty',
157 | 'Dona Austria',
158 | 'Ericka Strohl',
159 | 'Lakisha Kouba',
160 | 'Fernando Dymond',
161 | 'Amie Rodreguez',
162 | 'Tyrone Winders',
163 | 'Rae Degner',
164 | 'Darren Canez',
165 | 'Earnestine Zahm',
166 | 'Fernando Stemm',
167 | 'Tanisha Sprowl',
168 | 'Saundra Nokes',
169 | 'Darren Czerwinski',
170 | 'Lenore Messersmith',
171 | 'Ashlee Stolz',
172 | 'Darryl Schaner',
173 | 'Sofia Lacayo',
174 | 'Sofia Wiers',
175 | 'Lonnie Mccarville',
176 | 'Allie Bavaro',
177 | 'Sharron Conine',
178 | 'Guy Ledger',
179 | 'Carmella Kleffman',
180 | 'Clayton Rodrick',
181 | 'Kathrine Solley',
182 | 'Annabelle Riser',
183 | 'Julio Wurster',
184 | 'Earnestine Camille',
185 | 'Hugh Juarbe',
186 | 'Guy Hodgin',
187 | 'Jamie Alpers',
188 | 'Benita Mccrimmon',
189 | 'Earnestine Guidroz',
190 | 'Ted Formica',
191 | 'Jamie Auton',
192 | 'Guy Gagnier',
193 | 'Tanisha Dahlen',
194 | 'Annabelle Spillane',
195 | 'Noemi Mcalexander',
196 | 'Allan Hynd',
197 | 'Fernando Schaner',
198 | 'Erik Haubert',
199 | 'Jeanie Mazzarella'
200 | ]
201 |
202 | languages = %w( ar ca de en eu fr hr it lt mn pl ro sl sr-YU tr zh-TWbg cs el es fa gl hu ja lv nl pt-BR ru sq sv uk zhbs da en-GB et fi he id ko mk no pt sk sr th vi )
203 |
204 | users = users[0...USERS]
205 | names = names[0...USERS]
206 | groups = groups[0...GROUPS]
207 |
208 | s_users = Hash.new{|h,k| h[k] = ''}
209 | s_groups = Hash.new{|h,k| h[k] = ''}
210 |
211 | n = 300
212 | users.zip(names).each do |username, fullname|
213 | s_users[username] = user.
214 | gsub('%{username}', username).
215 | gsub('%{cn}', fullname).
216 | gsub('%{givenName}', fullname.split(' ')[0]).
217 | gsub('%{sn}', fullname.split(' ')[1]).
218 | gsub('%{mail}', "#{username.downcase}@fakemail.com").
219 | gsub('%{uidNumber}', (n += 1).to_s ).
220 | gsub('%{homeDir}', username).
221 | gsub('%{language}', languages.sample(:random => rng))
222 | end
223 | n = 4000
224 | groups.each do |groupname|
225 | gidNumber = (n += 1).to_s
226 | members = ""
227 | selected_users = []
228 | selected_groups = []
229 | (1..(1+rng.rand(3))).each do |i|
230 | if rng.rand(2) == 0
231 | name = (users - selected_users).sample(:random => rng)
232 | members += user_member.gsub('%{username}', name)
233 | selected_users << name
234 | s_users[name] += user_group.gsub('%{gidNumber}', gidNumber)
235 | else
236 | name = (groups - selected_groups).sample(:random => rng)
237 | members += group_member.gsub('%{groupname}', name)
238 | selected_groups << name
239 | s_groups[name] += group_group.gsub('%{gidNumber}', gidNumber)
240 | end
241 | end
242 | s_groups[groupname] = group.
243 | gsub('%{groupname}', groupname).
244 | gsub('%{gidNumber}', gidNumber).
245 | gsub('%{members}', members) + s_groups[groupname]
246 | end
247 |
248 | # Write everything to stdout
249 | puts s_users.values.join("\n")
250 | puts
251 | puts s_groups.values.join("\n")
252 |
253 | puts '
254 | dn: cn=MicroUsers,ou=Group,dc=redmine,dc=org
255 | objectclass: groupOfURLs
256 | cn: MicroUsers
257 | memberURL: ldap:///ou=Person,dc=redmine,dc=org??sub?(uid=*micro*)
258 |
259 | dn: cn=TweetUsers,ou=Group,dc=redmine,dc=org
260 | objectclass: groupOfURLs
261 | cn: TweetUsers
262 | memberURL: ldap:///ou=Person,dc=redmine,dc=org??sub?(uid=*tweet*)'
263 |
--------------------------------------------------------------------------------
/test/fixtures/ldap/slapd.conf:
--------------------------------------------------------------------------------
1 | #
2 | # LDAP Defaults
3 | #
4 |
5 | # See ldap.conf(5) for details
6 | # This file should be world readable but not world writable.
7 |
8 | #BASE dc=example,dc=com
9 | #URI ldap://ldap.example.com ldap://ldap-master.example.com:666
10 |
11 | #SIZELIMIT 12
12 | #TIMELIMIT 15
13 | #DEREF never
14 |
15 | # TLS certificates (needed for GnuTLS)
16 | #TLS_CACERT /etc/ssl/certs/ca-certificates.crt
17 |
18 | # Sample OpenLDAP configuration file for Redmine LDAP test server
19 | #
20 | #ucdata-path /var/lib/ldap/ucdata
21 | moduleload back_hdb.la
22 | moduleload memberof.la
23 | moduleload dynlist.la
24 |
25 | include /etc/ldap/schema/core.schema
26 | include /etc/ldap/schema/cosine.schema
27 | include /etc/ldap/schema/inetorgperson.schema
28 | include /etc/ldap/schema/openldap.schema
29 | include /etc/ldap/schema/nis.schema
30 | include /etc/ldap/schema/dyngroup.schema
31 | include /etc/ldap/schema/ppolicy.schema
32 |
33 | pidfile /var/run/slapd/slapd.pid
34 | argsfile /var/run/slapd/slapd.args
35 |
36 | database hdb
37 | suffix "dc=redmine,dc=org"
38 | rootdn "cn=admin,dc=redmine,dc=org"
39 | rootpw password
40 | directory /var/lib/ldap
41 | # Indices to maintain
42 | index objectClass eq
43 |
44 | overlay memberof
45 | memberof-group-oc groupOfNames
46 | memberof-member-ad member
47 | memberof-memberof-ad memberOf
48 |
49 | overlay dynlist
50 | dynlist-attrset groupOfURLs memberURL member
--------------------------------------------------------------------------------
/test/fixtures/ldap/test-ldap.ldif:
--------------------------------------------------------------------------------
1 | dn: dc=redmine,dc=org
2 | objectClass: top
3 | objectClass: dcObject
4 | objectClass: organization
5 | o: redmine.org
6 | dc: redmine
7 |
8 | dn: cn=admin,dc=redmine,dc=org
9 | objectClass: simpleSecurityObject
10 | objectClass: organizationalRole
11 | cn: admin
12 | description: LDAP administrator
13 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
14 |
15 | dn: ou=Person,dc=redmine,dc=org
16 | ou: Person
17 | objectClass: organizationalUnit
18 |
19 | dn: ou=Group,dc=redmine,dc=org
20 | ou: Group
21 | objectClass: organizationalUnit
22 |
23 | dn: uid=example1,ou=Person,dc=redmine,dc=org
24 | objectClass: posixAccount
25 | objectClass: inetOrgPerson
26 | gidNumber: 0
27 | givenName: Example
28 | sn: One
29 | uid: example1
30 | homeDirectory: /home/example1
31 | cn: Example One
32 | uidNumber: 900
33 | mail: example1@redmine.org
34 | userPassword:: e1NIQX1mRXFOQ2NvM1lxOWg1WlVnbEQzQ1pKVDRsQnM9
35 |
36 | dn: uid=edavis,ou=Person,dc=redmine,dc=org
37 | objectClass: posixAccount
38 | objectClass: top
39 | objectClass: inetOrgPerson
40 | gidNumber: 0
41 | givenName: Eric
42 | sn: Davis
43 | uid: edavis
44 | mail: edavis@littlestreamsoftware.com
45 | homeDirectory: /home/edavis
46 | cn: Eric Davis
47 | uidNumber: 902
48 | userPassword:: e1NIQX1mRXFOQ2NvM1lxOWg1WlVnbEQzQ1pKVDRsQnM9
49 | o: 4003
50 | o: 100
51 |
52 | dn: uid=LoadGeek,ou=Person,dc=redmine,dc=org
53 | mail: loadgeek@fakemail.com
54 | uid: LoadGeek
55 | cn: Christián Earheart
56 | preferredLanguage: pt
57 | uidNumber: 301
58 | gidNumber: 100
59 | homeDirectory: /home/loadgeek
60 | objectClass: posixAccount
61 | objectClass: person
62 | objectClass: inetOrgPerson
63 | objectClass: pwdPolicy
64 | givenName: Christián
65 | sn: Earheart
66 | description: Earheart User
67 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
68 | loginShell: /bin/sh
69 | pwdAttribute: 2.5.4.35
70 | pwdLockout: TRUE
71 | o: 4005
72 | o: 4007
73 | o: 4009
74 | o: 4015
75 |
76 | dn: uid=tweetmicro,ou=Person,dc=redmine,dc=org
77 | mail: tweetmicro@fakemail.com
78 | uid: tweetmicro
79 | cn: Rae Croll
80 | preferredLanguage: ar
81 | uidNumber: 302
82 | gidNumber: 100
83 | homeDirectory: /home/tweetmicro
84 | description: Tweetmicro user [disabled]
85 | objectClass: posixAccount
86 | objectClass: person
87 | objectClass: inetOrgPerson
88 | givenName: Rae
89 | sn: Croll
90 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
91 | loginShell: /bin/sh
92 | o: 4001
93 | o: 4006
94 | o: 4008
95 | o: 4007
96 |
97 | dn: uid=systemhack,ou=Person,dc=redmine,dc=org
98 | mail: systemhack@fakemail.com
99 | uid: systemhack
100 | cn: Darryl Ditto
101 | preferredLanguage: da
102 | uidNumber: 303
103 | gidNumber: 100
104 | homeDirectory: /home/systemhack
105 | objectClass: posixAccount
106 | objectClass: person
107 | objectClass: inetOrgPerson
108 | givenName: Darryl
109 | sn: Ditto
110 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
111 | loginShell: /bin/sh
112 | o: 4002
113 | o: 4003
114 | o: 4006
115 |
116 | dn: uid=tweetsave,ou=Person,dc=redmine,dc=org
117 | mail: tweetsave@fakemail.com
118 | uid: tweetsave
119 | cn: Nelson Meriwether
120 | preferredLanguage: pl
121 | uidNumber: 304
122 | gidNumber: 100
123 | homeDirectory: /home/tweetsave
124 | objectClass: posixAccount
125 | objectClass: person
126 | objectClass: inetOrgPerson
127 | givenName: Nelson
128 | sn: Meriwether
129 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
130 | loginShell: /bin/sh
131 | o: 4002
132 | o: 4006
133 |
134 | dn: uid=microunit,ou=Person,dc=redmine,dc=org
135 | mail: microunit@fakemail.com
136 | uid: microunit
137 | cn: Elnora Gershon
138 | preferredLanguage: vi
139 | uidNumber: 305
140 | gidNumber: 100
141 | homeDirectory: /home/microunit
142 | objectClass: posixAccount
143 | objectClass: person
144 | objectClass: inetOrgPerson
145 | givenName: Elnora
146 | sn: Gershon
147 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
148 | loginShell: /bin/sh
149 | o: 4002
150 | o: 4005
151 | o: 4007
152 | o: 4008
153 | o: 4009
154 | o: 4015
155 |
156 | dn: uid=incomplete,ou=Person,dc=redmine,dc=org
157 | uid: incomplete
158 | cn: Incomplete User
159 | preferredLanguage: pt
160 | description: User without all the required fields
161 | uidNumber: 306
162 | gidNumber: 100
163 | homeDirectory: /home/incomplete
164 | objectClass: posixAccount
165 | objectClass: person
166 | objectClass: inetOrgPerson
167 | sn: User
168 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
169 | loginShell: /bin/sh
170 | o: 4002
171 | o: 4003
172 | o: 4006
173 | o: 4009
174 |
175 | dn: uid=rubycalm,ou=Person,dc=redmine,dc=org
176 | mail: rubycalm@fakemail.com
177 | uid: rubycalm
178 | cn: Fernando Stemm
179 | preferredLanguage: va
180 | description: User with primary group Smuaddan
181 | uidNumber: 307
182 | gidNumber: 4000
183 | homeDirectory: /home/incomplete
184 | objectClass: posixAccount
185 | objectClass: person
186 | objectClass: inetOrgPerson
187 | givenName: Fernando
188 | sn: Stemm
189 | userPassword: {SSHA}Si9/UcgqKWBlN/+SQb+X1IHZnokzaicm
190 | loginShell: /bin/sh
191 | o: 4001
192 | o: 4016
193 |
194 | dn: cn=Smuaddan,ou=Group,dc=redmine,dc=org
195 | objectClass: groupOfNames
196 | objectClass: posixAccount
197 | homeDirectory: /nonexistent
198 | gidNumber: 100
199 | uidNumber: 100
200 | uid: Smuaddan
201 | cn: Smuaddan
202 | member: uid=edavis,ou=Person,dc=redmine,dc=org
203 |
204 | dn: cn=Rill,ou=Group,dc=redmine,dc=org
205 | objectClass: groupOfNames
206 | objectClass: posixAccount
207 | homeDirectory: /nonexistent
208 | gidNumber: 4000
209 | uidNumber: 4000
210 | uid: Rill
211 | cn: Rill
212 | member: uid=tweetmicro,ou=Person,dc=redmine,dc=org
213 |
214 | dn: cn=Rynever,ou=Group,dc=redmine,dc=org
215 | objectClass: groupOfNames
216 | objectClass: posixAccount
217 | homeDirectory: /nonexistent
218 | gidNumber: 4001
219 | uidNumber: 4001
220 | uid: Rynever
221 | cn: Rynever
222 | member: uid=tweetmicro,ou=Person,dc=redmine,dc=org
223 | member: uid=rubycalm,ou=Person,dc=redmine,dc=org
224 |
225 | dn: cn=Worathest,ou=Group,dc=redmine,dc=org
226 | objectClass: groupOfNames
227 | objectClass: posixAccount
228 | homeDirectory: /nonexistent
229 | gidNumber: 4002
230 | uidNumber: 4002
231 | uid: Worathest
232 | cn: Worathest
233 | member: uid=microunit,ou=Person,dc=redmine,dc=org
234 | member: uid=tweetsave,ou=Person,dc=redmine,dc=org
235 | member: uid=systemhack,ou=Person,dc=redmine,dc=org
236 | member: uid=incomplete,ou=Person,dc=redmine,dc=org
237 | o: 4004
238 |
239 | dn: cn=Säyeldas,ou=Group,dc=redmine,dc=org
240 | objectClass: groupOfNames
241 | objectClass: posixAccount
242 | homeDirectory: /nonexistent
243 | gidNumber: 4003
244 | uidNumber: 4003
245 | uid: Säyeldas
246 | cn: Säyeldas
247 | member: uid=systemhack,ou=Person,dc=redmine,dc=org
248 | member: uid=incomplete,ou=Person,dc=redmine,dc=org
249 | member: uid=edavis,ou=Person,dc=redmine,dc=org
250 | o: 4004
251 | o: 4008
252 |
253 | dn: cn=Briklør,ou=Group,dc=redmine,dc=org
254 | objectClass: groupOfNames
255 | objectClass: posixAccount
256 | homeDirectory: /nonexistent
257 | gidNumber: 4004
258 | uidNumber: 4004
259 | uid: Briklør
260 | cn: Briklør
261 | member: cn=Worathest,ou=Group,dc=redmine,dc=org
262 | member: cn=Säyeldas,ou=Group,dc=redmine,dc=org
263 | o: 4005
264 |
265 | dn: cn=Bluil,ou=Group,dc=redmine,dc=org
266 | objectClass: groupOfNames
267 | objectClass: posixAccount
268 | homeDirectory: /nonexistent
269 | gidNumber: 4005
270 | uidNumber: 4005
271 | uid: Bluil
272 | cn: Bluil
273 | member: cn=Briklør,ou=Group,dc=redmine,dc=org
274 | member: uid=microunit,ou=Person,dc=redmine,dc=org
275 | member: uid=LoadGeek,ou=Person,dc=redmine,dc=org
276 |
277 | dn: cn=Anbely,ou=Group,dc=redmine,dc=org
278 | objectClass: groupOfNames
279 | objectClass: posixAccount
280 | homeDirectory: /nonexistent
281 | gidNumber: 4006
282 | uidNumber: 4006
283 | uid: Anbely
284 | cn: Anbely
285 | member: uid=tweetsave,ou=Person,dc=redmine,dc=org
286 | member: uid=systemhack,ou=Person,dc=redmine,dc=org
287 | member: uid=incomplete,ou=Person,dc=redmine,dc=org
288 | member: uid=tweetmicro,ou=Person,dc=redmine,dc=org
289 |
290 | dn: cn=Issekin,ou=Group,dc=redmine,dc=org
291 | objectClass: groupOfNames
292 | objectClass: posixAccount
293 | homeDirectory: /nonexistent
294 | gidNumber: 4007
295 | uidNumber: 4007
296 | uid: Issekin
297 | cn: Issekin
298 | member: uid=microunit,ou=Person,dc=redmine,dc=org
299 | member: uid=tweetmicro,ou=Person,dc=redmine,dc=org
300 | member: uid=LoadGeek,ou=Person,dc=redmine,dc=org
301 |
302 |
303 | dn: cn=Enden,ou=Group,dc=redmine,dc=org
304 | objectClass: groupOfNames
305 | objectClass: posixAccount
306 | homeDirectory: /nonexistent
307 | gidNumber: 4008
308 | uidNumber: 4008
309 | uid: Enden
310 | cn: Enden
311 | member: cn=Säyeldas,ou=Group,dc=redmine,dc=org
312 | member: uid=microunit,ou=Person,dc=redmine,dc=org
313 | member: uid=tweetmicro,ou=Person,dc=redmine,dc=org
314 |
315 |
316 | dn: cn=Therß,ou=Group,dc=redmine,dc=org
317 | objectClass: groupOfNames
318 | objectClass: posixAccount
319 | homeDirectory: /nonexistent
320 | gidNumber: 4009
321 | uidNumber: 4009
322 | uid: Therß
323 | cn: Therß
324 | description: Therß Team Group
325 | member: cn=Iardum,ou=Group,dc=redmine,dc=org
326 | member: cn=LoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamLoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamdipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquam,ou=Group,dc=redmine,dc=org
327 | member: uid=LoadGeek,ou=Person,dc=redmine,dc=org
328 | member: uid=microunit,ou=Person,dc=redmine,dc=org
329 | member: uid=incomplete,ou=Person,dc=redmine,dc=org
330 | o: 4010
331 | o: 4011
332 |
333 | dn: cn=Iardum,ou=Group,dc=redmine,dc=org
334 | objectClass: groupOfNames
335 | objectClass: posixAccount
336 | homeDirectory: /nonexistent
337 | gidNumber: 4010
338 | uidNumber: 4010
339 | uid: Iardum
340 | cn: Iardum
341 | member: cn=Therß,ou=Group,dc=redmine,dc=org
342 | o: 4009
343 |
344 | dn: cn=LoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamLoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamdipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquam,ou=Group,dc=redmine,dc=org
345 | objectClass: groupOfNames
346 | objectClass: posixAccount
347 | homeDirectory: /nonexistent
348 | gidNumber: 4011
349 | uidNumber: 4011
350 | uid: LoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamLoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamdipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquam
351 | cn: LoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamLoremipsumdolorsitametconsectetueradipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquamdipiscingelitseddiamnonummynibheuismodtinciduntutlaoreetdoloremagnaaliquam
352 | member: cn=Therß,ou=Group,dc=redmine,dc=org
353 |
354 | dn: cn=IT отдел Системные,ou=Group,dc=redmine,dc=org
355 | objectClass: groupOfNames
356 | objectClass: posixAccount
357 | homeDirectory: /nonexistent
358 | gidNumber: 4015
359 | uidNumber: 4015
360 | uid: IT отдел Системные
361 | cn: IT отдел Системные
362 | description: Issue #93
363 | member: uid=LoadGeek,ou=Person,dc=redmine,dc=org
364 | member: uid=microunit,ou=Person,dc=redmine,dc=org
365 |
366 | dn: cn=Příliš žluťoučký kůň úpěl ďábelské ódy,ou=Group,dc=redmine,dc=org
367 | objectClass: groupOfNames
368 | objectClass: posixAccount
369 | homeDirectory: /nonexistent
370 | gidNumber: 4016
371 | uidNumber: 4016
372 | uid: Příliš žluťoučký kůň úpěl ďábelské ódy
373 | cn: Příliš žluťoučký kůň úpěl ďábelské ódy
374 | description: Issue #149
375 | member: uid=rubycalm,ou=Person,dc=redmine,dc=org
376 |
377 | dn: cn=MicroUsers,ou=Group,dc=redmine,dc=org
378 | objectclass: groupOfURLs
379 | cn: MicroUsers
380 | memberURL: ldap:///ou=Person,dc=redmine,dc=org??sub?(uid=*micro*)
381 |
382 | dn: cn=TweetUsers,ou=Group,dc=redmine,dc=org
383 | objectclass: groupOfURLs
384 | cn: TweetUsers
385 | memberURL: ldap:///ou=Person,dc=redmine,dc=org??sub?(uid=*tweet*)
--------------------------------------------------------------------------------
/test/fixtures/member_roles.yml:
--------------------------------------------------------------------------------
1 | ---
2 | member_roles_001:
3 | id: 300
4 | role_id: 1
5 | member_id: 300
6 | member_roles_002:
7 | id: 302
8 | role_id: 1
9 | member_id: 301
10 | inherited_from: 300
11 | member_roles_003:
12 | id: 303
13 | role_id: 2
14 | member_id: 302
15 |
--------------------------------------------------------------------------------
/test/fixtures/members.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ldap_sync_members:
3 | created_on: 2010-07-19 19:35:33 +02:00
4 | project_id: 201
5 | id: 300
6 | user_id: 10
7 | mail_notification: false
8 | ldap_sync_members_1:
9 | id: 301
10 | created_on: 2010-07-19 19:35:33 +02:00
11 | project_id: 201
12 | user_id: 7
13 | mail_notification: true
14 | ldap_sync_members_2:
15 | id: 302
16 | created_on: 2010-07-19 19:35:33 +02:00
17 | project_id: 202
18 | user_id: 7
19 | mail_notification: true
--------------------------------------------------------------------------------
/test/fixtures/projects.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ldap_sync_project:
3 | created_on: 2011-07-19 19:13:59 +02:00
4 | name: LDAP Sync
5 | updated_on: 2013-06-09 10:13:05 +02:00
6 | id: 201
7 | description: LDAP Sync redmine plugin
8 | homepage: https://github.com/thorin/redmine_ldap_sync
9 | is_public: true
10 | identifier: ldap_sync
11 | redmine_project:
12 | created_on: 2011-07-19 19:13:59 +02:01
13 | name: Redmine
14 | updated_on: 2013-06-09 10:13:05 +02:01
15 | id: 202
16 | description: Redmine Issue Tracker
17 | homepage: https://github.com/redmine/redmine
18 | is_public: true
19 | identifier: redmine
20 |
--------------------------------------------------------------------------------
/test/fixtures/roles.yml:
--------------------------------------------------------------------------------
1 | ---
2 | manager:
3 | name: Manager
4 | id: 1
5 | builtin: 0
6 | issues_visibility: all
7 | permissions: |
8 | ---
9 | - :add_project
10 | - :edit_project
11 | - :close_project
12 | - :select_project_modules
13 | - :manage_members
14 | - :manage_versions
15 | - :manage_categories
16 | - :view_issues
17 | - :add_issues
18 | - :edit_issues
19 | - :manage_issue_relations
20 | - :manage_subtasks
21 | - :add_issue_notes
22 | - :move_issues
23 | - :delete_issues
24 | - :view_issue_watchers
25 | - :add_issue_watchers
26 | - :set_issues_private
27 | - :set_notes_private
28 | - :view_private_notes
29 | - :delete_issue_watchers
30 | - :manage_public_queries
31 | - :save_queries
32 | - :view_gantt
33 | - :view_calendar
34 | - :log_time
35 | - :view_time_entries
36 | - :edit_time_entries
37 | - :delete_time_entries
38 | - :manage_news
39 | - :comment_news
40 | - :view_documents
41 | - :add_documents
42 | - :edit_documents
43 | - :delete_documents
44 | - :view_wiki_pages
45 | - :export_wiki_pages
46 | - :view_wiki_edits
47 | - :edit_wiki_pages
48 | - :delete_wiki_pages_attachments
49 | - :protect_wiki_pages
50 | - :delete_wiki_pages
51 | - :rename_wiki_pages
52 | - :add_messages
53 | - :edit_messages
54 | - :delete_messages
55 | - :manage_boards
56 | - :view_files
57 | - :manage_files
58 | - :browse_repository
59 | - :manage_repository
60 | - :view_changesets
61 | - :manage_related_issues
62 | - :manage_project_activities
63 |
64 | position: 1
--------------------------------------------------------------------------------
/test/fixtures/settings.yml:
--------------------------------------------------------------------------------
1 | redmine_ldap_setting:
2 | name: plugin_redmine_ldap_sync
3 | updated_on: <%= Time.now.to_s(:db) %>
4 | value: |
5 | --- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
6 | 1: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
7 | active: true
8 | groups_base_dn: OU=Group,DC=redmine,DC=org
9 | class_user: person
10 | users_search_scope: subtree
11 | class_group: groupOfNames
12 | groupname_pattern: ''
13 | group_search_filter: ''
14 | account_locked_test: flags.include? '[disabled]'
15 | group_membership: on_groups
16 | nested_groups: on_parents
17 | groupname: cn
18 | account_flags: description
19 | member: member
20 | user_memberid: dn
21 | user_groups: o
22 | groupid: gidNumber
23 | parent_group: o
24 | group_parentid: gidNumber
25 | member_group: member
26 | group_memberid: dn
27 | required_group: ''
28 | fixed_group: ldap.users
29 | create_groups: '1'
30 | create_users: '1'
31 | sync_on_login: 'user_fields_and_groups'
32 | dyngroups: ''
33 | admin_group: Itora
34 | group_fields_to_sync:
35 | - '3'
36 | user_fields_to_sync:
37 | - firstname
38 | - lastname
39 | - mail
40 | - '1'
41 | - '2'
42 | user_ldap_attrs: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
43 | '1': preferredLanguage
44 | '2': uidNumber
45 | group_ldap_attrs: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
46 | '3': description
47 | 2: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
48 | active: true
--------------------------------------------------------------------------------
/test/fixtures/users.yml:
--------------------------------------------------------------------------------
1 | ---
2 | admin:
3 | id: 1
4 | created_on: 2006-07-19 19:12:21 +02:00
5 | status: 1
6 | last_login_on: 2006-07-19 22:57:52 +02:00
7 | language: en
8 | # password = admin
9 | salt: 82090c953c4a0000a7db253b0691a6b4
10 | hashed_password: b5b6ff9543bf1387374cdfa27a54c96d236a7150
11 | updated_on: 2006-07-19 22:57:52 +02:00
12 | admin: true
13 | <% if Redmine::VERSION::MAJOR < 3 %>
14 | mail: admin@somenet.foo
15 | <% end %>
16 | lastname: Admin
17 | firstname: redMine
18 | auth_source_id:
19 | mail_notification: all
20 | login: admin
21 | type: User
22 | rhill:
23 | id: 2
24 | created_on: 2006-07-19 19:34:07 +02:00
25 | status: 1
26 | last_login_on:
27 | language: en
28 | # password = foo
29 | salt: 3126f764c3c5ac61cbfc103f25f934cf
30 | hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b
31 | updated_on: 2006-07-19 19:34:07 +02:00
32 | admin: false
33 | <% if Redmine::VERSION::MAJOR < 3 %>
34 | mail: rhill@somenet.foo
35 | <% end %>
36 | lastname: Hill
37 | firstname: Robert
38 | auth_source_id:
39 | mail_notification: all
40 | login: rhill
41 | type: User
42 | users_002:
43 | id: 3
44 | created_on: 2006-07-19 19:32:09 +02:00
45 | status: 1
46 | last_login_on: 2006-07-19 22:42:15 +02:00
47 | language: en
48 | # password = jsmith
49 | salt: 67eb4732624d5a7753dcea7ce0bb7d7d
50 | hashed_password: bfbe06043353a677d0215b26a5800d128d5413bc
51 | updated_on: 2006-07-19 22:42:15 +02:00
52 | admin: false
53 | <% if Redmine::VERSION::MAJOR < 3 %>
54 | mail: jsmith@somenet.foo
55 | <% end %>
56 | lastname: Smith
57 | firstname: John
58 | auth_source_id:
59 | mail_notification: all
60 | login: jsmith
61 | type: User
62 | users_003:
63 | id: 4
64 | created_on: 2006-07-19 19:33:19 +02:00
65 | status: 1
66 | last_login_on:
67 | language: en
68 | # password = foo
69 | salt: 7599f9963ec07b5a3b55b354407120c0
70 | hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
71 | updated_on: 2006-07-19 19:33:19 +02:00
72 | admin: false
73 | <% if Redmine::VERSION::MAJOR < 3 %>
74 | mail: dlopper@somenet.foo
75 | <% end %>
76 | lastname: Lopper
77 | firstname: Dave
78 | auth_source_id:
79 | mail_notification: all
80 | login: dlopper
81 | type: User
82 | users_005:
83 | id: 5
84 | created_on: 2006-07-19 19:33:19 +02:00
85 | # Locked
86 | status: 3
87 | last_login_on:
88 | language: en
89 | hashed_password: 1
90 | updated_on: 2006-07-19 19:33:19 +02:00
91 | admin: false
92 | <% if Redmine::VERSION::MAJOR < 3 %>
93 | mail: dlopper2@somenet.foo
94 | <% end %>
95 | lastname: Lopper2
96 | firstname: Dave2
97 | auth_source_id:
98 | mail_notification: all
99 | login: dlopper2
100 | type: User
101 | users_006:
102 | id: 6
103 | created_on: 2006-07-19 19:33:19 +02:00
104 | status: 0
105 | last_login_on:
106 | language: ''
107 | hashed_password: 1
108 | updated_on: 2006-07-19 19:33:19 +02:00
109 | admin: false
110 | <% if Redmine::VERSION::MAJOR < 3 %>
111 | mail: ''
112 | <% end %>
113 | lastname: Anonymous
114 | firstname: ''
115 | auth_source_id:
116 | mail_notification: only_my_events
117 | login: ''
118 | type: AnonymousUser
119 | someone:
120 | id: 7
121 | created_on: 2006-07-19 19:33:19 +02:00
122 | status: 1
123 | last_login_on:
124 | language: ''
125 | hashed_password: 1
126 | updated_on: 2006-07-19 19:33:19 +02:00
127 | admin: false
128 | <% if Redmine::VERSION::MAJOR < 3 %>
129 | mail: someone@foo.bar
130 | <% end %>
131 | lastname: One
132 | firstname: Some
133 | auth_source_id: 1
134 | mail_notification: only_my_events
135 | login: someone
136 | type: User
137 | loadgeek:
138 | id: 8
139 | created_on: 2006-07-19 19:33:19 +02:00
140 | status: 1
141 | last_login_on:
142 | language: 'it'
143 | # password = foo
144 | salt: 7599f9963ec07b5a3b55b354407120c0
145 | hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
146 | updated_on: 2006-07-19 19:33:19 +02:00
147 | admin: false
148 | <% if Redmine::VERSION::MAJOR < 3 %>
149 | mail: miscuser8@foo.bar
150 | <% end %>
151 | lastname: Misc
152 | firstname: User
153 | auth_source_id: 1
154 | mail_notification: only_my_events
155 | login: loadgeek
156 | type: User
157 | users_009:
158 | id: 9
159 | created_on: 2006-07-19 19:33:19 +02:00
160 | status: 1
161 | last_login_on:
162 | language: 'it'
163 | hashed_password: 1
164 | updated_on: 2006-07-19 19:33:19 +02:00
165 | admin: false
166 | <% if Redmine::VERSION::MAJOR < 3 %>
167 | mail: miscuser9@foo.bar
168 | <% end %>
169 | lastname: Misc
170 | firstname: User
171 | auth_source_id:
172 | mail_notification: only_my_events
173 | login: miscuser9
174 | type: User
175 | users_010:
176 | id: 12
177 | created_on: 2006-07-19 19:33:19 +02:00
178 | status: 1
179 | last_login_on:
180 | language: 'it'
181 | hashed_password: 1
182 | updated_on: 2006-07-19 19:33:19 +02:00
183 | admin: false
184 | <% if Redmine::VERSION::MAJOR < 3 %>
185 | mail: rubycalm@fakemail.com
186 | <% end %>
187 | lastname: Stemm
188 | firstname: Fernando
189 | auth_source_id: 1
190 | mail_notification: only_my_events
191 | login: rubycalm
192 | type: User
193 | therß:
194 | id: 10
195 | lastname: therß
196 | type: Group
197 | rynever:
198 | id: 11
199 | lastname: rynever
200 | type: Group
201 | issue_149:
202 | id: 13
203 | lastname: Příliš žluťoučký kůň úpěl ďábelské ódy
204 | type: Group
--------------------------------------------------------------------------------
/test/functional/ldap_settings_controller_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../../test_helper', __FILE__)
19 |
20 | class LdapSettingsControllerTest < ActionController::TestCase
21 | fixtures :auth_sources, :users, :settings, :custom_fields
22 |
23 | setup do
24 | Setting.clear_cache
25 | @auth_source = auth_sources(:auth_sources_001)
26 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@auth_source.id)
27 | @request.session[:user_id] = 1
28 | end
29 |
30 | def test_should_get_index
31 | get :index
32 | assert_response :success
33 | assert_not_nil assigns(:ldap_settings)
34 |
35 | assert_select "table tr", 3
36 | assert_select "a", :text => 'LDAP test server', :count => 1
37 | assert_select "td", :text => '127.0.0.1', :count => 1
38 | assert_select "td", :text => '127.0.0.1', :count => 1
39 | end
40 |
41 | def test_should_get_base_settings_js
42 | get :base_settings, :format => 'js'
43 | assert_response :success
44 | assert_template 'ldap_settings/base_settings'
45 | end
46 |
47 | def test_should_redirect_to_get_edit_on_get_show
48 | get :show, params: { id: 1 }
49 | assert_redirected_to edit_ldap_setting_path(1)
50 | end
51 |
52 | def test_should_get_edit
53 | get :edit, params: { id: @auth_source.id }
54 | assert_response :success
55 | end
56 |
57 | def test_should_get_404
58 | get :edit, params: { id: 999 }
59 | assert_response :not_found
60 | end
61 |
62 | def test_should_disable_ldap_setting
63 | # Given that
64 | assert @ldap_setting.active?, "LdapSetting must be enabled"
65 | assert_equal 'member', @ldap_setting.member_group
66 |
67 | # When we do
68 | get :disable, params: { id: @ldap_setting.id }
69 | assert_redirected_to ldap_settings_path
70 | assert_match /success/, flash[:notice]
71 |
72 | # We should have
73 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@ldap_setting.id)
74 | assert_equal 'member', ldap_setting.member_group, 'LdapSetting is not the same'
75 | assert !ldap_setting.active?, "LdapSetting must be disabled"
76 | end
77 |
78 | def test_should_disable_an_invalid_ldap_setting
79 | # Given that
80 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(2)
81 | assert ldap_setting.active?
82 |
83 | # When we do
84 | get :disable, params: { id: ldap_setting.id }
85 | assert_redirected_to ldap_settings_path
86 | assert_match /success/, flash[:notice]
87 |
88 | # We should have
89 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(2)
90 | assert_nil ldap_setting.member_group, 'LdapSetting is not the same'
91 | assert !ldap_setting.active?, "LdapSetting must be disabled"
92 | end
93 |
94 | def test_should_enable_ldap_setting
95 | # Given that
96 | @ldap_setting.active = false; @ldap_setting.save
97 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@ldap_setting.id)
98 | assert !ldap_setting.active?, "LdapSetting must be disabled"
99 | assert_equal 'member', ldap_setting.member_group
100 |
101 | # When we do
102 | get :enable, params: { id: ldap_setting.id }
103 | assert_redirected_to ldap_settings_path
104 | assert_match /success/, flash[:notice]
105 |
106 | # We should have
107 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(ldap_setting.id)
108 | assert_equal 'member', ldap_setting.member_group, 'LdapSetting is not the same'
109 | assert ldap_setting.active?, "LdapSetting must be enabled"
110 | end
111 |
112 | def test_should_not_enable_ldap_setting_with_errors
113 | # Given that
114 | @ldap_setting.active = false; @ldap_setting.save
115 | @ldap_setting.send(:attribute=, :dyngroups, 'invalid')
116 | @ldap_setting.send(:settings=, @ldap_setting.send(:attributes))
117 |
118 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@ldap_setting.id)
119 | assert !@ldap_setting.active?, 'LdapSetting must be disabled'
120 | assert_equal 'member', @ldap_setting.member_group
121 |
122 | # When we do
123 | get :enable, params: { id: @ldap_setting.id }
124 | assert_redirected_to ldap_settings_path
125 | assert_match /invalid settings/, flash[:error]
126 |
127 | # We should have
128 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@ldap_setting.id)
129 | assert_equal 'member', ldap_setting.member_group, 'LdapSetting is not the same'
130 | assert !ldap_setting.active?, "LdapSetting must be disabled"
131 | end
132 |
133 | def test_should_fail_with_error
134 | put :update, params: {
135 | id: @ldap_setting.id,
136 | ldap_setting: {
137 | auth_source_ldap_id: @auth_source_id,
138 | active: true,
139 | groupname: 'cn',
140 | groups_base_dn: 'groups_base_dn',
141 | class_group: 'group',
142 | class_user: nil, # Missing required field
143 | group_membership: 'on_members',
144 | groupid: 'groupid',
145 | nested_groups: '',
146 | user_groups: 'memberof',
147 | sync_on_login: '',
148 | dyngroups: ''
149 | }
150 | }
151 | assert assigns(:ldap_setting).errors.added?(:class_user, :blank), 'An error must be reported for :class_user'
152 | assert_response :success
153 | end
154 |
155 | def test_should_update_ldap_setting
156 | put :update, params: {
157 | id: @ldap_setting.id,
158 | ldap_setting: {
159 | auth_source_ldap_id: @auth_source_id,
160 | active: true,
161 | account_disabled_test: '',
162 | account_flags: '',
163 | attributes_to_sync: '',
164 | class_group: 'group',
165 | class_user: 'user',
166 | create_groups: '',
167 | create_users: '',
168 | fixed_group: '',
169 | group_memberid: '',
170 | group_membership: 'on_members',
171 | group_parentid: '',
172 | group_search_filter: '',
173 | groupid: 'groupid',
174 | groupname: 'cn',
175 | groupname_pattern: '',
176 | groups_base_dn: 'groups_base_dn',
177 | member: '',
178 | member_group: '',
179 | nested_groups: '',
180 | parent_group: '',
181 | required_group: '',
182 | user_fields_to_sync: [],
183 | group_fields_to_sync: [],
184 | user_ldap_attrs: {},
185 | group_ldap_attrs: {},
186 | user_groups: 'memberof',
187 | user_memberid: '',
188 | sync_on_login: '',
189 | dyngroups: ''
190 | }
191 | }
192 | assert_redirected_to ldap_settings_path
193 | assert assigns(:ldap_setting).valid?
194 | assert_match /success/, flash[:notice]
195 | end
196 |
197 | def test_should_test
198 | put :test, params: {
199 | id: @ldap_setting.id,
200 | format: 'text',
201 | ldap_setting: @ldap_setting.send(:attributes),
202 | ldap_test: { test_users: 'example1', test_groups: 'Therß' }
203 | }
204 |
205 | assert_response :success
206 | assert_equal 'text/plain', response.content_type
207 |
208 | assert_match /User \"example1\":/, response.body
209 | assert_match /Group \"Therß\":/, response.body
210 | assert_match /Users enabled:/, response.body
211 | assert_match /Users locked by flag:/, response.body
212 | assert_match /Admin users:/, response.body
213 | assert_match /Groups:/, response.body
214 | assert_match /LDAP attributes on a user:/, response.body
215 | assert_match /LDAP attributes on a group:/, response.body
216 |
217 | assert_no_match /ldap_test\.rb/, response.body, 'Should not throw an error'
218 | end
219 |
220 | def test_should_validate_on_test
221 | @ldap_setting.dyngroups = 'invalid'
222 |
223 | put :test, params: {
224 | id: @ldap_setting.id,
225 | format: 'text',
226 | ldap_setting: @ldap_setting.send(:attributes),
227 | ldap_test: { :test_users => 'example1', :test_groups => 'Therß' }
228 | }
229 |
230 | assert_response :success
231 | assert_equal 'text/plain', response.content_type
232 |
233 | assert_match /Validation errors .* Dynamic groups/m, response.body
234 |
235 | assert_no_match /ldap_test\.rb/, response.body, 'Should not throw an error'
236 | end
237 | end
--------------------------------------------------------------------------------
/test/integration/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tainewoo/redmine_ldap_sync/95219d5f0ab007db9975a6d0f8e32e78c1f36728/test/integration/.gitkeep
--------------------------------------------------------------------------------
/test/performance/auth_source_ldap_performance_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../../test_helper', __FILE__)
19 | require 'rails/performance_test_help'
20 |
21 | class AuthSourceLdapPerformanceTest < ActionDispatch::PerformanceTest
22 | fixtures :auth_sources, :users, :groups_users, :settings, :custom_fields
23 | fixtures :email_addresses if Redmine::VERSION::MAJOR >= 3
24 |
25 | setup do
26 | clear_ldap_cache!
27 | Setting.clear_cache
28 | @auth_source = auth_sources(:auth_sources_001)
29 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@auth_source.id)
30 |
31 | AuthSourceLdap.activate_users = false
32 | AuthSourceLdap.running_rake = false
33 | end
34 |
35 | def test_sync_groups
36 | @auth_source.sync_groups
37 | end
38 |
39 | def test_sync_users
40 | @auth_source.sync_users
41 | end
42 | end
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 |
19 | if RUBY_VERSION >= '2.0.0'
20 | require 'simplecov'
21 |
22 | SimpleCov.start do
23 | add_group 'Controllers', 'app/controllers'
24 | add_group 'Models', 'app/models'
25 | add_group 'Helpers', 'app/helpers'
26 | add_group 'Libraries', 'lib'
27 | add_filter '/test/'
28 | add_filter 'init.rb'
29 | root File.expand_path(File.dirname(__FILE__) + '/../')
30 | end
31 | end
32 |
33 | require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
34 |
35 | Rails.backtrace_cleaner.remove_silencers!
36 |
37 | class ActiveSupport::TestCase
38 | self.fixture_path = File.expand_path(File.dirname(__FILE__) + '/fixtures')
39 |
40 | def clear_ldap_cache!
41 | FileUtils.rm_rf Rails.root.join("tmp/ldap_cache")
42 | end
43 | end
44 |
45 | class ActionDispatch::IntegrationTest
46 | self.fixture_path = File.expand_path(File.dirname(__FILE__) + '/fixtures')
47 | end
48 |
49 | module ActionController::TestCase::Behavior
50 | def process_patched(action, method, *args)
51 | options = args.extract_options!
52 | if options.present?
53 | params = options.delete(:params)
54 | options = options.merge(params) if params.present?
55 | args << options
56 | end
57 | process_unpatched(action, method, *args)
58 | end
59 |
60 | if Rails::VERSION::MAJOR < 5
61 | alias_method :process_unpatched, :process
62 | alias_method :process, :process_patched
63 | end
64 | end
--------------------------------------------------------------------------------
/test/ui/base.rb:
--------------------------------------------------------------------------------
1 | # Redmine - project management software
2 | # Copyright (C) 2006-2017 Jean-Philippe Lang
3 | #
4 | # This program is free software; you can redistribute it and/or
5 | # modify it under the terms of the GNU General Public License
6 | # as published by the Free Software Foundation; either version 2
7 | # of the License, or (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program; if not, write to the Free Software
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 |
18 | require File.expand_path('../../test_helper', __FILE__)
19 | require 'capybara/rails'
20 |
21 | Capybara.default_driver = :selenium
22 | Capybara.register_driver :selenium do |app|
23 | # Use the following driver definition to test locally using Chrome
24 | # (also requires chromedriver to be in PATH)
25 | # Capybara::Selenium::Driver.new(app, :browser => :chrome)
26 | # Add :switches => %w[--lang=en] to force default browser locale to English
27 | # Default for Selenium remote driver is to connect to local host on port 4444
28 | # This can be change using :url => 'http://localhost:9195' if necessary
29 | # PhantomJS 1.8 now directly supports Webdriver Wire API,
30 | # simply run it with `phantomjs --webdriver 4444`
31 | # Add :desired_capabilities => Selenium::WebDriver::Remote::Capabilities.internet_explorer)
32 | # to run on Selenium Grid Hub with IE
33 | Capybara::Selenium::Driver.new(app, browser: :remote, desired_capabilities: Selenium::WebDriver::Remote::Capabilities.phantomjs)
34 | end
35 |
36 | Capybara.register_driver :chrome_headless do |app|
37 | capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
38 | chromeOptions: { args: %w(headless disable-popup-blocking no-sandbox disable-gpu window-size=1024,900 lang=en) }
39 | )
40 | Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities )
41 | end
42 |
43 | # default: 2
44 | Capybara.default_wait_time = 2
45 |
46 | module Redmine
47 | module UiTest
48 | # Base class for UI tests
49 | class Base < ActionDispatch::IntegrationTest
50 | include Capybara::DSL
51 |
52 | # Stop ActiveRecord from wrapping tests in transactions
53 | # Transactional fixtures do not work with Selenium tests, because Capybara
54 | # uses a separate server thread, which the transactions would be hidden
55 | if defined? self.use_transactional_tests
56 | self.use_transactional_tests = false
57 | else
58 | self.use_transactional_fixtures = false
59 | end
60 |
61 | # Should not depend on locale since Redmine displays login page
62 | # using default browser locale which depend on system locale for "real" browsers drivers
63 | def log_user(login, password)
64 | visit '/my/page'
65 | assert_equal '/login', current_path
66 | within('#login-form form') do
67 | fill_in 'username', :with => login
68 | fill_in 'password', :with => password
69 | find('input[name=login]').click
70 | end
71 | assert_equal '/my/page', current_path
72 | end
73 |
74 | setup do
75 | # Set the page width higher than 900 to get the full layout with sidebar
76 | page.driver.browser.manage.window.resize_to(1024, 900)
77 | end
78 |
79 | teardown do
80 | Capybara.reset_sessions! # Forget the (simulated) browser state
81 | Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
82 | end
83 | end
84 | end
85 | end
--------------------------------------------------------------------------------
/test/ui/ldap_setting_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../base', __FILE__)
19 |
20 | if RUBY_VERSION >= '2.0.0'
21 | require 'simplecov'
22 | SimpleCov.command_name 'UI Tests'
23 | end
24 |
25 | class Redmine::UiTest::LdapSettingTest < Redmine::UiTest::Base
26 | fixtures :auth_sources, :users, :settings, :custom_fields
27 | fixtures :email_addresses if Redmine::VERSION::MAJOR >= 3
28 |
29 | setup do
30 | log_user('admin', 'admin')
31 | visit '/admin/ldap_sync'
32 | within 'tr#ldap-config-1' do
33 | click_link 'LDAP test server'
34 | end
35 | assert_equal '/admin/ldap_sync/1/edit', current_path
36 | end
37 |
38 | def test_ldap_setting_test
39 | click_link 'Synchronization actions'
40 | select 'Enabled', :from => 'Dynamic groups'
41 |
42 | click_link 'Test'
43 | within 'div#tab-content-Test' do
44 | fill_in 'Users', :with => 'tweetmicro,systemhack,microunit,missing_user'
45 | fill_in 'Groups', :with => 'Iardum,Therß,MissingGroup'
46 | click_link 'Execute'
47 | end
48 |
49 |
50 | assert_selector '#test-result', :text => /User "tweetmicro":\s+Email = tweetmicro@fakemail.com/
51 | assert_selector '#test-result', :text => /User "microunit":\s+Email = microunit@fakemail.com/
52 | assert_selector '#test-result', :text => /User "missing_user": Not found/
53 |
54 | assert_selector '#test-result', :text => /Group "Iardum": No fields/
55 | assert_selector '#test-result', :text => /Group "Therß": Description = Therß Team Group/
56 | assert_selector '#test-result', :text => /Group "MissingGroup": Not found/
57 |
58 | assert_selector '#test-result', :text => /Users enabled: a total of \d+\s+\[[^\]]*"microunit"[^\]]*\]/
59 | assert_selector '#test-result', :text => /Users locked by flag: a total of \d+\s+\[[^\]]*"tweetmicro"[^\]]*\]/
60 | assert_selector '#test-result', :text => /Groups: a total of \d+\s+\[[^\]]*\]/
61 | assert_selector '#test-result', :text => /Dynamic groups: a total of \d+\s+.*MicroUsers:\s+\[[^\]]*microunit[^\]]*\]/
62 | end
63 |
64 | def test_base_settings
65 | select 'Samba LDAP', :from => 'Base settings'
66 |
67 | assert_equal 'sambaSamAccount', find_field('Users objectclass').value
68 | assert_equal 'member', find_field('Member users (group)').value
69 |
70 | select 'Active Directory (with nested groups)', :from => 'Base settings'
71 |
72 | assert_equal 'on_parents', find_field('Nested groups').value
73 | assert_equal 'flags.to_i & 2 != 0', find_field('Account disabled test').value
74 | assert_equal 'samaccountname', find_field('Group name (group)').value
75 | assert_equal 'useraccountcontrol', find_field('Account flags (user)').value
76 | assert_equal 'distinguishedname', find_field('Groupid (group)').value
77 | assert_equal 'member', find_field('Member groups (group)').value
78 | assert_equal 'distinguishedname', find_field('Memberid (group)').value
79 | end
80 |
81 | def test_group_membership
82 | select 'On the user class', :from => 'Group membership'
83 |
84 | assert !find_field('Member users (group)').visible? rescue Capybara::ElementNotFound
85 | assert !find_field('Memberid (user)').visible? rescue Capybara::ElementNotFound
86 | assert find_field('Groups (user)').visible?
87 | assert find_field('Groupid (group)').visible?
88 |
89 | select 'On the group class', :from => 'Group membership'
90 |
91 | assert !find_field('Groups (user)').visible? rescue Capybara::ElementNotFound
92 | assert !find_field('Groupid (group)').visible? rescue Capybara::ElementNotFound
93 | assert find_field('Member users (group)').visible?
94 | assert find_field('Memberid (user)').visible?
95 | end
96 |
97 | def test_nested_groups
98 | select 'Disabled', :from => 'Nested groups'
99 |
100 | assert !find_field('Member groups (group)').visible? rescue Capybara::ElementNotFound
101 | assert !find_field('Memberid (group)').visible? rescue Capybara::ElementNotFound
102 | assert !find_field('Parent groups (group)').visible? rescue Capybara::ElementNotFound
103 | assert !find_field('Parentid (group)').visible? rescue Capybara::ElementNotFound
104 |
105 | select 'Membership on the parent class', :from => 'Nested groups'
106 |
107 | assert !find_field('Parent groups (group)').visible? rescue Capybara::ElementNotFound
108 | assert !find_field('Parentid (group)').visible? rescue Capybara::ElementNotFound
109 | assert find_field('Member groups (group)').visible?
110 | assert find_field('Memberid (group)').visible?
111 |
112 | select 'Membership on the member class', :from => 'Nested groups'
113 |
114 | assert !find_field('Member groups (group)').visible? rescue Capybara::ElementNotFound
115 | assert !find_field('Memberid (group)').visible? rescue Capybara::ElementNotFound
116 | assert find_field('Parent groups (group)').visible?
117 | assert find_field('Parentid (group)').visible?
118 | end
119 | end
--------------------------------------------------------------------------------
/test/ui/login_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../base', __FILE__)
19 |
20 | if RUBY_VERSION >= '2.0.0'
21 | require 'simplecov'
22 | SimpleCov.command_name 'UI Tests'
23 | end
24 |
25 | class Redmine::UiTest::LoginTest < Redmine::UiTest::Base
26 | fixtures :auth_sources, :users, :settings, :custom_fields, :roles, :projects, :members, :member_roles
27 | fixtures :email_addresses if Redmine::VERSION::MAJOR >= 3
28 |
29 | setup do
30 | visit '/login'
31 | end
32 |
33 | def test_login_with_existing_user
34 | within '#login-form' do
35 | fill_in 'Login', :with => 'loadgeek'
36 | fill_in 'Password', :with => 'password'
37 | click_on 'Login'
38 | end
39 | assert_equal my_page_path, current_path
40 | end
41 |
42 | def test_login_with_new_user
43 | within '#login-form' do
44 | fill_in 'Login', :with => 'systemhack'
45 | fill_in 'Password', :with => 'password'
46 | click_on 'Login'
47 | end
48 | assert_equal my_page_path, current_path
49 | end
50 |
51 | def test_login_with_incomplete_user
52 | within '#login-form' do
53 | fill_in 'Login', :with => 'incomplete'
54 | fill_in 'Password', :with => 'password'
55 | click_on 'Login'
56 | end
57 |
58 | assert_selector 'h2', :text => /Register/
59 |
60 | fill_in 'First name', :with => 'Incomplete'
61 | fill_in 'Last name', :with => 'User'
62 | fill_in 'Email', :with => 'incomplete@fakemail.com'
63 | select 'Nederlands', :from => 'Language'
64 |
65 | click_on 'Submit'
66 |
67 | assert_equal my_account_path, current_path
68 |
69 | assert User.find_by_login('incomplete')
70 | end
71 |
72 | end
--------------------------------------------------------------------------------
/test/unit/helpers/ldap_settings_helper_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../../../test_helper', __FILE__)
19 |
20 | class LdapSettingsHelperTest < ActionView::TestCase
21 | include LdapSettingsHelper
22 | include Redmine::I18n
23 |
24 | fixtures :auth_sources, :settings, :custom_fields
25 |
26 | setup do
27 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(auth_sources(:auth_sources_001).id)
28 | end
29 |
30 | def test_groups_fields
31 | assert_equal ['Description'], group_fields.map(&:name)
32 | assert_equal ['no description'], group_fields.map(&:default_value)
33 | assert_equal ['description'], group_fields.map(&:ldap_attribute)
34 |
35 | @ldap_setting.group_ldap_attrs = {}
36 | assert_equal [''], group_fields.map(&:ldap_attribute)
37 | end
38 |
39 | def test_user_fields
40 | assert_equal ['Email', 'First name', 'Last name', 'Preferred Language', 'Uid Number'], user_fields.map(&:name).sort
41 | assert_equal ['', '', '', '0', 'en'], user_fields.map(&:default_value).sort
42 | assert_equal %w(givenName mail preferredLanguage sn uidNumber), user_fields.map(&:ldap_attribute).sort
43 |
44 | @ldap_setting.user_ldap_attrs = {}
45 | assert_equal ['', '', 'givenName', 'mail', 'sn'], user_fields.map(&:ldap_attribute).sort
46 | end
47 |
48 | def test_users_fields_list
49 | fields = [
50 | ["3", "Test Group"]
51 | ]
52 |
53 | assert_equal " Description = Test Group\n", group_fields_list(fields)
54 | end
55 |
56 | def test_groups_fields_list
57 | fields = [
58 | ["1", "de"],
59 | ["2", "67123"]
60 | ]
61 | group_changes = {:added => ["group1", "group2"]}
62 |
63 | assert_equal " Preferred Language = de\n" +
64 | " Uid Number = 67123\n" +
65 | " Groups = [\"group1\", \"group2\"]\n",
66 | user_fields_list(fields, group_changes)
67 | end
68 |
69 | def test_options_for_base_settings
70 | assert_not_equal 0, options_for_base_settings.size
71 | end
72 |
73 | def test_user_field_name
74 | assert_equal 'Preferred Language', user_field_name("1")
75 | end
76 |
77 | def test_group_field_name
78 | assert_equal 'Description', group_field_name("3")
79 | end
80 |
81 | def test_change_status_link
82 | @ldap_setting.active = true
83 | assert_match /Disable/, change_status_link(@ldap_setting)
84 |
85 | @ldap_setting.active = false
86 | assert_match /Enable/, change_status_link(@ldap_setting)
87 | end
88 | end
--------------------------------------------------------------------------------
/test/unit/ldap_test_test.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | # Copyright (C) 2011-2013 The Redmine LDAP Sync Authors
3 | #
4 | # This file is part of Redmine LDAP Sync.
5 | #
6 | # Redmine LDAP Sync is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # Redmine LDAP Sync is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with Redmine LDAP Sync. If not, see .
18 | require File.expand_path('../../test_helper', __FILE__)
19 |
20 | class LdapTestTest < ActiveSupport::TestCase
21 | include ActiveModel::Lint::Tests
22 |
23 | fixtures :auth_sources, :users, :groups_users, :settings, :custom_fields
24 | fixtures :email_addresses if Redmine::VERSION::MAJOR >= 3
25 |
26 | setup do
27 | Setting.clear_cache
28 | @auth_source = auth_sources(:auth_sources_001)
29 | @ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@auth_source.id)
30 | @ldap_test = @model = LdapTest.new(@ldap_setting)
31 | end
32 |
33 | def test_run_with_disabled_settings
34 | @ldap_setting.active = false;
35 | @ldap_test = LdapTest.new(@ldap_setting)
36 |
37 | assert @ldap_test.setting.active?
38 |
39 | @ldap_test.run_with_users_and_groups([], [])
40 | assert_not_equal 0, @ldap_test.non_dynamic_groups.size
41 |
42 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
43 | end
44 |
45 | def test_run_with_one_or_more_users
46 | @ldap_test.run_with_users_and_groups(['loadgeek'], [])
47 | assert_equal 1, @ldap_test.users_at_ldap.size
48 | assert_include 'loadgeek', @ldap_test.users_at_ldap.keys
49 |
50 | @ldap_test = LdapTest.new(@ldap_setting)
51 | @ldap_test.run_with_users_and_groups(['MissingUser', 'tweetmicro'], [])
52 | assert_equal 2, @ldap_test.users_at_ldap.size
53 | assert_include 'MissingUser', @ldap_test.users_at_ldap.keys
54 | assert_equal :not_found, @ldap_test.users_at_ldap['MissingUser']
55 | assert_include 'tweetmicro', @ldap_test.users_at_ldap.keys
56 | assert_not_equal 0, @ldap_test.users_at_ldap['tweetmicro'][:groups][:added].size
57 | assert_equal 5, @ldap_test.users_at_ldap['tweetmicro'][:fields].size, "#{@ldap_test.users_at_ldap['tweetmicro'][:fields]}"
58 | assert_equal 0, @ldap_test.groups_at_ldap.size
59 |
60 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
61 | end
62 |
63 | def test_run_with_one_or_more_groups
64 | @ldap_test.run_with_users_and_groups([], ['Rynever'])
65 | assert_equal 1, @ldap_test.groups_at_ldap.size
66 | assert_include 'Rynever', @ldap_test.groups_at_ldap.keys
67 |
68 | @ldap_test = LdapTest.new(@ldap_setting)
69 | @ldap_test.run_with_users_and_groups([], ['MissingGroup', 'Therß'])
70 | assert_equal 2, @ldap_test.groups_at_ldap.size
71 | assert_include 'MissingGroup', @ldap_test.groups_at_ldap.keys
72 | assert_equal :not_found, @ldap_test.groups_at_ldap['MissingGroup']
73 | assert_include 'Therß', @ldap_test.groups_at_ldap.keys
74 | assert_equal 1, @ldap_test.groups_at_ldap['Therß'][:fields].size
75 | assert_equal 0, @ldap_test.users_at_ldap.size
76 |
77 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
78 | end
79 |
80 | def test_run_with_users_and_groups
81 | @ldap_test.run_with_users_and_groups(['tweetsave', 'microunit'], ['Briklør', 'Rynever', 'Worathest'])
82 | assert_equal 2, @ldap_test.users_at_ldap.size
83 | assert_equal 3, @ldap_test.groups_at_ldap.size
84 |
85 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
86 | end
87 |
88 | def test_run_with_no_group_fields_and_user_fields
89 | @ldap_setting.group_fields_to_sync = []
90 | @ldap_setting.user_fields_to_sync = []
91 |
92 | @ldap_test.run_with_users_and_groups(['tweetsave'], ['Briklør', 'Therß'])
93 | assert_equal 0, @ldap_test.groups_at_ldap['Therß'][:fields].size
94 |
95 | # uid is required and should be set with the default value
96 | assert_equal 4, @ldap_test.users_at_ldap['tweetsave'][:fields].size, "#{@ldap_test.users_at_ldap['tweetsave'][:fields]}"
97 |
98 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
99 | end
100 |
101 | def test_run_with_deleted_users
102 | @ldap_test.run_with_users_and_groups(['tweetsave'], ['Briklør'])
103 | assert_not_equal 0, @ldap_test.user_changes[:locked].size
104 | assert_not_equal 0, @ldap_test.user_changes[:deleted].size
105 |
106 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
107 | end
108 |
109 | def test_run_with_admin_group
110 | @ldap_setting.admin_group = 'Worathest'
111 |
112 | @ldap_test.run_with_users_and_groups(['tweetsave'], ['Therß'])
113 | assert_not_equal 0, @ldap_test.admin_users.size
114 |
115 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
116 | end
117 |
118 | def test_run_with_required_group
119 | @ldap_setting.required_group = 'Bluil'
120 |
121 | @ldap_test.run_with_users_and_groups(['tweetsave'], ['Therß'])
122 | assert_not_equal 0, @ldap_test.users_locked_by_group.size
123 |
124 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
125 | end
126 |
127 | def test_run_with_dynamic_groups
128 | @ldap_setting.dyngroups = 'enabled'
129 |
130 | @ldap_test.run_with_users_and_groups(['microunit'], ['Enden'])
131 | assert_include 'MicroUsers', @ldap_test.users_at_ldap['microunit'][:groups][:added]
132 | assert_not_equal 0, @ldap_test.dynamic_groups.size
133 |
134 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
135 | end
136 |
137 | def test_run_with_minimal_settings
138 | @ldap_setting.dyngroups = ''
139 | @ldap_setting.nested_groups = ''
140 | @ldap_setting.sync_on_login = ''
141 | @ldap_setting.account_flags = ''
142 | @ldap_setting.group_fields_to_sync = []
143 | @ldap_setting.user_fields_to_sync = []
144 | @ldap_setting.admin_group = ''
145 | @ldap_setting.required_group = ''
146 |
147 | @ldap_test.run_with_users_and_groups([], [])
148 | assert_not_equal 0, @ldap_test.messages.size
149 | assert_not_equal 0, @ldap_test.user_changes[:enabled].size
150 | assert_equal 0, @ldap_test.user_changes[:locked].size
151 | assert_equal 1, @ldap_test.user_changes[:deleted].size
152 | assert_equal 0, @ldap_test.users_at_ldap.size
153 | assert_equal 0, @ldap_test.groups_at_ldap.size
154 | assert_not_equal 0, @ldap_test.non_dynamic_groups.size
155 | assert_equal 0, @ldap_test.dynamic_groups.size
156 | assert_equal 0, @ldap_test.users_locked_by_group.size
157 | assert_equal 0, @ldap_test.admin_users.size
158 |
159 | assert_no_match /ldap_test\.rb/, @ldap_test.messages, "Should not throw an error"
160 | end
161 |
162 | def test_run_without_groups_base_dn_should_fail_on_open_ldap
163 | @ldap_setting.groups_base_dn = ''
164 |
165 | @ldap_test.run_with_users_and_groups([], [])
166 | assert_not_equal 0, @ldap_test.messages.size
167 | assert_equal 0, @ldap_test.non_dynamic_groups.size
168 | assert_equal 0, @ldap_test.dynamic_groups.size
169 |
170 | assert_match /ldap_test\.rb/, @ldap_test.messages, "Should throw an error"
171 | end
172 |
173 | def test_run_with_dynamic_bind_should_not_fail
174 | @auth_source.account = 'uid=$login,ou=Person,dc=redmine,dc=org'
175 | assert @auth_source.save, @auth_source.errors.full_messages.join(', ')
176 | ldap_setting = LdapSetting.find_by_auth_source_ldap_id(@auth_source.id)
177 | ldap_test = LdapTest.new(ldap_setting)
178 |
179 | ldap_test.bind_user = 'admin'
180 | ldap_test.bind_password = 'password'
181 | ldap_test.run_with_users_and_groups([], [])
182 | assert_not_equal 15, ldap_test.messages.size
183 | assert_equal 15, ldap_test.non_dynamic_groups.size
184 |
185 | assert_no_match /ldap_test\.rb/, ldap_test.messages, "Should no throw an error"
186 | end
187 |
188 | def test_log_messages
189 | @ldap_test.run_with_users_and_groups([], [])
190 | assert_match /active, .* locked .* deleted/, @ldap_test.messages
191 | end
192 |
193 | def test_error_case
194 | @ldap_setting.account_locked_test = "flags.include? [disabled]'"
195 |
196 | @ldap_test.run_with_users_and_groups([], [])
197 |
198 | assert_match /ldap_test\.rb/, @ldap_test.messages, "Should throw an error"
199 | end
200 |
201 | def test_should_filter_the_list_of_groups_with_the_groupname_pattern
202 | @ldap_setting.groupname_pattern = "s$"
203 | @ldap_setting.dyngroups = 'enabled'
204 |
205 | @ldap_test.run_with_users_and_groups([], [])
206 |
207 | assert_equal 3, @ldap_test.non_dynamic_groups.size + @ldap_test.dynamic_groups.size
208 | assert_include 'Säyeldas', @ldap_test.non_dynamic_groups
209 | end
210 |
211 | end
--------------------------------------------------------------------------------