Closed advh67 closed 3 years ago
Can you try again. Cannot promise is fixed. Do not have an easy way to fix but I will help debug. I want this to work.
I have created a new app with last scaffold template. I later modified the file settings.py activating LDAP_SETTINGS. The app worked and showed the login screen. When I type any user/password it throws this error on console:
ERROR:root:Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 469, in wrapper ret = func(*func_args, *func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 435, in wrapper ret = func(args, **kwargs) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder return self.action(path, request.method, request.query, request.json) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action if self.plugins['pam'].check_credentials(username, password): KeyError: 'pam'
I upgraded pyweb typing "pip install --upgrade py4web", and file /usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/pam.py exists. /usr/lib/.../pam_plugin.py exists, too.
I have this in my file settings.py:
enable PAM
USE_PAM = False
enable LDAP
USE_LDAP = True LDAP_SETTINGS = { # corrected typing error SETTING -> SETTINGS 'mode': 'ad', 'server': 'mycorporateserver.intranet',
'base_dn': 'ou=Users,dc=domain,dc=com'}
By the way, my corporate ldap server accepts user names, not emails. How can I change it on py4web?
I posted a new version. Please check if it fixes it.
It looks like it has been fixed. I have updated your modifications directly from github to my folder "site-packages". Updated the "assets" folder, deleted my app and re-created it using a updated dashboard. Then, I modified again the (corrected) settings.py with my settings. Now It shows login screen. When I type user/password and click "login", it throws an "Internal server error" about jwt:
traceback | Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/jwt/api_jws.py", line 180, in _load signing_input, crypto_segment = jwt.rsplit(b'.', 1)
ValueError: not enough values to unpack (expected 2, got 1)
During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 469, in wrapper ret = func(*func_args, **func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 434, in wrapper [obj.on_request() for obj in fixtures] File "/usr/lib/python3.7/site-packages/py4web/core.py", line 434, in [obj.on_request() for obj in fixtures] File "/usr/lib/python3.7/site-packages/py4web/core.py", line 348, in on_request self.load() File "/usr/lib/python3.7/site-packages/py4web/core.py", line 310, in load token_data, self.secret, algorithms=[self.algorithm]) File "/usr/lib/python3.7/site-packages/jwt/api_jwt.py", line 84, in decode payload, _, _, _ = self._load(jwt) File "/usr/lib/python3.7/site-packages/jwt/api_jws.py", line 183, in _load raise DecodeError('Not enough segments') jwt.exceptions.DecodeError: Not enough segments
-- | --
DecodeError
Not enough segments
file/usr/lib/python3.7/site-packages/py4web/core.pyfuncwrapperlnum469code try: request.app_name = app_name ret = func(*func_args, **func_kwargs) if isinstance(ret, dict): response.headers['Content-Type'] = 'application/json' varsfunc_args()func_kwargs{}app_name'gestor'funcfile/usr/lib/python3.7/site-packages/py4web/core.pyfuncwrapperlnum434code def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures: varsargs()kwargs{}fixtures[, , , , , ]funcfile/usr/lib/python3.7/site-packages/py4web/core.pyfunclnum434code def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures: vars.0objfile/usr/lib/python3.7/site-packages/py4web/core.pyfuncon_requestlnum348code def on_request(self): self.load() def on_error(self): varsselffile/usr/lib/python3.7/site-packages/py4web/core.pyfuncloadlnum310code else: self.local.data = jwt.decode( token_data, self.secret, algorithms=[self.algorithm]) if self.expiration is not None and self.storage is None: assert self.local.data[ varsselfraw_token'3f24065c-45d5-466f-bb0a-0a5664355b7a'token_datab'3f24065c-45d5-466f-bb0a-0a5664355b7a'file/usr/lib/python3.7/site-packages/jwt/api_jwt.pyfuncdecodelnum84code ) payload, _, _, _ = self._load(jwt) if options is None: varsselfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'key''verifyTruealgorithms['HS256']optionsNonekwargs{}file/usr/lib/python3.7/site-packages/jwt/api_jws.pyfunc_loadlnum183code header_segment, payload_segment = signing_input.split(b'.', 1) except ValueError: raise DecodeError('Not enough segments') try: varsselfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a' | /usr/lib/python3.7/site-packages/py4web/core.py | wrapper | 469 | try: request.app_name = app_name ret = func(*func_args, **func_kwargs) if isinstance(ret, dict): response.headers['Content-Type'] = 'application/json' | func_args()func_kwargs{}app_name'gestor'func | () | {} | 'gestor' | | /usr/lib/python3.7/site-packages/py4web/core.py | wrapper | 434 | def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures: | args()kwargs{}fixtures[, , , , , ]func | () | {} | [, , , , , ] | | /usr/lib/python3.7/site-packages/py4web/core.py | | 434 | def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures: | .0obj | | | /usr/lib/python3.7/site-packages/py4web/core.py | on_request | 348 | def on_request(self): self.load() def on_error(self): | self | | /usr/lib/python3.7/site-packages/py4web/core.py | load | 310 | else: self.local.data = jwt.decode( token_data, self.secret, algorithms=[self.algorithm]) if self.expiration is not None and self.storage is None: assert self.local.data[ | selfraw_token'3f24065c-45d5-466f-bb0a-0a5664355b7a'token_datab'3f24065c-45d5-466f-bb0a-0a5664355b7a' | | '3f24065c-45d5-466f-bb0a-0a5664355b7a' | b'3f24065c-45d5-466f-bb0a-0a5664355b7a' | /usr/lib/python3.7/site-packages/jwt/api_jwt.py | decode | 84 | ) payload, _, _, _ = self._load(jwt) if options is None: | selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'key''verifyTruealgorithms['HS256']optionsNonekwargs{} | | b'3f24065c-45d5-466f-bb0a-0a5664355b7a' | '' | True | ['HS256'] | None | {} | /usr/lib/python3.7/site-packages/jwt/api_jws.py | _load | 183 | header_segment, payload_segment = signing_input.split(b'.', 1) except ValueError: raise DecodeError('Not enough segments') try: | selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a' | | b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
/usr/lib/python3.7/site-packages/py4web/core.py
wrapper
469
try: request.app_name = app_name ret = func(*func_args, **func_kwargs) if isinstance(ret, dict): response.headers['Content-Type'] = 'application/json'
func_args()func_kwargs{}app_name'gestor'func | () | {} | 'gestor' |
()
{}
'gestor'
/usr/lib/python3.7/site-packages/py4web/core.py
wrapper
434
def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures:
args()kwargs{}fixtures[, , , , , ]func | () | {} | [, , , , , ] |
()
{}
[, , , , , ]
/usr/lib/python3.7/site-packages/py4web/core.py
434
def wrapper(*args, **kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, **kwargs) for obj in fixtures:
.0obj | |
/usr/lib/python3.7/site-packages/py4web/core.py
on_request
348
def on_request(self): self.load() def on_error(self):
self |
/usr/lib/python3.7/site-packages/py4web/core.py
load
310
else: self.local.data = jwt.decode( token_data, self.secret, algorithms=[self.algorithm]) if self.expiration is not None and self.storage is None: assert self.local.data[
selfraw_token'3f24065c-45d5-466f-bb0a-0a5664355b7a'token_datab'3f24065c-45d5-466f-bb0a-0a5664355b7a' | | '3f24065c-45d5-466f-bb0a-0a5664355b7a' | b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
'3f24065c-45d5-466f-bb0a-0a5664355b7a'
b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
/usr/lib/python3.7/site-packages/jwt/api_jwt.py
decode
84
) payload, _, _, _ = self._load(jwt) if options is None:
selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'key''verifyTruealgorithms['HS256']optionsNonekwargs{} | | b'3f24065c-45d5-466f-bb0a-0a5664355b7a' | '' | True | ['HS256'] | None | {}
b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
''
True
['HS256']
None
{}
/usr/lib/python3.7/site-packages/jwt/api_jws.py
_load
183
header_segment, payload_segment = signing_input.split(b'.', 1) except ValueError: raise DecodeError('Not enough segments') try:
selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a' | | b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
Try clear cookies
On Mon, Sep 23, 2019, 02:04 advh67 notifications@github.com wrote:
May be fixed. I have updated your modifications directly from github to my folder "site-packages". Updated the "assets" folder, deleted my app and re-created it with updated dashboard. Then, I modified again the (corrected) settings.py with my settings. Now It shows login screen. When I type user/password and click "login", it throws an "Internal server error" about jwt: traceback Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/jwt/api_jws.py", line 180, in _load signing_input, crypto_segment = jwt.rsplit(b'.', 1) ValueError: not enough values to unpack (expected 2, got 1) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 469, in wrapper ret = func(*func_args, func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 434, in wrapper [obj.on_request() for obj in fixtures] File "/usr/lib/python3.7/site-packages/py4web/core.py", line 434, in [obj.on_request() for obj in fixtures] File "/usr/lib/python3.7/site-packages/py4web/core.py", line 348, in on_request self.load() File "/usr/lib/python3.7/site-packages/py4web/core.py", line 310, in load token_data, self.secret, algorithms=[self.algorithm]) File "/usr/lib/python3.7/site-packages/jwt/apijwt.py", line 84, in decode payload, , , = self._load(jwt) File "/usr/lib/python3.7/site-packages/jwt/api_jws.py", line 183, in _load raise DecodeError('Not enough segments') jwt.exceptions.DecodeError: Not enough segments DecodeError Not enough segments file/usr/lib/python3.7/site-packages/py4web/core.pyfuncwrapperlnum469code try: request.app_name = app_name ret = func(*func_args, *func_kwargs) if isinstance(ret, dict): response.headers['Content-Type'] = 'application/json' varsfunc_args()func_kwargs{}app_name'gestor'funcfile/usr/lib/python3.7/site-packages/py4web/core.pyfuncwrapperlnum434code def wrapper(args, kwargs): try: [obj.on_request() for obj in fixtures] ret = func(*args, kwargs) for obj in fixtures: varsargs()kwargs{}fixtures[, , , , , ]funcfile/usr/lib/python3.7/site-packages/py4web/core.pyfunclnum434code def wrapper(*args, *kwargs): try: [obj.on_request() for obj in fixtures] ret = func(args, kwargs) for obj in fixtures: vars.0objfile/usr/lib/python3.7/site-packages/py4web/core.pyfuncon_requestlnum348code def on_request(self): self.load() def on_error(self): varsselffile/usr/lib/python3.7/site-packages/py4web/core.pyfuncloadlnum310code else: self.local.data = jwt.decode( token_data, self.secret, algorithms=[self.algorithm]) if self.expiration is not None and self.storage is None: assert self.local.data[ varsselfraw_token'3f24065c-45d5-466f-bb0a-0a5664355b7a'token_datab'3f24065c-45d5-466f-bb0a-0a5664355b7a'file/usr/lib/python3.7/site-packages/jwt/apijwt.pyfuncdecodelnum84code ) payload, , , = self._load(jwt) if options is None: varsselfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'key''verifyTruealgorithms['HS256']optionsNonekwargs{}file/usr/lib/python3.7/site-packages/jwt/api_jws.pyfunc_loadlnum183code header_segment, payload_segment = signing_input.split(b'.', 1) except ValueError: raise DecodeError('Not enough segments') try: varsselfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a' /usr/lib/python3.7/site-packages/py4web/core.py /usr/lib/python3.7/site-packages/py4web/core.py wrapper 469 try: request.app_name = app_name ret = func(*func_args, **func_kwargs) if isinstance(ret, dict): response.headers['Content-Type'] = 'application/json' func_args()func_kwargs{}app_name'gestor'func () () {} 'gestor'
/usr/lib/python3.7/site-packages/py4web/core.py wrapper 434 def wrapper(*args, *kwargs): try: [obj.on_request() for obj in fixtures] ret = func(args, **kwargs) for obj in fixtures: args()kwargs{}fixtures[, , , , , ]func () () {} [, , , , , ]
/usr/lib/python3.7/site-packages/py4web/core.py
434 def wrapper(*args, *kwargs): try: [obj.on_request() for obj in fixtures] ret = func(args, **kwargs) for obj in fixtures: .0obj
/usr/lib/python3.7/site-packages/py4web/core.py on_request 348 def on_request(self): self.load() def on_error(self): self
/usr/lib/python3.7/site-packages/py4web/core.py load 310 else: self.local.data = jwt.decode( token_data, self.secret, algorithms=[self.algorithm]) if self.expiration is not None and self.storage is None: assert self.local.data[
selfraw_token'3f24065c-45d5-466f-bb0a-0a5664355b7a'token_datab'3f24065c-45d5-466f-bb0a-0a5664355b7a'
'3f24065c-45d5-466f-bb0a-0a5664355b7a' b'3f24065c-45d5-466f-bb0a-0a5664355b7a' /usr/lib/python3.7/site-packages/jwt/apijwt.py decode 84 ) payload, , , = self._load(jwt) if options is None:
selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'key''verifyTruealgorithms['HS256']optionsNonekwargs{}
b'3f24065c-45d5-466f-bb0a-0a5664355b7a' '' True ['HS256'] None {} /usr/lib/python3.7/site-packages/jwt/api_jws.py _load 183 header_segment, payload_segment = signing_input.split(b'.', 1) except ValueError: raise DecodeError('Not enough segments') try: selfjwtb'3f24065c-45d5-466f-bb0a-0a5664355b7a'
b'3f24065c-45d5-466f-bb0a-0a5664355b7a'
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/web2py/py4web/issues/29?email_source=notifications&email_token=AAHLZT7EFNEA7IO4WUFEKQTQLCBBLA5CNFSM4ILICVT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7KHCEQ#issuecomment-534016274, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLZTZ5IAUBWT5DAFZ6QWTQLCBBLANCNFSM4ILICVTQ .
Cookies cleared.
Now, the error is:
ERROR:root:Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 469, in wrapper ret = func(*func_args, *func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 435, in wrapper ret = func(args, **kwargs) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder return self.action(path, request.method, request.query, request.json) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action check = self.plugins[plugin_name].check_credentials(username, password) File "/usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/ldap_plugin.py", line 189, in check_credentials logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s]' NameError: name 'logger' is not defined
Can you try again. I have a possible temporary fix
ERROR:root:Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/py4web/core.py", line 471, in wrapper
ret = func(*func_args, *func_kwargs)
File "/usr/lib/python3.7/site-packages/py4web/core.py", line 437, in wrapper
ret = func(args, **kwargs)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder
return self.action(path, request.method, request.query, request.json)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action
check = self.plugins[plugin_name].check_credentials(username, password)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/ldap_plugin.py", line 186, in check_credentials
exec("%s = %r" % (key, self.parameters[key]))
File "
one more try. I wish I had a way to test it myself.
On Wed, Sep 25, 2019 at 12:05 AM advh67 notifications@github.com wrote:
ERROR:root:Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 471, in wrapper ret = func(*func_args, *func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 437, in wrapper ret = func(args, *kwargs) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder return self.action(path, request.method, request.query, request.json) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action check = self.plugins[plugin_name].check_credentials(username, password) File "/usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/ldap_plugin.py", line 186, in check_credentials exec("%s = %r" % (key, self.parameters[key])) File "", line 1 logger = <module 'logging' from '/usr/lib/python3.7/logging/init*.py'> ^ SyntaxError: invalid syntax
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/web2py/py4web/issues/29?email_source=notifications&email_token=AAHLZT2KBKT5FLW3DXINREDQLMEUDA5CNFSM4ILICVT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7Q3EKQ#issuecomment-534884906, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLZTZXQLPN4WWUBHS4ICTQLMEUDANCNFSM4ILICVTQ .
Don't worry, "quien nunca trabaja, nunca yerra" "who never works, never fails"
The non-new error. I have erased cookies again and restarted py4web.
Could be the mistake "logger.debug..." -> "self.logger.debug..."? There is only one line (162) "self.logger = args["logger"] " in ldap_plugin.py, but there are many lines referencing the plain "logger" variable.
yes, they should all be self.logger.
On Wed, Sep 25, 2019 at 12:53 AM advh67 notifications@github.com wrote:
Don't worry, "quien nunca trabaja, nunca yerra" "who never works, never fails"
The non-new error. I have erased cookies again and restarted py4web.
ERROR:root:Traceback (most recent call last): File "/usr/lib/python3.7/site-packages/py4web/core.py", line 471, in wrapper ret = func(*func_args, *func_kwargs) File "/usr/lib/python3.7/site-packages/py4web/core.py", line 437, in wrapper ret = func(args, **kwargs) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder return self.action(path, request.method, request.query, request.json) File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action check = self.plugins[plugin_name].check_credentials(username, password) File "/usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/ldap_plugin.py", line 191, in check_credentials logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s] manage_groups: [%s]' % NameError: name 'logger' is not defined
Could be the mistake "logger.debug..." -> "self.logger.debug..."? There is only one line (162) "self.logger = args["logger"] ", but there are many lines referencing the plain "logger" variable.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/web2py/py4web/issues/29?email_source=notifications&email_token=AAHLZT5P4WHBUIRTX53Z6NLQLMKGVA5CNFSM4ILICVT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7Q6ZQI#issuecomment-534899905, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLZT6XRN5Y3AEFQMVUD6DQLMKGVANCNFSM4ILICVTQ .
I replaced all the logger with self.logger.
The next error is "mode is not defined" in check_credentials. You put there a loop with a exec() function. I modified my ldap_plugin.py for showing the variables on my console:
def check_credentials(self, username, password):
for key in self.parameters:
print("%s = %r" % (key, self.parameters[key])) # inserted by me
exec("%s = %r" % (key, self.parameters[key])) # original
exec("print(%s)" %key) # inserted by me, just prints the value of the new variable whose name is present in the keys of self.parameters
if password == '': # http://tools.ietf.org/html/rfc4513#section-5.1.2
self.logger.warning('blank password not allowed')
return False
self.logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s] manage_groups: [%s]' %
(str(mode), str(manage_user), str(custom_scope), str(manage_groups)))
The error thrown is:
mode = 'ad'
ad
server = 'myldap.intranet'
myldap.intranet
base_dn = 'ou=Users,dc=domain,dc=com'
ou=Users,dc=domain,dc=com
port = None
None
secure = False
False
self_signed_certificate = None
None
cert_path = None
None
cert_file = None
None
cacert_path = None
None
cacert_file = None
None
key_file = None
None
bind_dn = None
None
bind_pw = None
None
filterstr = 'objectClass='
objectClass=
username_attrib = 'uid'
uid
custom_scope = 'subtree'
subtree
allowed_groups = None
None
manage_user = False
False
user_firstname_attrib = 'cn:1'
ERROR:root:Traceback (most recent call last):
File "/usr/lib/python3.7/site-packages/py4web/core.py", line 471, in wrapper
ret = func(*func_args, *func_kwargs)
File "/usr/lib/python3.7/site-packages/py4web/core.py", line 437, in wrapper
ret = func(args, **kwargs)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 133, in responder
return self.action(path, request.method, request.query, request.json)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 164, in action
check = self.plugins[plugin_name].check_credentials(username, password)
File "/usr/lib/python3.7/site-packages/py4web/utils/auth_plugins/ldap_plugin.py", line 189, in check_credentials
exec("print(%s)" %key)
File "
?????
One more try please. :-)
ldap_plugin.py needs to add a line: import ldap import ldap.filter # <--add this
Still testing :-)
Update:
The code is now doing successfully the basic ldap authentication :-D
if bind_dn:
# need to search directory with an admin account 1st
con.simple_bind_s(bind_dn, bind_pw)
else:
# credentials should be in the form of username@domain.tld
con.simple_bind_s(username, password) # does not throw errors like INVALID_CREDENTIALS when credentials are right
# this will throw an index error if the account is not found
# in the base_dn
requested_attrs = ['sAMAccountName']
if manage_user:
requested_attrs.extend([user_firstname_attrib, user_lastname_attrib, user_mail_attrib])
Nothing throws error here
It goes OK upto line 300 of check_credentials() But, the lines:
result = con.search_ext_s( base_dn, ldap.SCOPE_SUBTREE, "(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), filterstr), requested_attrs)[0][1]
throw an error: UnboundLocalError: local variable 'result' referenced before assignment
I have enclosed that con.search_ext_s() with a try..except, and returns this error: {'desc': 'Referral', 'info': 'Referral:\nldaps://mydomain/ou=users,dc=mydomain'}
I don't know if this error is about ldap or about MY company ldap implementation. My working web2py app only needs to check if username/passwords are valid. I don't need to search anything else on corporate ldap.
My settings in settings.py are: LDAP_SETTINGS = { 'mode': 'ad', 'server': 'myldapserver.intranet', # is ldaps 'base_dn': 'ou=users,dc=mydomain', 'secure':True, 'self_signed_certificate':True, 'manage_user':True }
I will most likely be testing this soon, any idea's / recommendations for implementation?
Also any recommendations regarding login restrictions by group / user id (without having to create & maintain an access list)?
Well, my company does not rely its grouping structure on ldap. My needs are just checking user/password and maintain groups by hand because in my company is the only way to do it for me. The ldap structure is only a mirror of our active employees.
Would be nice to have something like (very)"basic_ldap_auth" or so, and inserting/updating the user on py4web auth_user table. Web2py's style.
A nice add would be creating, by default, a membership table with two groups "administrator" and "anonymous" by default(*). I usually authenticate by ldap, but any app must have an administrator (usually me, a mate, a skilled boss,...) and any (ldap) logged user must would be assigned to "anonymous" by default. New groups would be assigned to every active user (by hand :-( ).
(*) I understand english, but is a better option if default names could be translated to local language.
@advh67 You can do all this already in py4web but need to write some examples. Anyway the discussion does not belong in this thread. I will create a page in the documentation. :-)
OK. It will take a while for me to read and assimilate ;-) Thanks
I think this issue can be closed.
Basic LDAP authentication with AD works fine (but I've not tested LDAPS). Using TAGS for authorization is well documented on https://py4web.com/_documentation/static/en/chapter-13.html# , especially with the latest changes that you can preview on https://nicozanf.github.io/py4web-doc/en/master/chapter-13.html#
Please open another specific issue if there is something more to work on.
I created a new py4web app using the dashboard. The scaffold template created the skeleton of the new app. Ok.
In the file settings.py, line 33, says: LDAP_SETTING={ It would must be: LDAP_SETTINGS={
Corrected this mispelling, the next error: File "/home/advh67/py4web/apps/mynewapp/common.py", line 47, in
auth.register_plugin(LDAPPlugin(**LDAP_SETTINGS))
NameError: name 'LDAP_SETTINGS' is not defined
would must be(?): auth.register_plugin(LDAPPlugin(**settings.LDAP_SETTINGS))
Once corrected, the initialization fails again:
File "/home/advh67/py4web/apps/mynewapp/common.py", line 47, in
auth.register_plugin(LDAPPlugin(**settings.LDAP_SETTINGS))
File "/usr/lib/python3.7/site-packages/py4web/utils/auth.py", line 106, in register_plugin
self.plugins[plugin.name] = plugin
AttributeError: 'LDAPPlugin' object has no attribute 'name'
I am stuck.
Py4web was installed using: python3 -m pip install --upgrade py4web an launched by typing: py4web-start apps as told in documentation.
My folder /home/advh67/py4web is empty of files. It only contains the apps folder.