Fixed svn authorization issue

azbok - December 7, 2007 - 03:39
Project:Subversion
Version:5.x-2.x-dev
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs review
Description

I need authorization to access my subversion repository and the file listings weren't being loaded. I investigated and found that in these 3 functions:
subversion_get_diff
subversion_ls
subversion_cat

There is the code:

if ($project->need_auth) {
# login using owner's login and password
$cmd = array_merge($cmd, array(
'--username', escapeshellarg($project->auth_username),
'--password', escapeshellarg($project->auth_password),
));
}

The problem is that $project isn't defined, I added a function like so:

function subversion_project_load($rid) {
$query = db_query('SELECT need_auth, auth_username, auth_password FROM {subversion_projects} WHERE rid = %d', $rid);
$project = db_fetch_object($query);
return $project;
}

Next I added the line above each of the if blocks in each one of those 3 functions

$project = subversion_project_load($repo->rid); // <--------- added line

if ($project->need_auth) {
# login using owner's login and password
$cmd = array_merge($cmd, array(
'--username', escapeshellarg($project->auth_username),
'--password', escapeshellarg($project->auth_password),
));
}

After I added that, it works (only after the below step is done)!

Also btw, I'm using a https:// repository. Because of that, there's an extra step involved. On linux when I login as the web account (in this case www-data username), and then I try to do an svn ls, I get:

{/home/azbok} www-data$ svn ls https://domain.com/path/to/repository
Error validating server certificate for 'https://domain.com/path/to/repository:443':
- The certificate is not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
Certificate information:
- Hostname: domain.com
- Valid: from Tue, 25 Sep 2007 12:41:08 GMT until Fri, 22 Sep 2017 12:41:08 GMT
- Issuer: Company, City, US, State
- Fingerprint: ab:cd:ef:gh:ij:kl:mn:op:qr:st:uv:wx:yz
(R)eject, accept (t)emporarily or accept (p)ermanently? p
Authentication realm: Subversion Respositories
Password for 'www-data':

You need to permanently accept the certificate so that way the web server/drupal can then login properly.

azbok

#1

leop - January 21, 2008 - 16:51

Since the version of 20080121 this problem extends four functions: subversion_cat, subversion_fetch_repository, subversion_get_diff and subversion_ls. The solution you propose is not working, because it uses the username and password from the first project that is fetched from the database, while the functions operate on the level of the entire repository. More specific: given the repository id $rid, you fetch the first project from the subversion_projects table that corresponds to the $rid. Next, the username and password for that project are used to retrieve information from the entire repository for all projects. Other projects might have different usernames and passwords, but they are not used.

As discussed in http://drupal.org/node/211603 (which now refers here), the real problem is that authentication is handled on the level of individual projects, while the four functions subversion_cat, subversion_fetch_repository, subversion_get_diff and subversion_ls operate on the level of the entire repository. The real solution is to implement authentication on the level of the repository, or to rewrite all functions to the level of individual projects. I think the latter is the best solution, but it is more complicated.

#2

halkeye - February 12, 2008 - 04:17

the code originally worked on a project level.
It was a very ineffeciant

But its very possible that one login won't work on the entire project.

I prefer a rewrite for repo level auth, any objections? Any opinions?

#3

leop - February 12, 2008 - 13:36

Without any additional modules, Drupal does not have the possibility to administrate project 'view' access on a per-project level. In other words, you can choose to grant a user 'view' access to either all, or no projects. If a user creates a project, and enters the Subversion login for that project in the repository, all other users that have project 'view' access can also browse the Subversion files for that project. That means Subversion authentication is not needed for other users, as long as the user that owns the project entered the Subversion login for that project.

This leads me to the following conclusions:

  1. A user that can view a project can also browse the repository for that project using the Subversion module, but only if the repository login for that project was entered by the project owner
  2. If your repository has per-project-authentication, you shouldn't grant repository browsing access for that project to all users that can view Drupal projects
  3. Browsing in a per-project-authentication repository should be limited to a project (i.e. no browsing is permitted above the project level)

A rewrite for repository level access should work for repositories that require authentication only on a repository level. Per-project-authentication or per-directory-authentication based repositories should not automatically be accessible for all users that can view projects. You should think of an option that links Drupal project authentication to Subversion authentication. I think this is going to be difficult (but not impossible). Repository-based authentication should be easy.

#4

leop - February 12, 2008 - 18:24

I have been thinking some more about repository authentication, and think this should be done in an entirely different fashion. I think giving repository browsing access to users that don't have Subversion accounts is wrong, except when the repository allows for anonymous browsing access. Repository access should be handled by Subversion, and should not be by-passed by allowing other users to view content under a different Subversion account. Specifying a username and password for a repository as a whole, or per-project, that grants other website users access to view the repository or a project, poses a security problem. Here is how it should be done:

  • The subversion module does not need a username and password for a repository for which Subversion allows anonymous (browsing) access.
  • The subversion module should use the Subversion account that is linked to the Drupal account of the user that is currently logged in for authorization in Subversion.

So the exec commands that need username and password values, should take those from the Subversion account that is linked to the currently logged on user. No access should be given to users that don't have Subversion accounts linked to their Drupal accounts, as long as the Subversion repository doesn't allow anonymous access. So Subversion authorization isn't dealt with on the level of a repository, nor is it dealt with on the level of projects: it should be dealt with on the level of users and their linked Subversion accounts. It's as simple as that.

#5

halkeye - February 13, 2008 - 06:30

I do like the idea of using the user id of the user logged in. But what about the log parsing? should it be entirely disabled if the repository doesn't support anon reads.

Plus, what if you had an account for reading, but require logins for write? not anon, just a shared account?

Maybe per repository authentication, with overrides for the user logged in?

Pros:
* Better access control

Cons:
* Caching on any ls or diffs would have to be on a per user biases.
* Log parsing possibly won't work as its not runtime.

There's probably more issues, but I won't have any time to deal with it until at least the weekend.

#6

leop - February 13, 2008 - 11:08

Indeed, per-user authentication has some cons, but I think it is possible to deal with that as follows:

  • The problem of log-parsing (e.g. by cron) can be solved by supplying the SVN user that should be used for that task. That would come down to a per-repository account for log parsing. This is very similar to setting the user that should be used for closing project issues. However, be careful with implementing access to the logs, because you might not want to display logs to all users.
  • I see there is a caching problem, for example, some directories should not be shown to some users in the ls list. One way to deal with this is to cache the ls and diff results anyway, and perform an access check each time the users navigates. If the user clicks on a file or directory to which he or she has no access, the appropriate message t('Access denied') should be shown.
  • There might be another way to handle caching: Drupal shows menu items in pages depending on the access permissions of the current user. I suspect this to be cached somehow. If you can figure out how that works, you might be able to implement repository browsing cache or diff caching in a similar fashion.
  • Maybe there is some more info on the Drupal website about caching and per-user content.

Plus, what if you had an account for reading, but require logins for write? not anon, just a shared account?

I understand this as follows: the SVN repository does not allow for anonymous read access, but there is a shared account that people use for read access. If a user wants to commit to the repository, he or she should log in to the repository on a different, personal account. This doesn't really pose a problem for per-user authentication in the subversion module. Here is how you do it:

  • Drupal users can link Subversion accounts to their Drupal accounts.
  • Drupal users that you want to grant only read access to the SVN repository via the subversion module can link the shared readonly SVN account to their Drupal account.
  • Drupal users that have read/write SVN accounts can link those accounts to their Drupal accounts, and can possibly use the subversion module to perform write actions to the repository, whatever those actions may be.

#7

leop - February 13, 2008 - 11:15

Also you might want to take a look at the Version Control API -- CVS backend, Version Control API, or Version Control API -- SVN backend (only in CVS). There might be solutions for caching that you can use.

#8

leop - February 13, 2008 - 17:38

I just had a look at the "admin/settings/performance" page of my website, and it says:

Enabling the cache will offer a significant performance boost. Drupal can store and send compressed cached pages requested by anonymous users. By caching a web page, Drupal does not have to construct the page each time someone wants to view it.

Does that mean that caching only works for anonymous users? If so, you shouldn't bother about caching stuff for authenticated users with the normal Drupal caching functionality. I'm not entirely sure though whether Drupal caches pages for authenticated users, so I might be wrong here.

 
 

Drupal is a registered trademark of Dries Buytaert.