Fixed svn authorization issue
| Project: | Subversion |
| Version: | 5.x-2.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Jump to:
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
Since the version of 20080121 this problem extends four functions:
subversion_cat,subversion_fetch_repository,subversion_get_diffandsubversion_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 thesubversion_projectstable 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_diffandsubversion_lsoperate 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
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
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:
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
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:
So the
execcommands 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
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
Indeed, per-user authentication has some cons, but I think it is possible to deal with that as follows:
lslist. One way to deal with this is to cache thelsanddiffresults 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 messaget('Access denied')should be shown.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:
#7
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
I just had a look at the "admin/settings/performance" page of my website, and it says:
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.