Stay inside the current URL scheme
[girocco.git] / cgi / edituser.cgi
blob443dd007276df703ab198ea4c6bc7cd51771bb8e
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 ".";
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 sub _auth_form {
29 my $name = shift;
30 my $submit = shift;
31 my $fields = shift;
32 $fields = '' if (!$fields);
33 my $auth = shift;
34 my $authtag = ($auth ? qq(<input type="hidden" name="auth" value="$auth" />) :
35 qq(<p>Authorization code: <input name="auth" size="40" /></p>));
36 print <<EOT;
38 <form method="post">
39 <input type="hidden" name="name" value="$name" />
40 $authtag
41 $fields<p><input type="submit" value="$submit" /></p>
42 </form>
43 EOT
46 if ($cgi->param('name')) {
47 # submitted, let's see
48 # FIXME: racy, do a lock
49 my $name = $gcgi->wparam('name');
50 (Girocco::User::valid_name($name)
51 and Girocco::User::does_exist($name))
52 or $gcgi->err("Username is not registered.");
54 $gcgi->err_check and exit;
56 my $user;
57 ($user = Girocco::User->load($name)) && valid_email($user->{email})
58 or $gcgi->err("Username may not be updated.");
60 $gcgi->err_check and exit;
62 if (!$cgi->param('auth')) {
63 my $auth = $user->gen_auth;
65 # Send auth mail
66 open(MAIL, '|-', '/usr/bin/mail', '-s', "[$Girocco::Config::name] Account update authorization", $user->{email}) or
67 die "Sorry, could not send authorization code: $!";
68 print MAIL <<EOT;
69 Hello,
71 you have requested an authorization code to be sent to you for updating
72 your account's email and/or SSH keys. If you don't want to actually update
73 your email or SSH keys, just ignore this e-mail. Otherwise, use this code
74 within 24 hours:
76 $auth
78 Should you run into any problems, please let us know.
80 Have fun!
81 EOT
82 close MAIL;
84 print "<p>You should shortly receive an e-mail containing an authorization code.
85 Please enter this code below to update your SSH keys.
86 The code will expire in 24 hours or after you have used it.</p>";
87 _auth_form($name, "'Login'");
88 exit;
89 } else {
90 $user->{auth} && $user->{authtype} ne 'DEL' or do {
91 print "There currently isn't any authorization code filed under your account. ".
92 "Please <a href=\"@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi\">generate one</a>.";
93 exit;
96 my $fields = '';
97 my $email = $cgi->param('email');
98 my $keys = $cgi->param('keys');
100 my $auth = $gcgi->wparam('auth');
101 if ($auth ne $user->{auth}) {
102 print '<p>Invalid authorization code, please re-enter or ".
103 "<a href="@{[url_path($Girocco::Config::webadmurl)]}/edituser.cgi">generate a new one</a>.</p>';
104 _auth_form($name, "'Login'");
105 exit;
108 if (defined($email) && defined($keys)) {
109 # Auth valid, keys given -> save
110 if (($email eq $user->{email} || $user->update_email($gcgi, $email)) && $user->keys_fill($gcgi)) {
111 $user->del_auth;
112 $user->keys_save;
113 print "<p>Your Email &amp; SSH keys have been updated.</p>";
114 my $keylist = $user->keys_html_list;
115 if ($keylist) {
116 print <<EOT;
118 <div id="keys"><p>The following keys have been registered for user $name as
119 shown below along with their <tt>ssh-keygen -l</tt> fingerprint:</p>
120 $keylist</div>
123 exit;
125 } else {
126 # Otherwise pre-fill fields
127 $email = $user->{email};
128 $keys = $user->{keys};
131 my $httpspara = '';
132 $httpspara = <<EOT if $Girocco::Config::httpspushurl;
133 <p>Please be sure to include at least one RSA key (starts with the <tt>ssh-rsa</tt> prefix) in
134 order to enable HTTPS pushing. <sup><a href="@{[url_path($Girocco::Config::htmlurl)]}/httpspush.html">(learn more)</a></sup><br />
135 X.509 (e.g. OpenSSL) format public keys can be converted to SSH .pub format with the
136 <a href="http://repo.or.cz/w/ezcert.git/blob/master:/ConvertPubKey">ConvertPubKey</a> utility thus obviating the
137 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>
139 my $emailval = CGI::escapeHTML($email);
140 my $keysval = CGI::escapeHTML($keys);
141 print <<EOT;
142 <p>Authorization code validated (for now).</p>
143 <p>SSH (the <tt>ssh</tt> protocol) or HTTPS is used for pushing, your SSH key authenticates you -
144 there is no password (though we recommend that your SSH key is password-protected;
145 use <code>ssh-agent</code> to help your fingers).
146 You can find your public key in <tt>~/.ssh/id_rsa.pub</tt> or <tt>~/.ssh/id_dsa.pub</tt>.
147 If you do not have any yet, generate it using the <code>ssh-keygen</code> command.</p>
148 <p>You can paste multiple keys in the box below, each on a separate line.
149 Paste each key <em>including</em> the <tt>ssh-</tt>whatever prefix and email-like postfix.</p>
150 $httpspara<form method="post">
151 <input type="hidden" name="name" value="$name" />
152 <input type="hidden" name="auth" value="$auth" />
153 <table class="form">
154 <tr><td class="formlabel">Login:</td><td class="formdata">$name</td></tr>
155 <tr><td class="formlabel">Email:</td><td><input type="text" name="email" value="$emailval"/></td></tr>
156 <tr><td class="formlabel">Public SSH key(s):</td><td><textarea wrap="off" name="keys" rows="5" cols="80">$keysval</textarea></td></tr>
157 <tr><td class="formlabel"></td><td><input type="submit" value="Update" /></td></tr>
158 </table>
160 my $keylist = $user->keys_html_list;
161 if ($keylist) {
162 print <<EOT;
164 <div id="keys"><p>The following keys are currently registered for user $name as
165 shown below along with their <tt>ssh-keygen -l</tt> fingerprint:</p>
166 $keylist</div>
169 exit;
174 my $blurb1 = '';
175 $blurb1 = 'SSH (the <tt>ssh</tt> protocol)'
176 if $Girocco::Config::pushurl && !$Girocco::Config::httpspushurl;
177 $blurb1 = 'HTTPS (the <tt>https</tt> protocol)'
178 if !$Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
179 $blurb1 = 'SSH (the <tt>ssh</tt> protocol) or HTTPS (the <tt>https</tt> protocol)'
180 if $Girocco::Config::pushurl && $Girocco::Config::httpspushurl;
181 my $blurb2 = '';
182 $blurb2 = ' and download https push user authentication certificate(s)'
183 if $Girocco::Config::httpspushurl;
184 print <<EOT;
185 <p>Here you can update the email and public SSH key(s) associated with your user account$blurb2.
186 These public SSH key(s) are required for you to push to projects.</p>
187 <p>$blurb1 is used for pushing, your SSH key authenticates you -
188 there is no password (though we recommend that your SSH key is password-protected;
189 use <code>ssh-agent</code> to help your fingers).
190 You can find your public key in <tt>~/.ssh/id_rsa.pub</tt> or <tt>~/.ssh/id_dsa.pub</tt>.
191 If you do not have any yet, generate it using the <code>ssh-keygen</code> command.</p>
193 <p>Please enter your username below;
194 we will send you an email with an authorization code
195 and further instructions.</p>
197 <form method="post">
198 <table class="form">
199 <tr><td class="formlabel">Login:</td><td><input type="text" name="name" /></td></tr>
200 <tr style="display:none"><td class="formlabel">Anti-captcha (leave empty!):</td><td><input type="text" name="mail" /></td></tr>
201 <tr><td class="formlabel"></td><td><input type="submit" value="Send authorization code" /></td></tr>
202 </table>
203 </form>