git-shell-verify: only check read-only mode for receive-pack
[girocco.git] / cgi / edituser.cgi
blobd738570b416fd49e80cca81c99bfb0da59a16fe7
1 #!/usr/bin/perl
2 # (c) Petr Baudis <pasky@suse.cz>
3 # (c) Jan Krueger <jk@jk.gs>
4 # GPLv2
6 use strict;
7 use warnings;
9 use lib "__BASEDIR__";
10 use Girocco::CGI;
11 use Girocco::Config;
12 use Girocco::User;
13 use Girocco::Util;
15 my $gcgi = Girocco::CGI->new('User Email & SSH Key Update');
16 my $cgi = $gcgi->cgi;
18 unless ($Girocco::Config::manage_users) {
19 print "<p>I don't manage users.</p>";
20 exit;
23 if ($cgi->param('mail')) {
24 print "<p>Go away, bot.</p>";
25 exit;
28 if (my $romsg=check_readonly(1)) {
29 print "<p>$romsg</p>\n";
30 exit;
33 sub _auth_form {
34 my $name = shift;
35 my $submit = shift;
36 my $fields = shift;
37 $fields = '' if (!$fields);
38 my $auth = shift;
39 my $authtag = ($auth ? qq(<input type="hidden" name="auth" value="$auth" />) :
40 qq(<p>Authorization code: <input name="auth" size="50" /></p>));
41 print <<EOT;
43 <form method="post" action="@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi">
44 <input type="hidden" name="name" value="$name" />
45 $authtag
46 $fields<p><input type="submit" name="y0" value="$submit" /></p>
47 </form>
48 EOT
51 my $savefail = 0;
52 my $y0 = $cgi->param('y0') || '';
53 if ($cgi->param('name') && $y0 && $cgi->request_method eq 'POST') {
54 # submitted, let's see
55 # FIXME: racy, do a lock
56 my $name = $gcgi->wparam('name');
57 Girocco::User::does_exist($name, 1)
58 or $gcgi->err("Username is not registered.");
60 $gcgi->err_check and exit;
62 my $user;
63 ($user = Girocco::User->load($name)) && valid_email($user->{email})
64 or $gcgi->err("Username may not be updated.");
66 $gcgi->err_check and exit;
68 if (!$cgi->param('auth')) {
69 if ($y0 ne 'Send authorization code') {
70 print "<p>Invalid data. Go away, sorcerer.</p>\n";
71 exit;
74 valid_email($user->{email}) or die "Sorry, this user cannot be changed.";
76 my $auth = $user->gen_auth;
78 # Send auth mail
79 defined(my $MAIL = mailer_pipe '-s', "[$Girocco::Config::name] Account update authorization", $user->{email}) or
80 die "Sorry, could not send authorization code: $!";
81 print $MAIL <<EOT;
82 Hello,
84 You have requested an authorization code to be sent to you for updating
85 your account's email and/or SSH keys. If you don't want to actually update
86 your email or SSH keys, just ignore this e-mail. Otherwise, use this code
87 within 24 hours:
89 $auth
91 Should you run into any problems, please let us know.
93 Have fun!
94 EOT
95 close $MAIL;
97 print "<p>You should shortly receive an e-mail containing an authorization code.
98 Please enter this code below to update your SSH keys.
99 The code will expire in 24 hours or after you have used it.</p>";
100 _auth_form($name, "'Login'");
101 exit;
102 } else {
103 $user->{auth} && $user->{authtype} ne 'DEL' or do {
104 print "<p>There currently isn't any authorization code filed under your account. ".
105 "Please <a href=\"@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi\">generate one</a>.</p>";
106 exit;
109 my $fields = '';
110 my $email = $cgi->param('email');
111 my $keys = $cgi->param('keys');
113 my $auth = $gcgi->wparam('auth');
114 if ($auth ne $user->{auth}) {
115 print "<p>Invalid authorization code, please re-enter or ".
116 "<a href=\"@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi\">generate a new one</a>.</p>";
117 _auth_form($name, "'Login'");
118 exit;
121 if (defined($email) && defined($keys)) {
122 if ($y0 ne 'Update') {
123 print "<p>Invalid data. Go away, sorcerer.</p>\n";
124 exit;
127 # Auth valid, keys given -> save
128 if (($email eq $user->{email} || $user->update_email($gcgi, $email)) && $user->keys_fill($gcgi)) {
129 $user->del_auth;
130 $user->keys_save;
131 print "<p>Your Email &amp; SSH keys have been updated.</p>";
132 my $keylist = $user->keys_html_list;
133 if ($keylist) {
134 print <<EOT;
136 <div id="keys"><p>The following keys have been registered for user $name as
137 shown below along with their <tt>ssh-keygen -l -E md5</tt> fingerprint:</p>
138 $keylist</div>
141 exit;
143 $y0 = "'Login'";
144 $savefail = 1;
145 } else {
146 # Otherwise pre-fill fields
147 $email = $user->{email};
148 $keys = $user->{keys}."\n";
151 if ($y0 ne "'Login'") {
152 print "<p>Invalid data. Go away, sorcerer.</p>\n";
153 exit;
156 my $httpspara = '';
157 $httpspara = <<EOT if $Girocco::Config::httpspushurl;
158 <p>Please be sure to include at least one RSA key (starts with the <tt>ssh-rsa</tt> prefix) in
159 order to enable HTTPS pushing. <sup class="sup"><span><a href="@{[url_path($Girocco::Config::htmlurl)]}/httpspush.html">(learn more)</a></span></sup><br />
160 An X.509 (e.g. OpenSSL) format public key can be converted to SSH .pub format with the
161 <a href="http://repo.or.cz/w/ezcert.git/blob/master:/ConvertPubKey">ConvertPubKey</a> utility thus obviating the
162 need for OpenSSH if all pushing is to be done using HTTPS (see the example in the TIPS section of the <tt>ConvertPubKey -h</tt> output).</p>
164 my $emailval = CGI::escapeHTML($email);
165 my $keysval = CGI::escapeHTML($keys);
166 my $blurb = '';
167 $blurb = 'SSH (the <tt>ssh</tt> protocol)'
168 if $Girocco::Config::pushurl && !$Girocco::Config::httpspushurl;
169 $blurb = 'HTTPS (the <tt>https</tt> protocol)'
170 if !$Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
171 $blurb = 'SSH (the <tt>ssh</tt> protocol) or HTTPS (the <tt>https</tt> protocol)'
172 if $Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
173 my $dsablurb = '';
174 $dsablurb = ' or <tt>~/.ssh/id_dsa.pub</tt>' unless $Girocco::Config::disable_dsa;
175 print <<EOT;
176 <p>Authorization code validated (for now).</p>
177 <p>$blurb is used for pushing, your SSH key authenticates you -
178 there is no password (though we recommend that your SSH key is password-protected;
179 use <code>ssh-agent</code> to help your fingers).
180 You can find your public key in <tt>~/.ssh/id_rsa.pub</tt>$dsablurb.
181 If you do not have any yet, generate it using the <code>ssh-keygen</code> command.</p>
182 <p>You can paste multiple keys in the box below, each on a separate line.
183 Paste each key <em>including</em> the <tt>ssh-</tt>whatever prefix and email-like postfix.</p>
184 $httpspara<form method="post" action="@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi">
185 <input type="hidden" name="name" value="$name" />
186 <input type="hidden" name="auth" value="$auth" />
187 <table class="form">
188 <tr><td class="formlabel">Login:</td><td class="formdata">$name</td></tr>
189 <tr><td class="formlabel">Email:</td><td><input type="text" name="email" value="$emailval"/></td></tr>
190 <tr><td class="formlabel">Public SSH key(s):</td><td><textarea wrap="off" name="keys" rows="5" cols="80">$keysval</textarea></td></tr>
191 <tr><td class="formlabel"></td><td><input type="submit" name="y0" value="Update" /></td></tr>
192 </table>
194 my $keylist = $savefail ? '' : $user->keys_html_list;
195 if ($keylist) {
196 print <<EOT;
198 <div id="keys"><p>The following keys are currently registered for user $name as
199 shown below along with their <tt>ssh-keygen -l -E md5</tt> fingerprint:</p>
200 $keylist</div>
203 exit;
208 my $blurb1 = '';
209 $blurb1 = 'SSH (the <tt>ssh</tt> protocol)'
210 if $Girocco::Config::pushurl && !$Girocco::Config::httpspushurl;
211 $blurb1 = 'HTTPS (the <tt>https</tt> protocol)'
212 if !$Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
213 $blurb1 = 'SSH (the <tt>ssh</tt> protocol) or HTTPS (the <tt>https</tt> protocol)'
214 if $Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
215 my $blurb2 = '';
216 $blurb2 = ' and download https push user authentication certificate(s)'
217 if $Girocco::Config::httpspushurl;
218 my $dsablurb = '';
219 $dsablurb = ' or <tt>~/.ssh/id_dsa.pub</tt>' unless $Girocco::Config::disable_dsa;
220 print <<EOT;
221 <p>Here you may update the email and public SSH key(s) associated with your user account$blurb2.
222 You may <a href="@{[url_path($Girocco::Config::webadmurl)]}/deluser.cgi">request an authorization
223 code in order to remove your user account from this site</a>.</p>
224 <p>If you do not already have a user account you may
225 <a href="@{[url_path($Girocco::Config::webadmurl)]}/reguser.cgi">register user</a> instead.</p>
226 <p>The public SSH key(s) are required for you to push to projects.
227 $blurb1 is used for pushing, your SSH key authenticates you -
228 there is no password (though we recommend that your SSH key is password-protected;
229 use <code>ssh-agent</code> to help your fingers).
230 You can find your public key in <tt>~/.ssh/id_rsa.pub</tt>$dsablurb.
231 If you do not have any yet, generate it using the <code>ssh-keygen</code> command.</p>
233 <p>Please enter your username below;
234 we will send you an email with an authorization code
235 and further instructions.</p>
237 <form method="post" action="@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi">
238 <table class="form">
239 <tr><td class="formlabel">Login:</td><td><input type="text" name="name" /></td></tr>
240 <tr style="display:none"><td class="formlabel">Anti-captcha (leave empty!):</td><td><input type="text" name="mail" /></td></tr>
241 <tr><td class="formlabel"></td><td><input type="submit" name="y0" value="Send authorization code" /></td></tr>
242 </table>
243 </form>