Make LDAP auth fonctionnal

This commit is contained in:
Guillaume GILL 2017-11-08 00:35:38 +01:00
parent 9f57379f16
commit ac6f66b083
3 changed files with 78 additions and 17 deletions

View File

@ -1,49 +1,107 @@
# coding=utf-8
from __future__ import absolute_import
from octoprint.users import FilebasedUserManager
from octoprint.users import FilebasedUserManager, User
from octoprint.settings import settings
import ldap
import uuid
class LDAPUserManager(FilebasedUserManager):
#Login phase :
# - findUser called, if it return a user
# - chaeckPassword called, if it return True
# - login_user called with User returned by previous findUser
def checkPassword(self, username, password):
ldap_server = settings().get(["accessControl", "ldap_uri"])
ldap_search_base = settings().get(["accessControl", "ldap_search_base"])
ldap_verifypeer = settings().get(["accessControl", "ldap_tls_reqcert"])
self._logger.debug(ldap_server)
self._logger.debug(ldap_search_base)
if ldap_server is None or ldap_search_base is None:
self._logger.debug("LDAP conf error")
self._logger.error("LDAP conf error")
return False
dn = "uid=" + username + ",ou=users," + ldap_search_base
#@TODO Voir pour sortir le groupe "smile" de là...
group = "ou=smile,ou=users"
dn = "uid=" + username + "," + group + "," + ldap_search_base
try:
connection = ldap.initialize(ldap_server)
if (ldap_server.startswith('ldaps://')):
verifypeer = ldap.OPT_X_TLS_NEVER
if ldap_verifypeer == 'demand':
verifypeer = ldap.OPT_X_TLS_DEMAND
connection.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, verifypeer)
try:
connection.start_tls_s()
connection.bind_s(dn, password)
except:
pass
user = self.findUser(username)
connection.bind_s(dn, password)
connection.unbind_s()
user = FilebasedUserManager.findUser(self, username)
if not user:
self.addUser(username, uuid.uuid4(), True)
self.addUser(username, str(uuid.uuid4()), True)
return True
except ldap.INVALID_CREDENTIALS:
self._logger.debug("LDAP : Your username or password is incorrect.")
self._logger.error("LDAP : Your username or password is incorrect.")
return FilebasedUserManager.checkPassword(self, username, password)
except ldap.LDAPError, e:
if type(e.message) == dict:
for (k, v) in e.message.iteritems():
self._logger.debug("%s: %sn" % (k, v))
self._logger.error("%s: %sn" % (k, v))
else:
self._logger.debug(e.message)
self._logger.error(e.message)
return False
def changeUserPassword(self, username, password):
def changeUserPassword(self, username, password):
pass
def findUser(self, userid=None, session=None):
local_user = FilebasedUserManager.findUser(self, userid, session)
#If user not exists in local database, search it on LDAP
if userid and not local_user:
ldap_server = settings().get(["accessControl", "ldap_uri"])
ldap_search_base = settings().get(["accessControl", "ldap_search_base"])
ldap_verifypeer = settings().get(["accessControl", "ldap_tls_reqcert"])
try:
connection = ldap.initialize(ldap_server)
if (ldap_server.startswith('ldaps://')):
verifypeer = ldap.OPT_X_TLS_NEVER
if ldap_verifypeer == 'demand':
verifypeer = ldap.OPT_X_TLS_DEMAND
connection.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, verifypeer)
try:
connection.start_tls_s()
except:
pass
result = connection.search_s(ldap_search_base, ldap.SCOPE_SUBTREE, "uid="+userid)
connection.unbind_s()
if (result is None or len(result) == 0):
return None
#Return a fake user instance
return User(userid, str(uuid.uuid4()), True, ["user"])
except ldap.LDAPError, e:
if type(e.message) == dict:
for (k, v) in e.message.iteritems():
self._logger.error("%s: %sn" % (k, v))
else:
self._logger.error(e.message)
return None
else :
return local_user
def ldap_user_factory(components, settings, *args, **kwargs):
return LDAPUserManager();
__plugin_name__ = "Auth LDAP"
__plugin_version__ = "1.0.0"
__plugin_description__ = "LDAP authentication"
def __plugin_load__():
global __plugin_hooks__

View File

@ -7,4 +7,7 @@
# variables INSTALL_REQUIRES and EXTRA_REQUIRES.
###
## To install correctly python-ldap you need :
# apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev
.

View File

@ -14,11 +14,11 @@ plugin_package = "octoprint_%s" % plugin_identifier
plugin_name = "OctoPrint-LDAP"
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1"
plugin_version = "1.0.0"
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
plugin_description = "TODO"
plugin_description = "LDAP Auth provider"
# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
plugin_author = "Guillaume GILL"
@ -27,13 +27,13 @@ plugin_author = "Guillaume GILL"
plugin_author_email = "guillaume.gill@petitchinois.net"
# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
plugin_url = "TODO"
plugin_url = "https://github.com/gillg/OctoPrint-LDAP"
# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
plugin_license = "AGPLv3"
# Any additional requirements besides OctoPrint should be listed here
plugin_requires = ["ldap","uuid"]
plugin_requires = ["python-ldap","uuid"]
# Additional package data to install for this plugin. The subfolders "templates", "static" and "translations" will
# already be installed automatically if they exist.