hgweb: display different repositories to different users? - mercurial

I'd like to host two different sets of private repositories off the same server/vhost, and have users see one set or another depending on their credentials.
Is there an easier way of doing this than hosting two separate hgweb instances with separate user accounts and config files?

Technically, nothing prevents you from having this line:
allow_read = user1 user2 user3
in .hg/hgrc of half of your repos, and:
allow_read = user4 user5 user6
in the other half. Even to see the repo in the list, the user has to be in the allow_read list.
However, managing this can prove cumbersome.

Related

authz_dbd, multi user authentication and individual folders through .htaccess

Intro
Our apache2 setup serves files from a wide variety of folders using webdav, and use authz_dbd to communicate with a mysql database (this part works without problems).
Summary:
Apache2, mod_authz_dbd, mod_authn_dbd, mysql, enabling webdav, multi user environment (iot nodes).
However... some of these folders are user specific.
folder1 admins
+--subfolder1.1 admins+some other folk+user1
+--subfolder1.2 admins+again other folk+user1
folder2
+--subfolder 2.1 same as 1.1 but with user2
+--subfolder 2.2 as1.2.. but..user2
We use dbd-groups with wildcards, similar to this:
location /var/www/html/*/subfolder1.1
require dbd-group read
And normally wrote all in the vhosts file
(require user.. )
The problem
This becomes too large, we need another fix.
We cannot use .htaccess files in combination with dbd groups (dbd groups are not allowed in .htacces). Our debian (jessy) does not allow the other mysql apache2 mods.
The combination of .htaccess files with dbd's mysql authorization does not work (dbd groups are not allowed in .htaccess).
Our debian server does not allow other mysql apache2 mods (like mod_auth_mysql).
How can I combine mysql authorization with the folder specific users?
Ok, i believe ive cracked it:
Technique
Apache natively support for named groupes and backreferances.
The capture group can be employed to identify the folder (and with this the user).
How does this work;
every subdir with of the hosted directory (/var/www/web)
Beginning with M and containing at least three decimals (M\d{3,}) <- the capture group.
This is stored in a variable ( sitedir)
eg.
/var/www/web/M1234/etc. sitedir=M1234
/var/www/web/M1234567/test/ANY other directory sitedir=M1234567
In my case I match the user with the directory name require user %{env:MATCH_SITEDIR}
Be very aware to use the queries outside the require directives (as shown below).
Using cascaded RequireAny/Requireall other requirements can be made
(requirements on dbd groups, ip ristrictions etc).
Drawbacks
The capture group might allow for multiple folders with an Mcode.
This can be mitigated by adapting the capture group.
The captured foldername cannot be used inside the query (it does not allow this)
This would have been even nicer, but it does not work...(the variable is considered plain text).
working example
<DirectoryMatch /var/www/web/(?<sitedir>(M\d{3,}))>
AuthDBDUserPWQuery "SELECT password FROM mysql_auth WHERE username = %s"
AuthzDBDQuery "SELECT groups FROM mysql_auth WHERE username = %s"
<RequireAny>
Require user %{env:MATCH_SITEDIR}
<RequireAll>
Require valid-user
Require ip 10.0.0.0/16
<RequireAny>
Require dbd-group internal
Require dbd-group write
</RequireAny>
</RequireAll>
</RequireAny>
</DirectoryMatch>

Weird roster group in ejabberd "_root"

I am trying to debug a weird issue with one user's roster in ejabberd.
He is having a roster group "_root" show up in his client (PSI).
The server is using mod_ldap for user authentication.
Things tried so far:
deleting the group from the client -> the group appears again after a while
unregistering the user with /ejabberdctl unregister user domain.com -> the group appears again after a while
Only one user is affected by this on the server, which makes me think it has to be something specific to this one user's settings (or client). But we have a bunch of people also using PSI with no problems.
Is there a way to look at the roster groups defined for a specific user in the database directly?
Thanks,
kaza
That "_root" value must come from the roster module data. You did not say which roster module you use, but I guess the server is configured to use mod_roster_ldap and possibly mod_shared_roster_ldap. Check the configuration of the module and explore the content of the LDAP directory to see if you see that value. I would think that value comes from there.

Mercurial's authors description

I'm trying to change Mercurial's template.
When I push some files to my repository, the log files list my PC's name, not user's name that is logged in.
I don't want the PC's name, I want logged user's name shows up.
How I do it?
#Praveen-K has the right answer and Lazy Badger and Lasse have the details you're missing. Here it is spelled out, but go pick Praveen's answer:
The user name you're seeing in/on your remote repository are completely unrelated to:
Any settings on your repository/server
The username you use to authenticate to your repository
Instead that string, called 'author' is burned into the changeset (commit) at commit time and is entirely crafted on your "PC". You could set it to anything you want and once you push that commit to the repository that's how it will display.
At your current skill level you're not going to successfully change that string in commits you've already made, but if you dive into a good explanation (not lookup commands) like the hg book you'll come away understanding things.
Make the entry in to your hgrc file. This file should be in your .hg/ directory (it may be in your repo or you can do in your home directory) and if it is not exist make the file with the name of hgrc in that folder.
[ui]
username = Your Name <your#mail>

Controlling access via hgweb.config

I would like to be able to control access to some mercurial repositories on my server. I thought an easy solution would be to have all limited users have a username that ends with "_external". I would then change the deny_push and deny_read on some .hgrc files to give them access as needed. I setup up my hgweb.config file like below, but the deny_push and deny_read lines are ignored. Is this the correct syntax? Is there a better way to accomplish my goal (I looked into Rhodecode, but it seems to be pretty crashy on Windows).
[web]
style = gitweb
baseurl = /hg
allow_push = *
push_ssl = false
deny_push = *_external
deny_read = *_external
The best option you have is to setup a list with the usernames:
allow_push = user1, user2
deny_push = user3, user5
deny_read = user4
The problem with your syntax is that, you are first allowing push for everybody and then trying to limit the users.
mercurial-server can do this for you. This means connecting to your repository over ssh rather than over http, and authenticating using ssh keypairs, but in my experience that's far more convenient anyway.

how do you make use of AclExtension and mercurial-server/hg-ssh?

mercurial-server manages user database under keys folder. Users and groups are represented by files and folders.
AclExtension relies on linux user group through ssh.
they don't seem to match. or did I miss something?
I have managed to make mercurial-server work. but just don't see how to integrate AclExtension with it so I may have finer grained access control.
Unfortunately, the AclExtension does key its access off of usernames. If you are creating separate UNIX user accounts for each using with hg-ssh you've got everything you need, but if all of your ssh users are using the same Unix user account then the AclExtension isn't going to work for you.
Unless...
I did just look into the acl.py file and it looks like it uses the getpass.py module's getuser which checks the environment for the user name using this code:
for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
user = os.environ.get(name)
if user:
return user
so it might be possible to fake that out by setting an environment variable in the hg-ssh user's authorized_keys file like this:
command="hg-ssh path/to/repo" environment="LOGNAME=fakeusername" ssh-dss ...
where then you could put fakeusername in ACL rules, and could have a different fakeusername for each key, all running under the same UNIX account.
BTW: Everyone seems to just use hg-ssh alone, I never see the (non-official) mercurial-server app used anymore.
The environment trick doesn't seem to work on my Solaris box; my solution was to pass in the fakeusername as a parameter to hg-ssh and have that set os.environ['LOGNAME'] so that getpass sees it.
command="hg-ssh fakeusername" ssh-dss ...