Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New LDAPProvider for user_ldap #23992

Closed
wants to merge 67 commits into from
Closed

Conversation

@GitHubUser4234
Copy link

@GitHubUser4234 GitHubUser4234 commented Apr 14, 2016

New LDAPProvider for user_ldap, please refer to #23855

@blizzz

This comment has been minimized.

Copy link

@blizzz blizzz commented on apps/user_ldap/lib/backendutility.php in 3a4f0a1 Apr 13, 2016

seems to be redundant with getAccess()

@blizzz

This comment has been minimized.

Copy link

@blizzz blizzz commented on apps/user_ldap/lib/ldapprovider.php in 3a4f0a1 Apr 13, 2016

pass the UserManager (typehint against \OCP\IUserManager), this allows proper unit testing.

@blizzz

This comment has been minimized.

Copy link

@blizzz blizzz commented on apps/user_ldap/lib/ldapprovider.php in 3a4f0a1 Apr 13, 2016

Also here, best to pass \OCP\ILogger in the constructor (when instantiating you get it from \OC::$server->getLogger()). Use this subsequently, it's far nicer than the old writeLog.

@blizzz

This comment has been minimized.

Copy link

@blizzz blizzz commented on apps/user_ldap/lib/ldapprovider.php in 3a4f0a1 Apr 13, 2016

loginname does not help us here. You need to use Access::username2dn(), i.e. you need the Access instance here.

@blizzz

This comment has been minimized.

Copy link

@blizzz blizzz commented on apps/user_ldap/user_ldap.php in 3a4f0a1 Apr 13, 2016

pls check indentation

@mention-bot
Copy link

@mention-bot mention-bot commented Apr 14, 2016

By analyzing the blame information on this pull request, we identified @MorrisJobke, @blizzz and @LukasReschke to be potential reviewers

if ($backend instanceof IUserBackend && $backend->getBackendName() == USER_LDAP::BACKEND_NAME) {
$this->backend = $backend;
break;
}

This comment has been minimized.

@GitHubUser4234

GitHubUser4234 Apr 14, 2016
Author

When calling the user_ldap provider from a testing app, I'm currently running into a problem here, somehow the 'LDAP' backend is not in the loop, maybe because it is called before the 'LDAP' backend is registered? I have tried to uninstall and install the testing app again, but to no avail. Maybe something is wrong with this approach.

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

Possible. Do you have the code of the testing app available? In general some types of apps are being loaded first and before others, including authentication. So, if your test app has this type set, you might want to remove it. As a guess into the blue.

}
return false;
}
}

This comment has been minimized.

@GitHubUser4234

GitHubUser4234 Apr 15, 2016
Author

Not sure whether the usage of login names and internal user names is correct ☺️

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

Nope. loginnames and usernames differ. What you have often with LDAP is that a login name looks like "a.user" or "a.user@server.tld" while the username is based on the UUID which may look like "AB1234C5-678D-9E01-2E34-F567GHI89012". Basically, you'd just remove if($userName = $this->backend->loginName2UserName($uid)){.

You should always operate with usernames, not login names as they don't necessarily need to be unique.

If your callee uses the loginname instead of the username: if the user is logged in, you'll get the username from \OC::$server->getUserSession()->getUser(). This returns null or an IUser object. In the first cast, it's an error and maybe you just want to throw an exception. In the normal case you'll get the username from getUID() of the IUser instance.

foreach ($userManager->getBackends() as $backend){
$name = get_class($backend);
$this->logger->debug('instance '.$name.' backend.', ['app' => 'user_ldap']);
if ($backend instanceof IUserBackend && $backend->getBackendName() == USER_LDAP::BACKEND_NAME) {

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

use statement needed for IUserBackend and USER_LDAP

/**
* Translate an ownCloud login name to LDAP DN
* @param string $uid ownCloud user id
* @throws Exception

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

@return <TYPE> is missing

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

And Exception is missing the \ in front, otherwise it assumed to be in the same namespace as this class is in.

/**
* Return access for LDAP interaction.
*
* @return access

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

capital A please

if($userName = $this->backend->loginName2UserName($uid)){
return $this->backend->getLDAPAccess($userName)->username2dn($userName);
}
return false;

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

generally it is better to throw an exception instead of mixing return types.

/**
* Return access for LDAP interaction for the specified user.
* @param string $uid ownCloud user id
* @throws Exception

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

as above, @return is missing and Exception (although yet unthrown) lacks the \

if($userName = $this->backend->loginName2UserName($uid)){
return $this->backend->getLDAPAccess($userName);
}
return false;

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

as above, better to only return one type (Access) and throw an exception if this does not succeed. To ensure you're dealing with an LDAP user, it's a good idea to check $this->backend->userExists($uid)

/**
* creates and returns an instance of the ILDAPProvider
*
* @return ILDAPProvider

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

needs full namespace or usestatement

* @since 9.1.0
*/
public function getLDAPProvider() {
return new LDAPProvider(\OC::$server->getUserManager(), \OC::$server->getLogger());

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

even better would be to pass \OC::$server in the constructor, like https://github.com/owncloud/core/blob/master/lib/private/Comments/ManagerFactory.php#L44

/**
* Return access for LDAP interaction for the specified user
* @param string $uid
* @return mixed

This comment has been minimized.

* @throws Exception
*/
public function getUserDN($uid) {
throw new \Exception("Dummy function \"getUserDN\" called");

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

Currently, I am wondering whether it is not enough and sufficient to not have this class and throw an Exception directly in the servers LDAPProvider query, if nothing is configured in the config. This looks superfluous now that I see it. What do you think?

This comment has been minimized.

@GitHubUser4234

GitHubUser4234 Apr 18, 2016
Author

Yeah, sounds like less code to maintain 👍

/**
* Return access for LDAP interaction for the specified user
* @param string $uid
* @return Access for LDAP interaction

This comment has been minimized.

@blizzz

blizzz Apr 15, 2016
Contributor

namespace or use statement needed. However, specifying the LDAP backend's access is not enough, this should be another interface, which is also implemented by Access. ILDAPAccess for instance. We should handpick necessary methods from Access and declare them in the interface. Starting point: the methods that are useful for your application.

@blizzz
Copy link
Contributor

@blizzz blizzz commented Apr 15, 2016

Comments are inline, many taken out directly from my IDE ;) Smaller issues in general.

Three things remain, the first two low hanging fruits:

  • in user_ldap's appinfo/install.php and appinfo/update.php a check should happen wether a provider is configured. If not, write the config accordingly. Probably best to have a method in Helper that you call from both scripts.
  • In the LDAPProvider implementation actually check whether user_ldap is enabled, throw exception if not.
  • lib/public/ILDAPAccess as stated here https://github.com/owncloud/core/pull/23992/files#r59937276 I believe originally I was thinking of not returning an instance of the Access class here, but the pure LDAP Connection resource. However we have some normalization and conversion stuff in place in Access that you would need to take care of yourself if you have just the LDAP resource. We should figure out what you want to be able to do. We could have a shortcut to get the LDAP connection resource from Access->getConnection()->getConnectionResource(). To have proper control, some methods for controlling paged search, for instance, make sense, as do DNasBaseParameter() or sanitizeDN() and probably others. This needs some more thought work unfortunately.
3rdparty Outdated
@@ -1 +1 @@
Subproject commit 509385e674563e48a977bf8285c826963835528e
Subproject commit 16f2894332848adba757cc7add9d21a4ff1a6d18

This comment has been minimized.

@blizzz

blizzz Jul 8, 2016
Contributor

intentionally?

*
*/
$helper = new \OCA\User_LDAP\Helper();
$helper->setLDAPProvider();

This comment has been minimized.

@blizzz

blizzz Jul 8, 2016
Contributor

minor: there should be a blank line at the end of the file


public function __construct(Connection $connection, ILDAPWrapper $ldap,
Manager $userManager) {
parent::__construct($ldap);
$this->connection = $connection;
$this->userManager = $userManager;
$this->userManager->setLdapAccess($this);
$this->helper = new Helper();

This comment has been minimized.

@blizzz

blizzz Jul 8, 2016
Contributor

Ideally, this would be passed in the constructor (given, opens a can of worms).

*/
public function __construct(IServerContainer $serverContainer) {
$this->logger = $serverContainer->getLogger();
$this->helper = new Helper();

This comment has been minimized.

@blizzz

blizzz Jul 8, 2016
Contributor

there should not be initializations inside the constructor, they should be all passed as parameter. the Factory should deal with it.

* @since 9.1.0
*/
public function getLDAPProvider() {
return new LDAPProvider(\OC::$server);

This comment has been minimized.

@blizzz

blizzz Jul 8, 2016
Contributor

actually, the Factory should receive the container (== OC::$server), compare https://github.com/owncloud/core/blob/master/lib/private/Comments/ManagerFactory.php

@GitHubUser4234
Copy link
Author

@GitHubUser4234 GitHubUser4234 commented Jul 8, 2016

Thanks a lot @blizzz for your comments, they are implemented and committed. As discussed in IRC, the next step would be to implement unit tests to test all the public functions exposed by the LDAPProvider.

@GitHubUser4234 GitHubUser4234 force-pushed the GitHubUser4234:master branch to 648ad6a Jul 22, 2016
@ghost
Copy link

@ghost ghost commented Jul 22, 2016

@GitHubUser4234

Thanks a lot for your contribution!
Contributions to the core repo require a signed contributors agreement http://owncloud.org/about/contributor-agreement/

Alternatively you can add a comment here where you state that this contribution is MIT licensed.

Some more details about out pull request workflow can be found here: http://owncloud.org/code-reviews-on-github/

@elie195
Copy link
Contributor

@elie195 elie195 commented Aug 24, 2016

Is this PR targeted for implementation in 9.2? I'm looking forward to implementing it in my app to map UUID to owncloud_name in order to support LDAP in instances where the internal UUID mapping is set to the default.

@PVince81
Copy link
Contributor

@PVince81 PVince81 commented Sep 14, 2016

@jvillafanez @DeepDiver1975 @owncloud/ldap

@jvillafanez
Copy link
Member

@jvillafanez jvillafanez commented Sep 14, 2016

The changes seem big enough to be considered almost a new app, because I don't think it was originally planned the app contains such changes.

  • There are some refactor made there (sanitizeDN change the place in the PR) which is mixed with more changes. From my point of view, a bad idea since the change could have unexpected consecuences (some classes might be still calling to the old method). Such change should be isolated so we can verify that everything still works after the change.
  • Modifying lib/private/Server.php is a no-go from my point of view. An app such LDAP musn't modify core stuff. 🚫
  • Adding new interface to public library is also another no-go if it comes from another app such LDAP 🚫 . Core should provide generic interfaces for user and / or group handling, but never a specific interface for a specific service. It's fine is the LDAP app provide its own custom extension points so other apps hooks in there, but core shouldn't focus on LDAP.
@GitHubUser4234
Copy link
Author

@GitHubUser4234 GitHubUser4234 commented Sep 14, 2016

I switched to Nextcloud and I don't have the resources to maintain this PR in ownCloud. Sorry for any inconvenience caused.

@lock
Copy link

@lock lock bot commented Aug 4, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

9 participants
You can’t perform that action at this time.