setting up gitlab LDAP-authentication without special gitlab user - ldap

I want to set up Gitlab with our company's LDAP as a demo. But unfortunately I have to put in an admin password in gitlab.yml to make gitlab access the LDAP service. The problem actually is the administration, as they don't want to setup another account just for Gitlab. Is there any way to circumvent this without filling in my own password? Is there a way to make Gitlab establish the LDAP connection with only the provided user credentials?
Any ideas beside logging in as anonymous?
Already posted here.

I haven't tried it yet, but from the things I've build so far authenticating against LDAP and the informations from the config-file this user-account seems only to be needed when your LDAP does not support anonymous binding and searching.
So I would leave the two entries bind_dn and password commented out and try whether it works or not.
UPDATE
I've implemented LDAP-Autehntication in Gitlab and it's fairly easy.
In the gitlab.yml-file there is a section called ldap.
There you have to provide the informations to connect to your LDAP. It seems that all fields have to be given, there seems to be no fallback default! If you want to use anonymous binding for retrieval of the users DN supply an empty string for bind_dn and password. Commenting them out seems not to work! At least I got a 501 Error message.
More information can be found at https://github.com/patthoyts/gitlabhq/wiki/Setting-up-ldap-auth and (more outdated but still helpful) https://github.com/intridea/omniauth-ldap

I have patched gitlab to work this way and documented the process in https://foivos.zakkak.net/tutorials/gitlab_ldap_auth_without_querying_account/
I shamelessly copy the instructions here for self-completeness.
Note: This tutorial was last tested with gitlab 8.2 installed from source.
This tutorial aims to describe how to modify a Gitlab installation to
use the users credentials to authenticate with the LDAP server. By
default Gitlab relies on anonymous binding or a special querying user
to ask the LDAP server about the existence of a user before
authenticating her with her own credentials. For security reasons,
however, many administrators disable anonymous binding and forbid the
creation of special querying LDAP users.
In this tutorial we assume that we have a gitlab setup at
gitlab.example.com and an LDAP server running on ldap.example.com, and
users have a DN of the following form:
CN=username,OU=Users,OU=division,OU=department,DC=example,DC=com.
Patching
To make Gitlab work in such cases we need to partly modify its
authentication mechanism regarding LDAP.
First, we replace the omniauth-ldap module with this derivation. To
achieve this we apply the following patch to gitlab/Gemfile:
diff --git a/Gemfile b/Gemfile
index 1171eeb..f25bc60 100644
--- a/Gemfile
+++ b/Gemfile
## -44,4 +44,5 ## gem 'gitlab-grack', '~> 2.0.2', require: 'grack'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
# see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master
-gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
+#gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
+gem 'gitlab_omniauth-ldap', :git => 'https://github.com/zakkak/omniauth-ldap.git', require: 'net-ldap', require: "omniauth-ldap"
Now, we need to perform the following actions:
sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment
sudo -u git -H bundle install --deployment --without development test mysql aws
These commands will fetch the modified omniauth-ldap module in
gitlab/vendor/bundle/ruby/2.x.x/bundler/gems. Now that the module is
fetched, we need to modify it to use the DN our LDAP server expects. We
achieve this by patching lib/omniauth/strategies/ldap.rb in
gitlab/vendor/bundle/ruby/2.x.x/bundler/gems/omniauth-ldap with:
diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb
index 9ea62b4..da5e648 100644
--- a/lib/omniauth/strategies/ldap.rb
+++ b/lib/omniauth/strategies/ldap.rb
## -39,7 +39,7 ## module OmniAuth
return fail!(:missing_credentials) if missing_credentials?
# The HACK! FIXME: do it in a more generic/configurable way
- #options[:bind_dn] = "CN=#{request['username']},OU=Test,DC=my,DC=example,DC=com"
+ #options[:bind_dn] = "CN=#{request['username']},OU=Users,OU=division,OU=department,DC=example,DC=com"
#options[:password] = request['password']
#adaptor = OmniAuth::LDAP::Adaptor.new #options
With this module, gitlab uses the user's credentials to bind to the LDAP
server and query it, as well as, to authenticate the user herself.
This however will only work as long as the users do not use ssh-keys to
authenticate with Gitlab. When authenticating through an ssh-key, by
default Gitlab queries the LDAP server to find out whether the
corresponding user is (still) a valid user or not. At this point, we
cannot use the user credentials to query the LDAP server, since the user
did not provide them to us. As a result we disable this mechanism,
essentially allowing users with registered ssh-keys but removed from the
LDAP server to still use our Gitlab setup. To prevent such users from
being able to still use your Gitlab setup, you will have to manually
delete their ssh-keys from any accounts in your setup.
To disable this mechanism we patch gitlab/lib/gitlab/ldap/access.rb
with:
diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb
index 16ff03c..9ebaeb6 100644
--- a/lib/gitlab/ldap/access.rb
+++ b/lib/gitlab/ldap/access.rb
## -14,15 +14,16 ## module Gitlab
end
def self.allowed?(user)
- self.open(user) do |access|
- if access.allowed?
- user.last_credential_check_at = Time.now
- user.save
- true
- else
- false
- end
- end
+ true
+ # self.open(user) do |access|
+ # if access.allowed?
+ # user.last_credential_check_at = Time.now
+ # user.save
+ # true
+ # else
+ # false
+ # end
+ # end
end
def initialize(user, adapter=nil)
## -32,20 +33,21 ## module Gitlab
end
def allowed?
- if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
- return true unless ldap_config.active_directory
+ true
+ # if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
+ # return true unless ldap_config.active_directory
- # Block user in GitLab if he/she was blocked in AD
- if Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter)
- user.block unless user.blocked?
- false
- else
- user.activate if user.blocked? && !ldap_config.block_auto_created_users
- true
- end
- else
- false
- end
+ # # Block user in GitLab if he/she was blocked in AD
+ # if Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter)
+ # user.block unless user.blocked?
+ # false
+ # else
+ # user.activate if user.blocked? && !ldap_config.block_auto_created_users
+ # true
+ # end
+ # else
+ # false
+ # end
rescue
false
end
Configuration
In gitlab.yml use something like the following (modify to your needs):
#
# 2. Auth settings
# ==========================
## LDAP settings
# You can inspect a sample of the LDAP users with login access by running:
# bundle exec rake gitlab:ldap:check RAILS_ENV=production
ldap:
enabled: true
servers:
##########################################################################
#
# Since GitLab 7.4, LDAP servers get ID's (below the ID is 'main'). GitLab
# Enterprise Edition now supports connecting to multiple LDAP servers.
#
# If you are updating from the old (pre-7.4) syntax, you MUST give your
# old server the ID 'main'.
#
##########################################################################
main: # 'main' is the GitLab 'provider ID' of this LDAP server
## label
#
# A human-friendly name for your LDAP server. It is OK to change the label later,
# for instance if you find out it is too large to fit on the web page.
#
# Example: 'Paris' or 'Acme, Ltd.'
label: 'LDAP_EXAMPLE_COM'
host: ldap.example.com
port: 636
uid: 'sAMAccountName'
method: 'ssl' # "tls" or "ssl" or "plain"
bind_dn: ''
password: ''
# This setting specifies if LDAP server is Active Directory LDAP server.
# For non AD servers it skips the AD specific queries.
# If your LDAP server is not AD, set this to false.
active_directory: true
# If allow_username_or_email_login is enabled, GitLab will ignore everything
# after the first '#' in the LDAP username submitted by the user on login.
#
# Example:
# - the user enters 'jane.doe#example.com' and 'p#ssw0rd' as LDAP credentials;
# - GitLab queries the LDAP server with 'jane.doe' and 'p#ssw0rd'.
#
# If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to
# disable this setting, because the userPrincipalName contains an '#'.
allow_username_or_email_login: false
# To maintain tight control over the number of active users on your GitLab installation,
# enable this setting to keep new users blocked until they have been cleared by the admin
# (default: false).
block_auto_created_users: false
# Base where we can search for users
#
# Ex. ou=People,dc=gitlab,dc=example
#
base: 'OU=Users,OU=division,OU=department,DC=example,DC=com'
# Filter LDAP users
#
# Format: RFC 4515 http://tools.ietf.org/search/rfc4515
# Ex. (employeeType=developer)
#
# Note: GitLab does not support omniauth-ldap's custom filter syntax.
#
user_filter: '(&(objectclass=user)(objectclass=person))'

GitLab uses omniauth to manage multiple login sources (including LDAP).
So if you can somehow extend omniauth in order to manage the LDAP connection differently, you could fetch the password from a different source.
That would allow you to avoid keeping said password in the ldap section of the gitlab.yml config file.

Related

Use both JDBC and SAML2 IdPs in Apereo CAS 5.3.16

I am trying to setup Apereo CAS 5.3.16 to use a SAML2 IdP and a JDBC (PostreSQL) database IdP. We need CAS to try to authenticate against the SAML IdP first and then, if that fails, against the JDBC IdP.
Unfortunately, over the past weekend, the documentation for v 5.3.16 was removed from the Apereo website, so am now working from the markdown source documents in the codebase. I have consulted the manual extensively and read these posts - https://fawnoos.com/2017/03/22/cas51-delauthn-tutorial/ and CAS delegate authentication to Azure SAML - and can't get the app to do what we need.
CAS creates its SAML metadata, keys and obtains metadata from the SAML IdP (Okta).
The logs show the following entry:
DEBUG [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] -
<Resolved and finalized authentication handlers to carry out this authentication transaction are
[[org.apereo.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler#301ed37a,
org.apereo.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler#b48d4df,
org.apereo.cas.support.pac4j.authentication.handler.support.ClientAuthenticationHandler#6d3bc620]
Which looks right to me, except that I want the pac4j handler executed before the JDBC one. I don't know what HttpBasedServiceCredentialsAuthenticationHandler is but it is part of the CAS core in its source code, so I think it is supposed to be there.
The authentication request is going to the JDBC handler first and if that fails, is not falling through to the SAML handler. The authentication request is immediately rejected.
Here is (the relevant part of) our properties file (standalone.properties).
Can some kind soul please tell me what am I missing or doing wrong?
# --- UTS Library --- #
server.port=8080
server.ssl.enabled=false
server.use-forward-headers=true
server.session.cookie.http-only=true
server.session.tracking-modes=cookie
cas.server.name=${CAS_SERVER_NAME:}
cas.server.prefix=${cas.server.name}/cas
cas.host.name=
# Default theme name
cas.theme.defaultThemeName=ourtheme
# CAS session persistence
cas.ticket.tgt.rememberMe.enabled=true
cas.ticket.tgt.rememberMe.timeToKillInSeconds=604800
##
# CAS endpoint security
#
...
# logging settings
# Stacktrace settings, possible values: NEVER|ALWAYS|ON_TRACE_PARAM
server.error.include-stacktrace=${CAS_INCLUDE_STACKTRACE:ALWAYS}
##
# Database settings
#
database.driverClass=org.postgresql.Driver
database.url=jdbc:postgresql://${CAS_DB_HOST:127.0.0.1}:${CAS_DB_PORT:5432}/${CAS_DB_NAME:our_db}
database.dialect=org.hibernate.dialect.PostgreSQL82Dialect
database.user=${CAS_DB_USER:}
database.password=${CAS_DB_PASS:}
database.pool.initialSize=2
database.pool.minSize=2
database.pool.maxSize=12
database.pool.acquireIncrement=2
# kills persistent connections that have been idle for > 60 seconds
database.pool.maxIdleTime=60
# keys
cas.tgc.crypto.encryption.key=${CAS_TGC_ENCRYPTION_KEY:}
cas.tgc.crypto.signing.key=${CAS_TGC_SIGNING_KEY:}
cas.webflow.crypto.encryption.key=${CAS_WEBFLOW_ENCRYPTION_KEY:}
cas.webflow.crypto.signing.key=${CAS_WEBFLOW_SIGNING_KEY:}
##
# CAS Authentication Policy
#
cas.authn.policy.any.enabled=true
cas.authn.policy.any.tryAll=false
# Attribute release policy
cas.authn.attributeRepository.defaultAttributesToRelease=username,givenname,familyname,mail,[others]
# Disable default authenticators
cas.authn.accept.users=
#cas.sso.proxyAuthnEnabled=false
##
# Okta SAML IdP delegation integration
cas.authn.pac4j.saml[0].keystorePassword=our_passwd
cas.authn.pac4j.saml[0].privateKeyPassword=our_key
cas.authn.pac4j.saml[0].serviceProviderEntityId=urn:cas:saml:our.url
cas.authn.pac4j.saml[0].serviceProviderMetadataPath=/etc/cas/config/sp-metadata.xml
cas.authn.pac4j.saml[0].keystorePath=/etc/cas/config/samlKeystore.jks
cas.authn.pac4j.saml[0].identityProviderMetadataPath=https://our.okta.vanity.domain/app/our_okta_sp_id/sso/saml/metadata
##
# PostgreSQL authentication
cas.authn.jdbc.query[0].name=ourdb
cas.authn.jdbc.query[0].order=1
cas.authn.jdbc.query[0].sql=SELECT ...
cas.authn.jdbc.query[0].fieldPassword=password
cas.authn.jdbc.query[0].fieldDisabled=disabled
cas.authn.jdbc.query[0].url=${database.url}
cas.authn.jdbc.query[0].dialect=${database.dialect}
cas.authn.jdbc.query[0].user=${database.user}
cas.authn.jdbc.query[0].password=${database.password}
cas.authn.jdbc.query[0].driverClass=${database.driverClass}
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=...
##
# Attributes
#
cas.authn.attributeRepository.jdbc[0].sql=SELECT ...
cas.authn.attributeRepository.jdbc[0].username=username,univid
...
cas.authn.attributeRepository.jdbc[0].singleRow=true
cas.authn.attributeRepository.jdbc[0].order=0
cas.authn.attributeRepository.jdbc[0].queryType=OR
cas.authn.attributeRepository.jdbc[0].url=${database.url}
cas.authn.attributeRepository.jdbc[0].dialect=${database.dialect}
cas.authn.attributeRepository.jdbc[0].user=${database.user}
cas.authn.attributeRepository.jdbc[0].password=${database.password}
cas.authn.attributeRepository.jdbc[0].driverClass=${database.driverClass}
# Specify whether CAS should redirect to the specified service parameter on /logout requests
cas.logout.followServiceRedirects=true
# Specify how CAS should respond and validate incoming HTTP requests
# X-Frame-Options - default setting is DENY
cas.httpWebRequest.header.xframe=true
cas.httpWebRequest.header.xframeOptions=ALLOWALL
##
# CAS PersonDirectory Principal Resolution
#
...
##
# CAS Authentication Throttling
#
...
##
# CAS Health Monitoring
#
...
##
# SAML
#
# Indicates the SAML response issuer
#cas.samlCore.issuer=sso.lib.uts.edu.au
#
# Indicates the skew allowance which controls the issue instant of the SAML response
#cas.samlCore.skewAllowance=60
#
# Indicates whether SAML ticket id generation should be saml2-compliant.
#cas.samlCore.ticketidSaml2=false
##
# CORS handling
#
...
##
# Memcached
#
...
# Monitoring
cas.monitor.memcached.daemon=false
##
# Service ticket behaviour
#
cas.ticket.st.timeToKillInSeconds=60
##
# Service registry
cas.serviceRegistry.json.location=file:/etc/cas/services
# -- / -- #
Background:
Our organisation plans to retire CAS for Okta in a phased transition. The first phase is to use Okta as an IdP for CAS, replacing a bespoke Azure AD/MSAL module. We are not keen to upgrade to CAS 6 given our CAS will be retired. The org's CAS expert has left and it's been given to me, as I'm a Java programmer and CAS is written in Java. So at least I can debug it. I am, most certainly, not a CAS expert and I find the manual vague, incomplete and lacking in concrete examples.

LDAP Authentication - OpenShift - OKD

I have deployed a new OKD cluster (3.11) and as Identity Provider I have selected LDAPPasswordIdentityProvider
The configuration goes like this:
openshift_master_identity_providers=[{'name': 'idm', 'challenge': 'true', 'login': 'true', 'kind': 'LDAPPasswordIdentityProvider', 'attributes': {'id': ['dn'], 'email': ['mail'], 'name': ['cn'], 'preferredUsername': ['uid']}, 'bindDN': 'uid=service,cn=users,cn=accounts,dc=myorg,dc=com', 'bindPassword': 'reallysecurepasswordhere', 'insecure': 'false', 'url': 'ldaps://idm.myorg.com:636/dc=myorg,dc=com?uid??(memberof=cn=openshift,cn=accounts,dc=myorg,dc=com)'}]
I have tried two dozens of possibilities with this URL.
On the logs I always get:
I0528 15:23:38.491659 1 ldap.go:122] searching for (&(objectClass=*)(uid=user1))
E0528 15:23:38.494172 1 login.go:174] Error authenticating "user1" with provider "idm": multiple entries found matching "user1"
I don't get it why is the filter showing as (&(objectClass=*)(uid=... appears as the filter isn't being parsed correctly, despite the URL being as above.
I also checked the master-config.yaml and it is correct as my ini file.
If I do ldapsearch I get the expected results:
$ ldapsearch -x -D "uid=service,cn=users,cn=accounts,dc=myorg,dc=com" -W -H ldaps://idm.myorg.com -s sub -b "cn=accounts,dc=myorg,dc=com" '(&(uid=user1)(memberof=cn=openshift,cn=groups,cn=accounts,dc=myorg,dc=com))' uid
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <cn=accounts,dc=myorg,dc=com> with scope subtree
# filter: (&(uid=user1)(memberof=cn=openshift,cn=groups,cn=accounts,dc=myorg,dc=com))
# requesting: uid
#
# user1, users, accounts, myorg.com
dn: uid=user1,cn=users,cn=accounts,dc=myorg,dc=com
uid: user1
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
The LDAP Server is FreeIPA.
Help please!
Ok, I found the solution to the problem.
I assumed ... incorrectly ... that running the playbook openshift-ansible/playbook/openshift-master/config.yml would restart the openshift-master API.
It doesn't.
I noticed this when, instead of editing my ini inventory where I have this set and running config, I started editing directly on /etc/origin/master/master-config.yaml and using master-restart api to restart the API.
Several URL alterations (many incorrect actually) had never been ran. Config uploaded them, but the master api doesn't restart, so new config doesn't go in place, and I kept hitting the wall.

rails 4 devise ldap_authenticatable current_user not set

I'm fairly new to Rails 4 and am experimenting with Devise and ldap_authenticatable and I see something that I'm not sure is right. When I authenticate to my Active Directory Devise works fine and stores the user in the MySQL database as expected. However, I seem to lose the user params and can't tell which user just authenticated. user_signed_in? returns false but if I hit the login link I get the message "already signed in" current_user is nil and set_user fails because params(:id) is nil. Seems like something is broken here but I'm not sure what the norm is as far as Devise setting or keeping user params alive.
Any ideas or helpful information?
User Model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :ldap_authenticatable, :trackable, :validatable
before_save :get_ldap_attrs
def get_ldap_attrs
self.firstname = Devise::LDAP::Adapter.get_ldap_param(self.email, 'givenName')
self.lastname = Devise::LDAP::Adapter.get_ldap_param(self.email, 'sn')
self.login = Devise::LDAP::Adapter.get_ldap_param(self.email, 'sAMAccountName')
self.email = Devise::LDAP::Adapter.get_ldap_param(self.email,'mail').first
self.studentid = Devise::LDAP::Adapter.get_ldap_param(self.email, 'title')
end
end
----
ldap.yaml
## Authorizations
# Uncomment out the merging for each environment that you'd like to include.
# You can also just copy and paste the tree (do not include the "authorizations") to each
# environment if you need something different per enviornment.
authorizations: &AUTHORIZATIONS
allow_unauthenticated_bind: false
group_base: ou=groups,dc=kentshill,dc=org
## Requires config.ldap_check_group_membership in devise.rb be true
# Can have multiple values, must match all to be authorized
required_groups:
# If only a group name is given, membership will be checked against "uniqueMember"
#- ########################
#- #######################
# If an array is given, the first element will be the attribute to check against, the second the group name
#- ["moreMembers", "cn=users,ou=groups,dc=test,dc=com"]
## Requires config.ldap_check_attributes in devise.rb to be true
## Can have multiple attributes and values, must match all to be authorized
require_attribute:
objectClass: inetOrgPerson
authorizationRole: postsAdmin
## Environment
development:
host: address
port: 636
attribute: mail
base: DN
admin_user: fqn user with privs
admin_password: password
ssl: true
# <<: *AUTHORIZATIONS
test:
host: localhost
port: 3389
attribute: cn
base: ou=people,dc=test,dc=com
admin_user: cn=admin,dc=test,dc=com
admin_password: admin_password
ssl: simple_tls
# <<: *AUTHORIZATIONS
production:
host: localhost
port: 636
attribute: cn
base: ou=people,dc=test,dc=com
admin_user: cn=admin,dc=test,dc=com
admin_password: admin_password
ssl: start_tls
# <<: *AUTHORIZATIONS
----------------
Devise initializer
# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
# ==> LDAP Configuration
config.ldap_logger = true
config.ldap_create_user = true
config.ldap_update_password = true
#config.ldap_config = "#{Rails.root}/config/ldap.yml"
config.ldap_check_group_membership = false
#config.ldap_check_group_membership_without_admin = false
config.ldap_check_attributes = false
config.ldap_use_admin_to_bind = true
config.ldap_ad_group_check = false
# The secret key used by Devise. Devise uses this key to generate
# random tokens. Changing this key will render invalid all existing
# confirmation, reset password and unlock tokens in the database.
# Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
# by default. You can change it below and use your own secret key.
# config.secret_key = 'ead157a98cc1402f93c717c537225a807971f381bdb51063b22d9979b39e0db385493e0d392999152597ce52baf327d97ffc9a59371ea3258cd8f5fc6d158b75'
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'please-change-me-at-config-initializers-devise#example.com'
# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default) and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require 'devise/orm/active_record'
config.ldap_auth_username_builder = Proc.new() { |attribute, login, ldap| login }
# config.warden do |manager|
# manager.default_strategies(:scope => :user).unshift :ldap_authenticatable
# end
# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating a user. The default is
# just :email. You can configure it to use [:username, :subdomain], so for
# authenticating a user, both parameters are required. Remember that those
# parameters are used only when authenticating and not when retrieving from
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
config.authentication_keys = [:email]
# Configure parameters from the request object used for authentication. Each entry
# given should be a request method and it will automatically be passed to the
# find_for_authentication method and considered in your model lookup. For instance,
# if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
# The same considerations mentioned for authentication_keys also apply to request_keys.
# config.request_keys = []
# Configure which authentication keys should be case-insensitive.
# These keys will be downcased upon creating or modifying a user and when used
# to authenticate or find a user. Default is :email.
config.case_insensitive_keys = [:email]
"config/initializers/devise.rb" 280L, 13721C

Only show repos in gitweb that user has access to via Gitolite

I have gitolite setup and working with SSH key based auth. I can control access to repos via the gitolite-admin.git repo and the conf file. All of this works great over SSH but I would like to use GitWeb as a quick way to view the repos.
GitWeb is working great now but shows all repositories via the web interface. So my goal here is to:
Authenticate users in apache2 via PAM, I already have the Ubuntu server authenticating aginst AD and all the users are available. This should not be an issue.
Use the user name logged in with the check gitolite permissions
Display apropriate REPOS in the web interface.
Does anyone have a starting point for this? The Apache part shouldn't be difficult, and I'll set it to auth all fo the /gitweb/ url. I dont know how to pass that username around and authorize it against gitolite. Any ideas?
Thanks,
Nathan
Yes, it is possible, but you need to complete the gitweb config scripts in order to call gitolite.
The key is in the gitweb_config.perl: if that file exists, gitweb will include and call it.
See my gitweb/gitweb_config.perl file:
our $home_link_str = "ITSVC projects";
our $site_name = "ITSVC Gitweb";
use lib (".");
require "gitweb.conf.pl";
In gitweb/gitweb.conf.pl (custom script), I define the official callback function called by gitweb: export_auth_hook: that function will call gitolite.
use Gitolite::Common;
use Gitolite::Conf::Load;
#$ENV{GL_USER} = $cgi->remote_user || "gitweb";
$export_auth_hook = sub {
my $repo = shift;
my $user = $ENV{GL_USER};
# gitweb passes us the full repo path; so we strip the beginning
# and the end, to get the repo name as it is specified in gitolite conf
return unless $repo =~ s/^\Q$projectroot\E\/?(.+)\.git$/$1/;
# check for (at least) "R" permission
my $ret = &access( $repo, $user, 'R', 'any' );
my $res = $ret !~ /DENIED/;
return ($ret !~ /DENIED/);
};
From the comments:
GL_USER is set because of the line:
$ENV{GL_USER} = $cgi->remote_user || "gitweb";
$cgi->remote_user will pick the environment REMOTE_USER set by any Apache Auth module which has completed the authentication (like in this Apache configuration file).
You can print it with a 'die' line.
"Could not find Gitolite/Rc.pm" means the INC variable used by perl doesn't contain $ENV{GL_LIBDIR}; (set to ~/gitolite/lib or <any_place_where_gitolite_was_installed>/lib).
That is why there is a line in the same gitweb/gitweb.conf.pl file which adds that to INC:
unshift #INC, $ENV{GL_LIBDIR};
use lib $ENV{GL_LIBDIR};
use Gitolite::Rc;
Edit from Nat45928: in my case I needed to insert my home path into all the '#H#' entries. That solved all of my issues right away.

Gitlab 6.7 fails to create account when using LDAP Login

I'm currently trying to setup Gitlab 6.7 as a fresh install as well as upgrading from version 6.6. While doing so I ran into the following error:
When logging in with an LDAP account, which is not in Gitlab yet, the login fails with the message containing the words
Could not authorize you from LDAP because: "Validation failed username only letters, digits & '_' '-' '.' allowed. Letter should be first".
Hence the upgraded version still works with existing accounts.
After having a look at the code in GitHub I suspect that the root cause is that the generation of the Gitlab username changed.
To me it looks like before it was the first part of the email address (everything up to #) and now it seems to be the uid, but in my case the uid is an email address containing an # character.
As I do not have any other value in LDAP with uniquely identifies a user, I am required to use the uid/mail.
Anyone has a hint how to proceed here?
Thanks
LDAP:
objectClass person
givenName Jane
sn Doe
cn Jane Doe
uid jane.doe#example.com
mail jane.doe#example.com
Gitlab.yml 6.6:
ldap:
enabled: true
host: 'ldaphost.example.com'
base: 'o=example.com'
port: 636
uid: 'uid'
method: 'ssl' # "tls" or "ssl" or "plain"
#bind_dn: ''
#password: '_the_password_of_the_bind_user'
# If allow_username_or_email_login is enabled, GitLab will ignore everything
# after the first '#' in the LDAP username submitted by the user on login.
#
# Example:
# - the user enters 'jane.doe#example.com' and 'p#ssw0rd' as LDAP credentials;
# - GitLab queries the LDAP server with 'jane.doe' and 'p#ssw0rd'.
#
# If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to
# disable this setting, because the userPrincipalName contains an '#'.
allow_username_or_email_login: false
Gitlab.yml 6.7:
ldap:
enabled: true
host: 'ldaphost.example.com'
port: 636
uid: 'uid'
method: 'ssl' # "tls" or "ssl" or "plain"
#bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
#password: '_the_password_of_the_bind_user'
# If allow_username_or_email_login is enabled, GitLab will ignore everything
# after the first '#' in the LDAP username submitted by the user on login.
#
# Example:
# - the user enters 'jane.doe#example.com' and 'p#ssw0rd' as LDAP credentials;
# - GitLab queries the LDAP server with 'jane.doe' and 'p#ssw0rd'.
#
# If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to
# disable this setting, because the userPrincipalName contains an '#'.
allow_username_or_email_login: false
# Base where we can search for users
#
# Ex. ou=People,dc=gitlab,dc=example
#
base: 'o=example.com'
# Filter LDAP users
#
# Format: RFC 4515
# Ex. (employeeType=developer)
#
user_filter: ''