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

Provide imap auth interface for plugins #9418

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jaudriga
Copy link

@jaudriga jaudriga commented Apr 17, 2024

Addresses #9377 .

Main change: Allows to use the rcmail::login() function for merely logging into IMAP by introducing a new flag $just_connect. This allows applications using the Roundcube Framework to reuse IMAP authentication logic.

Background: It would be beneficial for applications like Roundcube JMAP (see audriga/roundcube-jmap#6 ) or Kolab's FreeBusy to reuse large parts of the existing IMAP Authentcation logic of Roundcube. This is my try at providing an interface for reusing that.

Minor additional change: Adds a function in rcube to connect to IMAP. I actually consider this optional as its only beneficial for FreeBusy for now. This would basically allow FreeBusy to just call rcube::imap_connect() instead of what they are doing right now (from lib/Kolab/FreeBusy/SourceIMAP.php):

// enable proxy authentication
if (!empty($config['proxy_auth'])) {
	$imap->set_options(array('auth_cid' => $config['proxy_auth'], 'auth_pw' => $config['pass']));
}

// authenticate user in IMAP
if (!$imap->connect($host, $config['user'], $config['pass'], $port, $ssl)) {
	Logger::get('imap')->addWarning("Failed to connect to IMAP server: " . $imap->get_error_code(), $config);
	return false;
}

Copy link
Member

@pabzm pabzm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the one request about the comment I find this well done and would merge it (which I don't decide on my own), thanks a lot for the thoughful and careful way to introduce a new feature!

program/include/rcmail.php Outdated Show resolved Hide resolved
@pabzm
Copy link
Member

pabzm commented May 7, 2024

@jaudriga After reading the corresponding ticket I'm wondering you want this actually merged or if it's more of a proof of concept to illustrate your broader request?

@jaudriga
Copy link
Author

@pabzm

It would be great to have this merged as this is an obvious and straight forward aspect of #9377 to address for me.

I realize that that might not address all aspects of #9377 , however, its an important and good step in the right direction.

Addressing even broader changes would be great, but not strictly necessary in my opinion. I would need a bit more support for those as a bunch of design decisions would need to be taken that I am not comfortable taking on my own.

I would suggest that we focus on this PR for now and potentially discuss about further improvements in #9377 .

@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch from f891a11 to ade9454 Compare May 13, 2024 08:16
@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch from ade9454 to d938502 Compare May 14, 2024 06:27
@jaudriga
Copy link
Author

I rebased on newest master as on of the CI jobs failed: https://github.com/roundcube/roundcubemail/actions/runs/9059543070/job/24905660338

@pabzm
Copy link
Member

pabzm commented May 14, 2024

The CI will be fixed with #9449, please rebase again after that was merged.

@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch from d938502 to ec1851f Compare May 16, 2024 16:33
@jaudriga
Copy link
Author

I rebased again ;)

@pabzm
Copy link
Member

pabzm commented May 17, 2024

@alecpl Any thoughts on this?

@pabzm
Copy link
Member

pabzm commented May 29, 2024

@alecpl Please have a look at this and provide feedback, or let us know that you're fine with us proceeding without your involvement.

@alecpl
Copy link
Member

alecpl commented Jun 2, 2024

I don't like it as it is.

  1. It should be storage_connect not imap_connect. The existing rcmail::storage_connect() would need to be renamed (or moved to rcmail_action).
  2. I think this new storage_connect() should contain more code from login(), i.e. lines from 751-809. Possibly also set_user() and set_storage_prop() calls.
  3. Then that method could return rcube_user on success.

Fixes roundcube#9377 . Allows rcmail::login() to be reused in plugins providing
an API. The login function provides some useful logic for connecting to
IMAP sources like checking credentials for validity or converting
usernames in some cases.

Before this change the login function always also created non-existing
users or set some sesison vars, which what API plugins would like to
avoid.
This is useful for plugins like FreeBusy [1] that previously
connected to IMAP via plain rcube_imap::connect().

[1] https://git.kolab.org/source/freebusy/browse/master/lib/Kolab/FreeBusy/SourceIMAP.php
@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch 3 times, most recently from 1354451 to c030281 Compare July 15, 2024 13:51
@jaudriga
Copy link
Author

I don't like it as it is.

Thanks @alecpl for taking a look at the PR. I came around to addressing your feedback today.

Your first suggestion was relatively straight-forward to address IMHO.

I intentionally left out returning an rcube_user object in the first iteration of the PR to avoid as much refactoring as possible. However, I agree that its more well-designed to return rcube_user in the new storage_connect.

The refactoring that I now did is moving the error codes from the rcmail into the rcube parent class. I chose this refactoring, because the $user is checked for brute-force prevention directly after querying for the username. This potentially sets the error to ERROR_RATE_LIMIT. Alternative to this refactoring I had the ideas of either throwing a novel Exception within storage_connect to signal ERROR_RATE_LIMIT or duplicating the rcube_user::query() call.

Please take a look if the newest changes are fine for you.

@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch 2 times, most recently from c6b3717 to e32b164 Compare July 15, 2024 14:28
* rename `imap_connect` to `storage_connect`
* rename `rcmail::storage_connect` to `storage_connect_from_session`
* let `storage_connect` return rcube_user
* let `storage_connect` include more code from `login()`
@jaudriga jaudriga force-pushed the 9377-provide-imap-auth-interface-for-plugins branch from e32b164 to 110a6a0 Compare July 15, 2024 14:28
*
* @return rcube_user|int|null Return user object on success, null or error code on failure
*/
public function storage_connect($imap, $host, $username, $password, $port, $ssl, $imap_options = [], $just_connect = false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to not have the $imap argument. We can call get_storage() in here. Then probably $imap_options should be gone too. BTW, you miss $imap_options in the storage_connect() call.


// Wait a second to slow down brute-force attacks (#1490549)
sleep(1);
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to never return null from this method. I.e. return error code or object, here it could be ERROR_STORAGE. That would mean we probably need other codes to cover the cases below.

I'm not sure what to do with $just_connect=true and empty $user (but successful connection).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants