indextext.html: update notice about ssh host key change
[girocco.git] / cgi / editproj.cgi
blobcb0ccaec0ff1de6914aa1418239fba7c0ac6b0aa
1 #!/usr/bin/perl
2 # (c) Petr Baudis <pasky@suse.cz>
3 # GPLv2
5 use strict;
6 use warnings;
8 use lib "__BASEDIR__";
9 use Girocco::CGI;
10 use Girocco::Config;
11 use Girocco::Project;
12 use Girocco::Util;
13 use POSIX qw(strftime);
15 my $script = <<'EOT';
16 <script type="text/javascript">
17 // <![CDATA[
18 function adduseritem(elem)
20 var inp = document.createElement('input');
21 inp.type = 'text';
22 inp.name = 'user';
23 var li = document.createElement('li');
24 li.appendChild(document.createTextNode('Add user: '));
25 li.appendChild(inp);
26 elem.parentNode.insertBefore(li, elem);
28 // ]]>
29 </script>
30 EOT
31 my $gcgi = Girocco::CGI->new('Project Settings', undef, $script);
32 my $cgi = $gcgi->cgi;
34 my $name = $cgi->param('name');
35 $name =~ s#\.git$## if $name; #
37 unless (defined $name) {
38 print "<p>I need the project name as an argument now.</p>\n";
39 exit;
42 if (!Girocco::Project::does_exist($name,1) && !Girocco::Project::valid_name($name)) {
43 print "<p>Invalid project name. Go away, sorcerer.</p>\n";
44 exit;
47 if (!Girocco::Project::does_exist($name,1)) {
48 print "<p>Sorry but the project $name does not exist. Now, how did you <em>get</em> here?!</p>\n";
49 exit;
52 if (my $romsg=check_readonly(1)) {
53 print "<p>$romsg</p>\n";
54 exit;
57 my $proj = Girocco::Project->load($name);
58 if (!$proj) {
59 print "<p>not found project $name, that's really weird!</p>\n";
60 exit;
62 push(@Girocco::Config::project_fields, "notifycia")
63 if $proj->{notifycia} && !grep(/notifycia/, @Girocco::Config::project_fields);
64 my $escname = $name;
65 $escname =~ s/[+]/%2B/g;
67 my $tzoffset = $cgi->param('tzoffset') || 0;
68 $tzoffset =~ /^[-+]?\d{1,5}$/ or $tzoffset = 0;
69 $tzoffset = 0 + $tzoffset;
70 $tzoffset >= -43200 && $tzoffset <= 43200 or $tzoffset = 0;
72 sub format_epoch_ts {
73 my $es = shift;
74 defined($es) or $es = time();
75 $es += $tzoffset;
76 my $str = strftime("%Y-%m-%d %H:%M:%S ", (gmtime($es))[0..5], -1, -1, -1);
77 if ($tzoffset) {
78 my $moff = int(abs($tzoffset) / 60);
79 $str .= sprintf("%s%02d%02d",
80 ($tzoffset >= 0 ? "+" : "-"),
81 int($moff / 60),
82 $moff - 60 * int($moff / 60));
83 } else {
84 $str .= "UTC";
86 return $str;
89 my $y0 = $cgi->param('y0') || '';
90 my $tok = $cgi->param('token') || '';
91 my $protok = 0;
92 if (($y0 eq 'Update' || $y0 eq 'View All' || $y0 eq 'Restart Mirroring') && $cgi->request_method eq 'POST') {{
93 my $ts = "<span class=\"timestamp\">" . format_epoch_ts() . "</span>";
94 $gcgi->err_prelude("<p class=\"failed\">Project update failed at $ts.</p>\n") unless $y0 eq 'View All';
95 # Check for token validity
96 if (!check_timed_token($tok, "projedit", $proj->{name}, $Girocco::Config::project_edit_timeout)) {
97 $gcgi->err("Session has timed out or is invalid, please try again.");
99 # submitted, let's see
100 my $fillok = $proj->cgi_fill($gcgi, 1);
101 my $authok = $proj->authenticate($gcgi);
102 $authok and $protok = 1;
103 $y0 eq 'View All' and last;
104 if (!$gcgi->err_check && $authok) {
105 $proj->update or last;
106 print "<p class=\"updated\">Project successfully updated at $ts.</p>\n";
107 if ($proj->{clone_failed}) {
108 $proj->clone;
109 print "<p>Please <a href=\"@{[url_path($Girocco::Config::webadmurl)]}".
110 "/mirrorproj.cgi?name=$escname\">pass onwards</a>.</p>\n";
111 print "<script language=\"javascript\">document.location=".
112 "'@{[url_path($Girocco::Config::webadmurl)]}/mirrorproj.cgi?name=$escname'</script>\n";
113 exit;
118 # $proj may be insane now but that's actually good for us since we'll let the
119 # user fix the invalid values he or she entered
120 my %h = $proj->form_defaults;
122 print <<EOT;
123 <p>Here you may adjust the settings of project $h{name}. Go wild.
125 if ($proj->{mirror}) {
126 print <<EOT;
127 Since this is a mirrored project, you may opt to remove it from the site as well.
128 Just <a href="@{[url_path($Girocco::Config::webadmurl)]}/delproj.cgi?name=$escname">remove it</a>.</p>
130 } else {
131 if ($proj->is_empty) {
132 print <<EOT;
133 Since this is an empty project, you may opt to remove it from the site as well.
134 Just <a href="@{[url_path($Girocco::Config::webadmurl)]}/delproj.cgi?name=$escname">remove it</a>.</p>
136 } else {
137 print <<EOT;
138 You may
139 <a href="@{[url_path($Girocco::Config::webadmurl)]}/delproj.cgi?name=$escname">request an authorization code</a> in order
140 to remove this project from the site.</p>
143 print <<EOT;
144 <p>Use the <b>+</b> button to enable access for more than a single user at a time.</p>
148 my $button_label = $proj->{clone_failed} ? 'Restart Mirroring' : 'Update';
149 my $showstatusopt = $proj->{mirror} && !$proj->{clone_failed} && !$proj->{clone_in_progress};
150 my $statuschecked = $proj->{statusupdates} ? 'checked="checked"' : '';
151 my $tokauth = get_token_field("projedit", $h{name}, $Girocco::Config::project_edit_timeout);
152 $tokauth and $tokauth = "\n".$tokauth;
154 print <<EOT;
155 <form method="post" action="@{[url_path($Girocco::Config::webadmurl)]}/editproj.cgi">$tokauth
156 <input type="hidden" name="tzoffset" value="0" />
157 <table class="form">
158 <tr><td class="formlabel">Project name:</td><td class="formdata"><a
159 href="@{[url_path($Girocco::Config::gitweburl)]}/$h{name}.git">$h{name}</a>.git
160 <input type="hidden" name="name" value="$h{name}" /></td></tr>
162 if ($Girocco::Config::project_passwords) {
163 my $vab = '';
164 $protok || !%{$Girocco::Config::protect_fields} or
165 $vab = '&#160;&#160;<input type="submit" name="y0" value="View All" />';
166 print <<EOT;
167 <tr><td class="formlabel"><strong>Admin password:</strong></td><td>
168 <input type="password" name="cpwd" /> <sup class="sup"><span><a
169 href="@{[url_path($Girocco::Config::webadmurl)]}/pwproj.cgi?name=$escname"
170 class="ctxaction">(forgot password?)</a></span></sup>$vab</td></tr>
171 <tr><td class="formlabel">New admin password (twice):<br />
172 <em>(leave empty to keep it the same)</em></td><td>
173 <input type="password" name="pwd" /><br /><input type="password" name="pwd2" /><br />
174 </td></tr>
177 if ($Girocco::Config::project_owners eq 'email') {
178 print <<EOT;
179 <tr><td class="formlabel">E-mail contact:</td><td><input type="text" name="email" value="$h{email}" /></td></tr>
183 if ($proj->{mirror}) {
184 print "<tr><td class=\"formlabel\">Repository URL:</td><td><input type=\"text\" name=\"url\" value=\"$h{url}\" /></td></tr>\n";
185 print '<tr><td class="formlabel">Mirror refs:</td><td class="formdatatd">'.
186 '<label title="Unchecking this will mirror the entire refs namespace which is usually unnecessary. '.
187 'Non-git sources always mirror the entire refs namespace regardless of this setting.">'.
188 '<input type="checkbox" name="cleanmirror" value="1" '.($h{'cleanmirror'} ? 'checked="checked" ' : '').
189 'style="vertical-align:middle" /><span style="vertical-align:middle; margin-left:0.5ex">'.
190 'Only mirror <code>refs/heads/*</code>, <code>refs/tags/*</code> and <code>refs/notes/*</code></span></label></td></tr>'."\n"
191 if grep(/cleanmirror/, @Girocco::Config::project_fields);
192 } else {
193 print <<EOT;
194 <tr><td class="formlabel" style="vertical-align:middle">Users:</td><td>
195 <ul>
197 $Girocco::Config::manage_users and print "<p>Only <a href=\"".
198 "@{[url_path($Girocco::Config::webadmurl)]}/reguser.cgi\">registered users</a> may push.</p>";
199 if ($Girocco::Config::mob and not grep { $_ eq $Girocco::Config::mob } @{$h{users}}) {
200 print "<p><em>(Please consider adding the <tt>$Girocco::Config::mob</tt> user.\n";
201 print "<sup class=\"sup\"><span><a href=\"@{[url_path($Girocco::Config::htmlurl)]}/mob.html\">(learn more)</a></span></sup>)\n";
202 print "</em></p>\n";
204 foreach my $user (@{$h{users}}) {
205 my $mlm = '';
206 $mlm = " <sup class=\"sup\"><span><a href=\"@{[url_path($Girocco::Config::htmlurl)]}/mob.html\">(learn more)</a></span></sup>"
207 if $Girocco::Config::mob && $user eq $Girocco::Config::mob;
208 print "<li><input type=\"checkbox\" name=\"user\" value=\"$user\" checked=\"1\" /> $user$mlm</li>\n";
210 print <<EOT;
211 <li>Add user: <input type="text" name="user" /></li>
212 <button type="button" onclick="adduseritem(this)"><b>+</b></button>
213 </ul>
214 </td></tr>
218 print '<tr><td class="formlabel">Default branch:</td><td class="formdatatd"><select size="1" name="HEAD">';
219 for ($proj->get_heads) {
220 my $selected = $proj->{HEAD} eq $_ ? ' selected="selected"' : '';
221 print "<option$selected>".Girocco::CGI::html_esc($_)."</option>";
223 print '</select></td></tr>
226 print '<tr><td class="formlabel">Tags (select to delete):</td><td>';
227 print '<select size="6" name="tags" multiple="multiple">';
228 for ($proj->get_ctag_names) {
229 print '<option>'.Girocco::CGI::html_esc($_).'</option>';
231 print '</select></td></tr>
235 $gcgi->print_form_fields($Girocco::Project::metadata_fields,
236 $protok?{}:$Girocco::Config::protect_fields,
237 \%h, @Girocco::Config::project_fields);
238 print <<EOT if $showstatusopt;
239 <tr><td class="formlabel">Enable status update emails:</td>
240 <td class="formdatatd"
241 ><input type="hidden" name="setstatusupdates" value="1"
242 /><input type="checkbox" name="statusupdates" value="1" $statuschecked /></td></tr>
244 print <<EOT;
245 <tr><td class="formlabel"></td><td><input type="submit" name="y0" value="$button_label" /></td></tr>
246 </table>
247 </form>
248 <script type="text/javascript">
249 // <![CDATA[
250 (function () {
251 var tzoffset = (new Date).getTimezoneOffset() * -60;
252 var form0 = document.forms[0];
253 if (form0 && form0.tzoffset) {
254 form0.tzoffset.value = tzoffset;
256 })();
257 // ]]>
258 </script>