diff --git a/app/models/user.rb b/app/models/user.rb index 51cce45acae2..d7cd19c38e7b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -129,7 +129,7 @@ def self.blocked_condition(blocked) validates :login, uniqueness: { if: Proc.new { |user| user.login.present? }, case_sensitive: false } validates :mail, uniqueness: { allow_blank: true, case_sensitive: false } # Login must contain letters, numbers, underscores only - validates :login, format: { with: /\A[a-z0-9_\-@.+ ]*\z/i } + validates :login, format: { with: /\A[\p{L}0-9_\-@.+ ]*\z/i } validates :login, length: { maximum: 256 } validates :firstname, :lastname, length: { maximum: 256 } diff --git a/docs/development/ldap/README.md b/docs/development/ldap/README.md new file mode 100644 index 000000000000..2f3a9dfb3fcd --- /dev/null +++ b/docs/development/ldap/README.md @@ -0,0 +1,31 @@ +--- +sidebar_navigation: + title: LDAP development setup + priority: 920 +--- + +# Set up a development LDAP server + +**Note:** This guide is targeted only at development with OpenProject. For the LDAP configuration guide, please see this [here](../../system-admin-guide/authentication/ldap-authentication/) + + +OpenProject comes with a built-in LDAP server for development purposes. This server uses [ladle gem](https://github.com/NUBIC/ladle) +to run an underlying apacheDS server. + +This guide will show you how to set it up in your development instance. + +## Prerequisites + +- A local java/JRE environment installed (openjdk, java installed via homebrew, etc.) +- A development setup of OpenProject (or any other configurable installation) + +## Running the LDAP server + +You only need to run this rake task to start the server: + +```bash +./bin/rails ldap_groups:development:ldap_server +``` + +It will both output the different users and groups, as well as connection details. Starting this task will ensure +an LDAP connection is created or updated to make sure you can use it right away. diff --git a/modules/ldap_groups/lib/tasks/ldap_groups.rake b/modules/ldap_groups/lib/tasks/ldap_groups.rake index ff24331508a8..e23f4deb538c 100644 --- a/modules/ldap_groups/lib/tasks/ldap_groups.rake +++ b/modules/ldap_groups/lib/tasks/ldap_groups.rake @@ -128,6 +128,7 @@ namespace :ldap_groups do uid=aa729,ou=people,dc=example,dc=com (Password: smada) uid=bb459,ou=people,dc=example,dc=com (Password: niwdlab) uid=cc414,ou=people,dc=example,dc=com (Password: retneprac) + uid=bölle,ou=people,dc=example,dc=com (Password: bólle) -------------------------------------------------------- diff --git a/spec/fixtures/ldap/users.ldif b/spec/fixtures/ldap/users.ldif index e369e7cd773f..1daaeed36865 100644 --- a/spec/fixtures/ldap/users.ldif +++ b/spec/fixtures/ldap/users.ldif @@ -182,3 +182,17 @@ mail: xara@example.org uid: xx396 userpassword:: e1NIQX1ZYzJFbjJSL3NiZGpsRU9pdGtMbGt3WTRqQVk9 +dn: uid=bölle,ou=people,dc=example,dc=com +objectClass: inetOrgPerson +objectClass: simulatedMicrosoftSecurityPrincipal +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: Bölle Büllendorf +sn: Büllendorf +givenName: Bölle +mail: boelle@example.org +uid: bölle +samAccountName: bölle +# Password is "bólle" +userpassword:: e1NIQX1rNDBGWHRYQ3RFL3l2cENhblRpQmZ2cE1ON1k9Cg== diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9bbcb97d49f5..121b8bdce4fc 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -143,6 +143,18 @@ end end + context 'with other letter char classes' do + let(:login) { "célîneüberölig" } + + it 'is valid' do + expect(user).to be_valid + end + + it 'may be stored in the database' do + expect(user.save).to be_truthy + end + end + context "with tabs" do let(:login) { 'ab\tc' } @@ -172,7 +184,7 @@ end context "with combination thereof" do - let(:login) { "the+boss-is@the_house." } + let(:login) { "the+boss-is-über@the_house." } it "is valid" do expect(user).to be_valid diff --git a/spec/requests/auth/ldap_sso_spec.rb b/spec/requests/auth/ldap_sso_spec.rb index 5d2858a013a6..d1367a9fc0c9 100644 --- a/spec/requests/auth/ldap_sso_spec.rb +++ b/spec/requests/auth/ldap_sso_spec.rb @@ -58,6 +58,23 @@ expect(subject).to redirect_to "/?first_time_user=true" end + context 'with a user that has umlauts in their name' do + let(:username) { 'bölle' } + let(:password) { 'bólle' } + + it 'creates a user with umlauts on the fly' do + expect(User.find_by(login: 'bölle')).to be_nil + + expect { subject }.to change(User.not_builtin.active, :count).by(1) + + user = User.find_by(login: 'bölle') + expect(user).to be_present + expect(user).to be_active + expect(session[:user_id]).to eq user.id + expect(subject).to redirect_to '/?first_time_user=true' + end + end + context "when not all attributes present" do let(:attr_mail) { nil }