File Makefile.in changed (mode: 100644) (index 310b5f5..5d69a2d) |
... |
... |
install: all |
16 |
16 |
@mkdir -p $(I_ETC)/xinetd.d |
@mkdir -p $(I_ETC)/xinetd.d |
17 |
17 |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/rocketgit |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/rocketgit |
18 |
18 |
@mkdir -p $(I_ETC)/cron.d |
@mkdir -p $(I_ETC)/cron.d |
19 |
|
cp -vd --no-clobber samples/cron $(I_ETC)/cron.d/rocketgit |
|
|
19 |
|
cp -vd samples/cron $(I_ETC)/cron.d/rocketgit |
20 |
20 |
@mkdir -p $(I_ETC)/httpd/conf.d |
@mkdir -p $(I_ETC)/httpd/conf.d |
21 |
21 |
cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/rocketgit.conf |
cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/rocketgit.conf |
22 |
22 |
@mkdir -p $(I_ETC)/rocketgit |
@mkdir -p $(I_ETC)/rocketgit |
|
... |
... |
install: all |
24 |
24 |
cp -vd samples/config.php $(I_ETC)/rocketgit/config.php.sample |
cp -vd samples/config.php $(I_ETC)/rocketgit/config.php.sample |
25 |
25 |
@mkdir -p $(I_ETC)/logrotate.d |
@mkdir -p $(I_ETC)/logrotate.d |
26 |
26 |
cp -vd --no-clobber samples/logrotate $(I_ETC)/logrotate.d/rocketgit |
cp -vd --no-clobber samples/logrotate $(I_ETC)/logrotate.d/rocketgit |
27 |
|
@mkdir -p $(I_VAR_LOG)/$(PRJ) |
|
28 |
|
@-chown rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
|
|
27 |
|
@mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ) |
|
28 |
|
@chown rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
29 |
29 |
@chmod 0700 $(I_VAR_LOG)/$(PRJ) |
@chmod 0700 $(I_VAR_LOG)/$(PRJ) |
30 |
|
@mkdir -p $(I_VAR_LOG)/$(PRJ)-web |
|
31 |
|
@-chown apache:apache $(I_VAR_LOG)/$(PRJ)-web |
|
32 |
|
@chmod 0700 $(I_VAR_LOG)/$(PRJ)-web |
|
33 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ) $(I_VAR_LIB)/$(PRJ)/locks $(I_VAR_LIB)/$(PRJ)/repos $(I_VAR_LIB)/$(PRJ)/q_merge_requests |
|
34 |
|
@-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
|
|
30 |
|
@mkdir -p --mode=0700 $(I_VAR_LOG)/$(PRJ)-web |
|
31 |
|
@chown apache:apache $(I_VAR_LOG)/$(PRJ)-web |
|
32 |
|
@mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ) |
|
33 |
|
@mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/locks |
|
34 |
|
@mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/repos |
|
35 |
|
@mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/q_merge_requests |
|
36 |
|
@mkdir -p --mode=0700 $(I_VAR_LIB)/$(PRJ)/qstats |
|
37 |
|
@mkdir -p --mode=0755 $(I_VAR_LIB)/$(PRJ)/sockets |
|
38 |
|
@chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
File TODO changed (mode: 100644) (index 294792c..246d7d6) |
1 |
1 |
== BEFORE FIRST RELEASE! == |
== BEFORE FIRST RELEASE! == |
|
2 |
|
[ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu) |
|
3 |
|
[ ] Checking mtime of event.php is not enough. Maybe checking version. |
|
4 |
|
Think of includes that may change. |
|
5 |
|
[ ] Create a unique index on users(username,organization)? |
|
6 |
|
[ ] Do not allow duplicated ssh keys. |
|
7 |
|
[ ] We have a little problem: we need the ssh keyring to regenerate fast but |
|
8 |
|
we may have a big events queue. We may want to signal directly |
|
9 |
|
the regeneration script and to not store mark-dirty state. Hm. |
|
10 |
|
[ ] Optimize keyring invalidation. |
|
11 |
|
[ ] Put "create user" on login page! |
|
12 |
|
[ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT. |
|
13 |
|
[ ] What happens if we unlock an unlocked resource. |
|
14 |
|
[ ] Renaming a repo! |
|
15 |
|
If we move to numbers, and the names are links, we may have problems |
|
16 |
|
when we create a repo with the same name. |
|
17 |
|
If we just rename the folder, the current/future clients could not |
|
18 |
|
access the repo. Maybe this is the best idea. If a user creates a |
|
19 |
|
repo with the same name, this is life. |
|
20 |
|
We have to record the renaming in the repo history. |
|
21 |
|
[ ] What happends if a user is doing a downgrade? Must not allow it. |
|
22 |
|
[ ] Use another home page for logged in users. |
2 |
23 |
[ ] Check if same user can create two repos with the same name! |
[ ] Check if same user can create two repos with the same name! |
3 |
24 |
[ ] When we are altering keys table and we upgrade, the file will not be rebuilt. |
[ ] When we are altering keys table and we upgrade, the file will not be rebuilt. |
4 |
25 |
We have to dirty it. |
We have to dirty it. |
|
37 |
58 |
|
|
38 |
59 |
|
|
39 |
60 |
== Medium == |
== Medium == |
|
61 |
|
[ ] Add history also for user. |
|
62 |
|
[ ] template_table can deal with a FALSE para: load error.html file in list/ |
|
63 |
|
[ ] Put in history how many visitors received. |
|
64 |
|
Maybe only whn hitting some limits? |
|
65 |
|
[ ] Run shaX 1000 times for login? |
|
66 |
|
[ ] There is no back button in tree browsing. |
|
67 |
|
[ ] Allow users to have templates repo to be used when creating a new repo. |
|
68 |
|
Also define global templates. |
40 |
69 |
[ ] In logs we should log the version! |
[ ] In logs we should log the version! |
41 |
70 |
[ ] GeoIP |
[ ] GeoIP |
42 |
71 |
[ ] Specify a timeout for push/fetch. |
[ ] Specify a timeout for push/fetch. |
File inc/events.inc.php added (mode: 100644) (index 0000000..bc8f557) |
|
1 |
|
<?php |
|
2 |
|
// |
|
3 |
|
// This functions are used for background tasks: the tasks that the user should |
|
4 |
|
// not wait to happen in the browser: e-mails, keyring regeneration etc. |
|
5 |
|
// |
|
6 |
|
require_once($INC . "/util.inc.php"); |
|
7 |
|
require_once($INC . "/log.inc.php"); |
|
8 |
|
require_once($INC . "/sql.inc.php"); |
|
9 |
|
require_once($INC . "/prof.inc.php"); |
|
10 |
|
|
|
11 |
|
if (!isset($rg_event_socket)) |
|
12 |
|
$rg_event_socket = "/var/lib/rocketgit/sockets/event.sock"; |
|
13 |
|
|
|
14 |
|
$rg_event_error = ""; |
|
15 |
|
|
|
16 |
|
function rg_event_set_error($str) |
|
17 |
|
{ |
|
18 |
|
global $rg_event_error; |
|
19 |
|
$rg_event_error = $str; |
|
20 |
|
rg_log($str); |
|
21 |
|
} |
|
22 |
|
|
|
23 |
|
function rg_event_error() |
|
24 |
|
{ |
|
25 |
|
global $rg_event_error; |
|
26 |
|
return $rg_event_error; |
|
27 |
|
} |
|
28 |
|
|
|
29 |
|
$rg_event_split_functions = array(); |
|
30 |
|
|
|
31 |
|
/* |
|
32 |
|
* Register event functions. |
|
33 |
|
*/ |
|
34 |
|
function rg_event_register_functions($functions) |
|
35 |
|
{ |
|
36 |
|
global $rg_event_split_functions; |
|
37 |
|
|
|
38 |
|
if (empty($functions)) { |
|
39 |
|
rg_event_set_error("Cannot register empty array"); |
|
40 |
|
return FALSE; |
|
41 |
|
} |
|
42 |
|
|
|
43 |
|
foreach ($functions as $type => $function) |
|
44 |
|
$rg_event_split_functions[$type] = $function; |
|
45 |
|
|
|
46 |
|
return TRUE; |
|
47 |
|
} |
|
48 |
|
|
|
49 |
|
/* |
|
50 |
|
* Signals the daemon that there is some work to do |
|
51 |
|
*/ |
|
52 |
|
function rg_event_signal_daemon() |
|
53 |
|
{ |
|
54 |
|
global $rg_event_socket; |
|
55 |
|
|
|
56 |
|
$ret = FALSE; |
|
57 |
|
do { |
|
58 |
|
$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0); |
|
59 |
|
if ($socket === FALSE) { |
|
60 |
|
rg_log("Could not create socket!"); |
|
61 |
|
break; |
|
62 |
|
} |
|
63 |
|
|
|
64 |
|
$r = socket_connect($socket, $rg_event_socket); |
|
65 |
|
if ($r === FALSE) { |
|
66 |
|
rg_log("Could not connect the socket!"); |
|
67 |
|
break; |
|
68 |
|
} |
|
69 |
|
|
|
70 |
|
$buf = "W"; $len = strlen($buf); |
|
71 |
|
$r = socket_send($socket, $buf, $len, 0); |
|
72 |
|
if ($r !== $len) { |
|
73 |
|
rg_log("Could not send!"); |
|
74 |
|
break; |
|
75 |
|
} |
|
76 |
|
|
|
77 |
|
socket_close($socket); |
|
78 |
|
$ret = TRUE; |
|
79 |
|
} while (0); |
|
80 |
|
|
|
81 |
|
return $ret; |
|
82 |
|
} |
|
83 |
|
|
|
84 |
|
/* |
|
85 |
|
* Inserts an event |
|
86 |
|
* This function is called from all over the place to generate events |
|
87 |
|
*/ |
|
88 |
|
function rg_event_add($db, $event) |
|
89 |
|
{ |
|
90 |
|
rg_prof_start("event_add"); |
|
91 |
|
rg_log("event_add: event=" . rg_array2string($event)); |
|
92 |
|
|
|
93 |
|
$ret = FALSE; |
|
94 |
|
do { |
|
95 |
|
$now = time(); |
|
96 |
|
$prio = $event['prio']; |
|
97 |
|
$e_data = rg_sql_escape($db, serialize($event)); |
|
98 |
|
$sql = "INSERT INTO events (itime, prio, data)" |
|
99 |
|
. " VALUES ($now, $prio, '$e_data')"; |
|
100 |
|
$res = rg_sql_query($db, $sql); |
|
101 |
|
if ($res === FALSE) { |
|
102 |
|
rg_event_set_error("Coulnd not add event (" . rg_sql_error() . ")"); |
|
103 |
|
break; |
|
104 |
|
} |
|
105 |
|
rg_sql_free_result($res); |
|
106 |
|
|
|
107 |
|
rg_event_signal_daemon(); |
|
108 |
|
|
|
109 |
|
$ret = TRUE; |
|
110 |
|
} while (0); |
|
111 |
|
|
|
112 |
|
rg_prof_end("event_add"); |
|
113 |
|
return $ret; |
|
114 |
|
} |
|
115 |
|
|
|
116 |
|
/* |
|
117 |
|
* Process an event |
|
118 |
|
*/ |
|
119 |
|
function rg_event_process($db, $event) |
|
120 |
|
{ |
|
121 |
|
global $rg_event_split_functions; |
|
122 |
|
|
|
123 |
|
rg_prof_start("event_process"); |
|
124 |
|
rg_log("event_process: event=" . rg_array2string($event)); |
|
125 |
|
|
|
126 |
|
$ret = FALSE; |
|
127 |
|
do { |
|
128 |
|
$category = $event['category']; |
|
129 |
|
unset($event['category']); |
|
130 |
|
|
|
131 |
|
if (!isset($rg_event_split_functions[$category])) { |
|
132 |
|
rg_event_set_error("Cannot find event function [$category]!"); |
|
133 |
|
rg_log("DEBUG: rg_event_split_functions=" . rg_array2string($rg_event_split_functions)); |
|
134 |
|
break; |
|
135 |
|
} |
|
136 |
|
|
|
137 |
|
$f = $rg_event_split_functions[$category]; |
|
138 |
|
rg_log("Calling $f..."); |
|
139 |
|
$evs = $f($db, $event); |
|
140 |
|
if ($evs === FALSE) { |
|
141 |
|
rg_event_set_error("Failed to fill event for category [$category]!"); |
|
142 |
|
break; |
|
143 |
|
} |
|
144 |
|
|
|
145 |
|
if (empty($evs)) { |
|
146 |
|
$ret = TRUE; |
|
147 |
|
break; |
|
148 |
|
} |
|
149 |
|
|
|
150 |
|
$r = TRUE; |
|
151 |
|
if (!is_array($evs)) |
|
152 |
|
rg_internal_error("evs is not array!"); |
|
153 |
|
foreach ($evs as $index => $ev) { |
|
154 |
|
$r = rg_event_add($db, $ev); |
|
155 |
|
if ($r !== TRUE) |
|
156 |
|
break; |
|
157 |
|
} |
|
158 |
|
if ($r !== TRUE) |
|
159 |
|
break; |
|
160 |
|
|
|
161 |
|
$ret = TRUE; |
|
162 |
|
} while (0); |
|
163 |
|
|
|
164 |
|
rg_prof_end("event_process"); |
|
165 |
|
return $ret; |
|
166 |
|
} |
|
167 |
|
|
|
168 |
|
/* |
|
169 |
|
* Process events queue |
|
170 |
|
* reset id to 1 if queue is empty? |
|
171 |
|
* Returns FALSE on error, else, the number of events processed |
|
172 |
|
*/ |
|
173 |
|
function rg_event_process_queue($db) |
|
174 |
|
{ |
|
175 |
|
rg_prof_start("event_process_queue"); |
|
176 |
|
rg_log("event_process_queue"); |
|
177 |
|
|
|
178 |
|
$ret = FALSE; |
|
179 |
|
$do_rollback = 0; |
|
180 |
|
do { |
|
181 |
|
$r = rg_sql_begin($db); |
|
182 |
|
if ($r !== TRUE) { |
|
183 |
|
rg_event_set_error("Cannot begin transaction" |
|
184 |
|
. " (" . rg_sql_error() . ")"); |
|
185 |
|
break; |
|
186 |
|
} |
|
187 |
|
$do_rollback = 1; |
|
188 |
|
|
|
189 |
|
// We limit to be able to deal with high prio tasks |
|
190 |
|
$sql = "SELECT * FROM events" |
|
191 |
|
. " ORDER BY prio, id" |
|
192 |
|
. " FOR UPDATE" |
|
193 |
|
. " LIMIT 100"; |
|
194 |
|
$res = rg_sql_query($db, $sql); |
|
195 |
|
$no_of_events = rg_sql_num_rows($res); |
|
196 |
|
if ($res === FALSE) { |
|
197 |
|
rg_event_set_error("Cannot load job list" |
|
198 |
|
. " (" . rg_sql_error() . ")"); |
|
199 |
|
break; |
|
200 |
|
} |
|
201 |
|
|
|
202 |
|
$r = TRUE; |
|
203 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
204 |
|
$ev = unserialize($row['data']); |
|
205 |
|
if ($ev === FALSE) { |
|
206 |
|
rg_internal_error("Cannot unserialize data"); |
|
207 |
|
exit(1); |
|
208 |
|
} |
|
209 |
|
$r = rg_event_process($db, $ev); |
|
210 |
|
if ($r !== TRUE) |
|
211 |
|
break; |
|
212 |
|
|
|
213 |
|
$sql = "DELETE FROM events WHERE id = " . $row['id']; |
|
214 |
|
$res2 = rg_sql_query($db, $sql); |
|
215 |
|
rg_sql_free_result($res2); |
|
216 |
|
} |
|
217 |
|
if ($r !== TRUE) |
|
218 |
|
break; |
|
219 |
|
rg_sql_free_result($res); |
|
220 |
|
|
|
221 |
|
$r = rg_sql_commit($db); |
|
222 |
|
if ($r !== TRUE) |
|
223 |
|
break; |
|
224 |
|
|
|
225 |
|
$ret = $no_of_events; |
|
226 |
|
$do_rollback = 0; |
|
227 |
|
} while (0); |
|
228 |
|
|
|
229 |
|
if ($do_rollback == 1) |
|
230 |
|
rg_sql_rollback($db); |
|
231 |
|
|
|
232 |
|
rg_prof_end("event_process_queue"); |
|
233 |
|
return $ret; |
|
234 |
|
} |
|
235 |
|
|
|
236 |
|
?> |
File inc/keys.inc.php changed (mode: 100644) (index f0d9e7b..d994d30) |
2 |
2 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
3 |
3 |
require_once($INC . "/state.inc.php"); |
require_once($INC . "/state.inc.php"); |
4 |
4 |
require_once($INC . "/prof.inc.php"); |
require_once($INC . "/prof.inc.php"); |
|
5 |
|
require_once($INC . "/events.inc.php"); |
5 |
6 |
|
|
6 |
7 |
$rg_keys_error = ""; |
$rg_keys_error = ""; |
7 |
8 |
|
|
8 |
9 |
function rg_keys_set_error($str) |
function rg_keys_set_error($str) |
9 |
10 |
{ |
{ |
10 |
11 |
global $rg_keys_error; |
global $rg_keys_error; |
11 |
|
|
|
12 |
12 |
$rg_keys_error = $str; |
$rg_keys_error = $str; |
13 |
13 |
} |
} |
14 |
14 |
|
|
|
... |
... |
function rg_keys_error() |
18 |
18 |
return $rg_keys_error; |
return $rg_keys_error; |
19 |
19 |
} |
} |
20 |
20 |
|
|
|
21 |
|
/* |
|
22 |
|
* Events functions |
|
23 |
|
*/ |
|
24 |
|
$rg_keys_functions = array( |
|
25 |
|
1000 => "rg_keys_event_new", |
|
26 |
|
1001 => "rg_keys_event_del", |
|
27 |
|
1002 => "rg_keys_event_mark_dirty", |
|
28 |
|
1003 => "rg_keys_event_notify_user" |
|
29 |
|
); |
|
30 |
|
rg_event_register_functions($rg_keys_functions); |
|
31 |
|
|
|
32 |
|
/* |
|
33 |
|
* Event for adding a new key |
|
34 |
|
*/ |
|
35 |
|
function rg_keys_event_new($db, $event) |
|
36 |
|
{ |
|
37 |
|
$ret = array(); |
|
38 |
|
|
|
39 |
|
$event['op'] = "new"; |
|
40 |
|
// mark keys dirty |
|
41 |
|
$ret[] = array_merge($event, array("category" => 1002, "prio" => 10)); |
|
42 |
|
// notify user |
|
43 |
|
$ret[] = array_merge($event, array("category" => 1003, "prio" => 100)); |
|
44 |
|
|
|
45 |
|
return $ret; |
|
46 |
|
} |
|
47 |
|
|
|
48 |
|
/* |
|
49 |
|
* Event for deleting a key |
|
50 |
|
*/ |
|
51 |
|
function rg_keys_event_del($db, $event) |
|
52 |
|
{ |
|
53 |
|
$ret = array(); |
|
54 |
|
$event['type'] = 1; |
|
55 |
|
$event['op'] = "del"; |
|
56 |
|
// mark keys dirty |
|
57 |
|
$ret[] = array_merge($event, array("category" => 1002, "prio" => 10)); |
|
58 |
|
// notify user |
|
59 |
|
$ret[] = array_merge($event, array("category" => 1003, "prio" => 100)); |
|
60 |
|
return $ret; |
|
61 |
|
} |
|
62 |
|
|
|
63 |
|
/* |
|
64 |
|
* Notify user that a new key was added/deleted to/from the keyring |
|
65 |
|
* TODO: Do not mark keys dirty from another place in this file |
|
66 |
|
*/ |
|
67 |
|
function rg_keys_event_mark_dirty($db, $event) |
|
68 |
|
{ |
|
69 |
|
$r = rg_keys_mark_dirty($db); |
|
70 |
|
if ($r === FALSE) |
|
71 |
|
return FALSE; |
|
72 |
|
|
|
73 |
|
return array(); |
|
74 |
|
} |
|
75 |
|
|
|
76 |
|
/* |
|
77 |
|
* Notify user that a new key was added to the keyring |
|
78 |
|
*/ |
|
79 |
|
function rg_keys_event_notify_user($db, $event) |
|
80 |
|
{ |
|
81 |
|
rg_prof_start("keys_event_notify_user"); |
|
82 |
|
rg_log("keys_event_notify_user: event=" . rg_array2string($event)); |
|
83 |
|
|
|
84 |
|
// TODO: load info about the keys and put the fingerprint in e-mail |
|
85 |
|
// TODO: Maybe put also the body in the e-mail, so it can be re-uploaded. |
|
86 |
|
// TODO: Maybe add also the statistics. |
|
87 |
|
|
|
88 |
|
$r = rg_mail("mail/user/key/" . $event['op'], $event); |
|
89 |
|
if ($r === FALSE) |
|
90 |
|
return FALSE; |
|
91 |
|
|
|
92 |
|
rg_prof_end("keys_event_notify_user"); |
|
93 |
|
return array(); |
|
94 |
|
} |
|
95 |
|
|
21 |
96 |
/* |
/* |
22 |
97 |
* Extracts info about a ssh key |
* Extracts info about a ssh key |
23 |
98 |
*/ |
*/ |
|
... |
... |
function rg_keys_mark_dirty($db) |
82 |
157 |
|
|
83 |
158 |
/* |
/* |
84 |
159 |
* Remove a key from database |
* Remove a key from database |
|
160 |
|
* TODO: Remove "multi" function and make this accepts an array of keys. |
|
161 |
|
* TODO: Here we must have a transaction! |
85 |
162 |
*/ |
*/ |
86 |
163 |
function rg_keys_remove($db, $rg_ui, $key_id, $flags) |
function rg_keys_remove($db, $rg_ui, $key_id, $flags) |
87 |
164 |
{ |
{ |
|
... |
... |
function rg_keys_remove($db, $rg_ui, $key_id, $flags) |
104 |
181 |
} |
} |
105 |
182 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
106 |
183 |
|
|
107 |
|
if (!isset($flags['no_dirty'])) { |
|
108 |
|
if (rg_keys_mark_dirty($db) !== TRUE) |
|
109 |
|
break; |
|
|
184 |
|
$event = array("category" => 1001, "prio" => 50, |
|
185 |
|
"email" => $rg_ui['email'], |
|
186 |
|
"IP" => rg_var_str("REMOTE_ADDR"), |
|
187 |
|
"key_id" => $key_id); |
|
188 |
|
$r = rg_event_add($db, $event); |
|
189 |
|
if ($r !== TRUE) { |
|
190 |
|
rg_keys_set_error("cannot add event" |
|
191 |
|
. " (" . rg_event_error() . ")"); |
|
192 |
|
break; |
110 |
193 |
} |
} |
111 |
194 |
|
|
112 |
195 |
$ret = TRUE; |
$ret = TRUE; |
|
... |
... |
function rg_keys_count($db, $uid) |
176 |
259 |
/* |
/* |
177 |
260 |
* Add a key |
* Add a key |
178 |
261 |
* Returns the key_id of the key. |
* Returns the key_id of the key. |
|
262 |
|
* TODO: Transaction! |
179 |
263 |
*/ |
*/ |
180 |
264 |
function rg_keys_add($db, $rg_ui, $key) |
function rg_keys_add($db, $rg_ui, $key) |
181 |
265 |
{ |
{ |
|
... |
... |
function rg_keys_add($db, $rg_ui, $key) |
215 |
299 |
break; |
break; |
216 |
300 |
} |
} |
217 |
301 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
218 |
|
$id = $row['key_id']; |
|
|
302 |
|
$key_id = $row['key_id']; |
219 |
303 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
220 |
304 |
|
|
221 |
|
// set dirty |
|
222 |
|
if (rg_keys_mark_dirty($db) != TRUE) |
|
|
305 |
|
$event = array("category" => 1000, "prio" => 50, |
|
306 |
|
"email" => $rg_ui['email'], |
|
307 |
|
"IP" => rg_var_str("REMOTE_ADDR"), |
|
308 |
|
"key_id" => $key_id); |
|
309 |
|
$r = rg_event_add($db, $event); |
|
310 |
|
if ($r !== TRUE) { |
|
311 |
|
rg_keys_set_error("cannot add event" |
|
312 |
|
. " (" . rg_event_error() . ")"); |
223 |
313 |
break; |
break; |
|
314 |
|
} |
224 |
315 |
|
|
225 |
|
$ret = $id; |
|
|
316 |
|
$ret = $key_id; |
226 |
317 |
} while (0); |
} while (0); |
227 |
318 |
|
|
228 |
319 |
rg_prof_end("keys_add"); |
rg_prof_end("keys_add"); |
File inc/repo.inc.php changed (mode: 100644) (index 70f57e7..4d397ad) |
... |
... |
require_once($INC . "/user.inc.php"); |
6 |
6 |
require_once($INC . "/git.inc.php"); |
require_once($INC . "/git.inc.php"); |
7 |
7 |
require_once($INC . "/rights.inc.php"); |
require_once($INC . "/rights.inc.php"); |
8 |
8 |
require_once($INC . "/prof.inc.php"); |
require_once($INC . "/prof.inc.php"); |
9 |
|
|
|
10 |
|
$rg_repo_error = ""; |
|
|
9 |
|
require_once($INC . "/events.inc.php"); |
11 |
10 |
|
|
12 |
11 |
$rg_repo_rights = array( |
$rg_repo_rights = array( |
13 |
12 |
"A" => "Admin", |
"A" => "Admin", |
|
... |
... |
$rg_repo_rights_default = "FMH"; |
34 |
33 |
rg_rights_register("repo", $rg_repo_rights); |
rg_rights_register("repo", $rg_repo_rights); |
35 |
34 |
|
|
36 |
35 |
|
|
|
36 |
|
// Repo history categories |
|
37 |
|
define('REPO_CAT_CREATE', 1); |
|
38 |
|
define('REPO_CAT_CLONED', 2); |
|
39 |
|
define('REPO_CAT_PUSH', 3); |
|
40 |
|
define('REPO_CAT_RENAME', 4); |
|
41 |
|
define('REPO_CAT_BUG_ADDED', 10); |
|
42 |
|
define('REPO_CAT_BUG_CLOSED', 11); |
|
43 |
|
|
|
44 |
|
$rg_repo_error = ""; |
|
45 |
|
|
37 |
46 |
function rg_repo_set_error($str) |
function rg_repo_set_error($str) |
38 |
47 |
{ |
{ |
39 |
48 |
global $rg_repo_error; |
global $rg_repo_error; |
40 |
|
|
|
41 |
49 |
$rg_repo_error = $str; |
$rg_repo_error = $str; |
42 |
50 |
} |
} |
43 |
51 |
|
|
|
... |
... |
function rg_repo_error() |
47 |
55 |
return $rg_repo_error; |
return $rg_repo_error; |
48 |
56 |
} |
} |
49 |
57 |
|
|
|
58 |
|
/* |
|
59 |
|
* Events functions |
|
60 |
|
*/ |
|
61 |
|
$rg_repo_functions = array( |
|
62 |
|
3000 => "rg_repo_event_new", |
|
63 |
|
3001 => "rg_repo_event_del", |
|
64 |
|
3002 => "rg_repo_event_rename", |
|
65 |
|
3003 => "rg_repo_event_notify_user" |
|
66 |
|
); |
|
67 |
|
rg_event_register_functions($rg_repo_functions); |
|
68 |
|
|
|
69 |
|
/* |
|
70 |
|
* Event for adding a new repo |
|
71 |
|
*/ |
|
72 |
|
function rg_repo_event_new($db, $event) |
|
73 |
|
{ |
|
74 |
|
$ret = array(); |
|
75 |
|
|
|
76 |
|
$event['op'] = "new"; |
|
77 |
|
// notify user |
|
78 |
|
$ret[] = array_merge($event, array("category" => 3003, "prio" => 100)); |
|
79 |
|
// TODO: notify watchers |
|
80 |
|
|
|
81 |
|
return $ret; |
|
82 |
|
} |
|
83 |
|
|
|
84 |
|
/* |
|
85 |
|
* Event for deleting repo |
|
86 |
|
*/ |
|
87 |
|
function rg_repo_event_del($db, $event) |
|
88 |
|
{ |
|
89 |
|
$ret = array(); |
|
90 |
|
|
|
91 |
|
$event['op'] = "del"; |
|
92 |
|
// notify user |
|
93 |
|
$ret[] = array_merge($event, array("category" => 3003, "prio" => 100)); |
|
94 |
|
// TODO: notify watchers |
|
95 |
|
|
|
96 |
|
return $ret; |
|
97 |
|
} |
|
98 |
|
|
|
99 |
|
/* |
|
100 |
|
* Event for renaming a repo |
|
101 |
|
*/ |
|
102 |
|
function rg_repo_event_rename($db, $event) |
|
103 |
|
{ |
|
104 |
|
$ret = array(); |
|
105 |
|
|
|
106 |
|
$event['op'] = "rename"; |
|
107 |
|
// notify user |
|
108 |
|
$ret[] = array_merge($event, array("category" => 3003, "prio" => 100)); |
|
109 |
|
// TODO: notify watchers |
|
110 |
|
|
|
111 |
|
return $ret; |
|
112 |
|
} |
|
113 |
|
|
|
114 |
|
/* |
|
115 |
|
* User notification |
|
116 |
|
*/ |
|
117 |
|
function rg_repo_event_notify_user($db, $event) |
|
118 |
|
{ |
|
119 |
|
rg_prof_start("repo_event_notify_user"); |
|
120 |
|
|
|
121 |
|
$r = rg_mail("mail/user/repo/" . $event['op'], $event); |
|
122 |
|
if ($r === FALSE) |
|
123 |
|
return FALSE; |
|
124 |
|
|
|
125 |
|
rg_prof_end("repo_event_notify_user"); |
|
126 |
|
return array(); |
|
127 |
|
} |
|
128 |
|
|
|
129 |
|
/* |
|
130 |
|
* Inserts an event into repo_history table |
|
131 |
|
*/ |
|
132 |
|
function rg_repo_history_insert($db, $repo_id, $category, $message) |
|
133 |
|
{ |
|
134 |
|
rg_prof_start("repo_history_insert"); |
|
135 |
|
rg_log("repo_history_insert: repo_id=$repo_id, category=$category" |
|
136 |
|
. ", message=$message"); |
|
137 |
|
|
|
138 |
|
$ret = FALSE; |
|
139 |
|
do { |
|
140 |
|
$now = time(); |
|
141 |
|
$e_message = rg_sql_escape($db, $message); |
|
142 |
|
$sql = "INSERT INTO repo_history_" . gmdate("Y_m", $now) |
|
143 |
|
. " (itime, repo_id, category, message)" |
|
144 |
|
. " VALUES ($now, $repo_id, $category, '$e_message')"; |
|
145 |
|
$res = rg_sql_query($db, $sql); |
|
146 |
|
if ($res === FALSE) |
|
147 |
|
break; |
|
148 |
|
|
|
149 |
|
rg_sql_free_result($res); |
|
150 |
|
$ret = TRUE; |
|
151 |
|
} while (0); |
|
152 |
|
|
|
153 |
|
rg_prof_end("repo_history_insert"); |
|
154 |
|
return $ret; |
|
155 |
|
} |
|
156 |
|
|
|
157 |
|
/* |
|
158 |
|
* Returns last events from repo_history |
|
159 |
|
* @category: 0 for any |
|
160 |
|
* @number: number of entries |
|
161 |
|
* @max_seconds: limit the search to less than max_seconds in the past |
|
162 |
|
*/ |
|
163 |
|
function rg_repo_history_load($db, $repo_id, $category, $number, $max_seconds) |
|
164 |
|
{ |
|
165 |
|
rg_prof_start("repo_history_load"); |
|
166 |
|
rg_log("repo_history_load: repo_id=$repo_id, category=$category" |
|
167 |
|
. ", number=$number max_seconds=$max_seconds"); |
|
168 |
|
|
|
169 |
|
$ret = FALSE; |
|
170 |
|
do { |
|
171 |
|
$now = time(); |
|
172 |
|
|
|
173 |
|
$category_sql = ""; |
|
174 |
|
if ($category > 0) |
|
175 |
|
$category_sql = " AND category = " . $category; |
|
176 |
|
|
|
177 |
|
$limit_sql = ""; |
|
178 |
|
if ($number > 0) |
|
179 |
|
$limit_sql = " LIMIT " . $number; |
|
180 |
|
else |
|
181 |
|
$limit_sql = " LIMIT 100"; |
|
182 |
|
|
|
183 |
|
$time_sql = ""; |
|
184 |
|
if ($max_seconds > 0) |
|
185 |
|
$time_sql = " AND itime >= " . ($now - $max_seconds); |
|
186 |
|
|
|
187 |
|
$sql = "SELECT * FROM repo_history" |
|
188 |
|
. " WHERE repo_id = $repo_id" |
|
189 |
|
. $category_sql |
|
190 |
|
. $time_sql |
|
191 |
|
. " ORDER BY itime DESC" |
|
192 |
|
. $limit_sql; |
|
193 |
|
$res = rg_sql_query($db, $sql); |
|
194 |
|
if ($res === FALSE) |
|
195 |
|
break; |
|
196 |
|
|
|
197 |
|
$ret = array(); |
|
198 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
199 |
|
$row['itime_text'] = gmdate("Y-m-d H:i", $row['itime']); |
|
200 |
|
$ret[] = $row; |
|
201 |
|
} |
|
202 |
|
|
|
203 |
|
rg_sql_free_result($res); |
|
204 |
|
} while (0); |
|
205 |
|
|
|
206 |
|
rg_prof_end("repo_history_load"); |
|
207 |
|
return $ret; |
|
208 |
|
} |
|
209 |
|
|
50 |
210 |
/* |
/* |
51 |
211 |
* Enforce name |
* Enforce name |
52 |
212 |
*/ |
*/ |
|
... |
... |
function rg_repo_create($db, $master, $rg_ui, $name, $max_commit_size, |
275 |
435 |
break; |
break; |
276 |
436 |
} |
} |
277 |
437 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
278 |
|
$ret = $row['repo_id']; |
|
279 |
438 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
|
439 |
|
|
|
440 |
|
$event = array("category" => 3000, "prio" => 50, |
|
441 |
|
"name" => $name, |
|
442 |
|
"description" => $description, |
|
443 |
|
"rights" => implode("\n", rg_rights_text("repo", $rights)), |
|
444 |
|
"email" => $rg_ui['email'], |
|
445 |
|
"IP" => rg_var_str("REMOTE_ADDR"), |
|
446 |
|
"repo_id" => $row['repo_id']); |
|
447 |
|
$r = rg_event_add($db, $event); |
|
448 |
|
if ($r !== TRUE) { |
|
449 |
|
rg_repo_set_error("cannot add event" |
|
450 |
|
. " (" . rg_event_error() . ")"); |
|
451 |
|
break; |
|
452 |
|
} |
|
453 |
|
|
|
454 |
|
// TODO: This will go with events |
|
455 |
|
rg_repo_history_insert($db, $row['repo_id'], REPO_CAT_CREATE, |
|
456 |
|
"Repo " . $name . " created."); |
|
457 |
|
|
|
458 |
|
$ret = $row['repo_id']; |
280 |
459 |
} while (0); |
} while (0); |
281 |
460 |
|
|
282 |
461 |
// git repo creation will be delayed for serialization reasons |
// git repo creation will be delayed for serialization reasons |
File inc/struct.inc.php changed (mode: 100644) (index dccf574..51d8064) |
... |
... |
include_once($INC . "/util.inc.php"); |
6 |
6 |
define("RG_DROP_TABLES", 1); |
define("RG_DROP_TABLES", 1); |
7 |
7 |
define("RG_IGNORE_ERRORS", 1 << 1); |
define("RG_IGNORE_ERRORS", 1 << 1); |
8 |
8 |
|
|
|
9 |
|
$rg_sql_struct_slaves = array(); |
9 |
10 |
$rg_sql_struct = array(); |
$rg_sql_struct = array(); |
10 |
11 |
$rg_sql_struct[1] = array(); |
$rg_sql_struct[1] = array(); |
11 |
12 |
$rg_sql_struct[1]['tables'] = array( |
$rg_sql_struct[1]['tables'] = array( |
|
... |
... |
$rg_sql_struct[9] = array(); |
192 |
193 |
$rg_sql_struct[9]['tables'] = array(); |
$rg_sql_struct[9]['tables'] = array(); |
193 |
194 |
$rg_sql_struct[9]['other'] = array( |
$rg_sql_struct[9]['other'] = array( |
194 |
195 |
"allow duplicate ssh keys" => "ALTER TABLE keys" |
"allow duplicate ssh keys" => "ALTER TABLE keys" |
195 |
|
. " DROP CONSTRAINT IF EXISTS keys_key_key", |
|
|
196 |
|
. " DROP CONSTRAINT IF EXISTS keys_pkey", |
|
197 |
|
"index on key_id" => "CREATE INDEX keys_i_key_id" |
|
198 |
|
. " ON keys(key_id)", |
196 |
199 |
"allow duplicate repos names" => "ALTER TABLE repos" |
"allow duplicate repos names" => "ALTER TABLE repos" |
197 |
|
. " DROP CONSTRAINT IF EXISTS repos_name_key", |
|
198 |
|
"index on repos names" => "CREATE INDEX repos_i_name ON repos(name)" |
|
|
200 |
|
. " DROP CONSTRAINT IF EXISTS repos_pkey", |
|
201 |
|
"index on repos names" => "CREATE INDEX repos_i_name" |
|
202 |
|
. " ON repos(name)" |
199 |
203 |
); |
); |
200 |
204 |
|
|
|
205 |
|
$rg_sql_struct[10] = array(); |
|
206 |
|
$rg_sql_struct[10]['tables'] = array( |
|
207 |
|
"repo_history" => "CREATE TABLE repo_history (" |
|
208 |
|
. "itime INT NOT NULL" |
|
209 |
|
. ", repo_id INT NOT NULL" |
|
210 |
|
. ", category SMALLINT NOT NULL" |
|
211 |
|
. ", message TEXT NOT NULL)" |
|
212 |
|
); |
|
213 |
|
$rg_sql_struct[10]['other'] = array(); |
|
214 |
|
$rg_sql_struct_slaves['repo_history'] = "repo_history"; |
|
215 |
|
|
|
216 |
|
$rg_sql_struct[11] = array(); |
|
217 |
|
$rg_sql_struct[11]['tables'] = array( |
|
218 |
|
"repo_history" => "CREATE TABLE events (" |
|
219 |
|
. "id BIGSERIAL PRIMARY KEY" |
|
220 |
|
. ", itime INT NOT NULL" |
|
221 |
|
. ", type INT NOT NULL" |
|
222 |
|
. ", data TEXT NOT NULL)" |
|
223 |
|
); |
|
224 |
|
$rg_sql_struct[11]['other'] = array(); |
|
225 |
|
|
|
226 |
|
$rg_sql_struct[12] = array(); |
|
227 |
|
$rg_sql_struct[12]['tables'] = array( |
|
228 |
|
"index on uid" => "CREATE INDEX repos_i_uid ON repos(uid)", |
|
229 |
|
"index on repo_id" => "CREATE INDEX repos_i_repo_id ON repos(repo_id)" |
|
230 |
|
); |
|
231 |
|
$rg_sql_struct[12]['other'] = array(); |
|
232 |
|
|
201 |
233 |
|
|
202 |
234 |
// This must be the last line |
// This must be the last line |
203 |
235 |
$rg_sql_schema_ver = count($rg_sql_struct); |
$rg_sql_schema_ver = count($rg_sql_struct); |
|
... |
... |
function rg_sql_struct_update($db, $flags) |
337 |
369 |
|
|
338 |
370 |
return $ret; |
return $ret; |
339 |
371 |
} |
} |
|
372 |
|
|
|
373 |
|
/* |
|
374 |
|
* Update slaves (postgresql partitions) |
|
375 |
|
* Returns FALSE in case of error |
|
376 |
|
*/ |
|
377 |
|
function rg_sql_struct_slaves_update($db) |
|
378 |
|
{ |
|
379 |
|
global $rg_sql_struct_slaves; |
|
380 |
|
|
|
381 |
|
rg_prof_start("sql_struct_slaves_update"); |
|
382 |
|
rg_log("sql_struct_update"); |
|
383 |
|
|
|
384 |
|
$ret = FALSE; |
|
385 |
|
$rollback = 0; |
|
386 |
|
do { |
|
387 |
|
if (empty($rg_sql_struct_slaves)) { |
|
388 |
|
$ret = TRUE; |
|
389 |
|
break; |
|
390 |
|
} |
|
391 |
|
|
|
392 |
|
$last_ts = rg_state_get($db, "slaves_create_last_ts"); |
|
393 |
|
if ($last_ts === FALSE) |
|
394 |
|
break; |
|
395 |
|
|
|
396 |
|
$last_ts = intval($last_ts); |
|
397 |
|
if ($last_ts == 0) |
|
398 |
|
$last_ts = gmmktime(0, 0, 0, gmdate("m"), 1, gmdate("Y")); |
|
399 |
|
|
|
400 |
|
// First second of next month |
|
401 |
|
$next_month_ts = gmmktime(0, 0, 0, gmdate("m") + 1, gmdate("d"), gmdate("Y")); |
|
402 |
|
|
|
403 |
|
if ($next_month_ts == $last_ts) { |
|
404 |
|
rg_log(" No update needed!"); |
|
405 |
|
$ret = TRUE; |
|
406 |
|
break; |
|
407 |
|
} |
|
408 |
|
|
|
409 |
|
// If we cannot lock, return error |
|
410 |
|
if (rg_lock("slave_create.lock") === FALSE) |
|
411 |
|
return FALSE; |
|
412 |
|
|
|
413 |
|
if (rg_sql_begin($db) !== TRUE) |
|
414 |
|
break; |
|
415 |
|
$rollback = 1; |
|
416 |
|
|
|
417 |
|
$ok = TRUE; |
|
418 |
|
$month = gmdate("m", $last_ts); |
|
419 |
|
$year = gmdate("Y", $last_ts); |
|
420 |
|
$ts = gmmktime(0, 0, 0, $month, 1, $year); |
|
421 |
|
do { |
|
422 |
|
$month++; |
|
423 |
|
$next_ts = gmmktime(0, 0, 0, $month, 1, $year); |
|
424 |
|
|
|
425 |
|
foreach ($rg_sql_struct_slaves as $table) { |
|
426 |
|
$slave_table = $table . "_" . gmdate("Y", $ts) . "_" . gmdate("m", $ts); |
|
427 |
|
$sql = "CREATE TABLE " . $slave_table |
|
428 |
|
. " (CHECK(itime >= $ts AND itime <= " . ($next_ts - 1) . "))" |
|
429 |
|
. " INHERITS (" . $table . ")"; |
|
430 |
|
$res = rg_sql_query($db, $sql); |
|
431 |
|
if ($res === FALSE) { |
|
432 |
|
$ok = FALSE; |
|
433 |
|
break; |
|
434 |
|
} |
|
435 |
|
rg_sql_free_result($res); |
|
436 |
|
|
|
437 |
|
$sql = "CREATE INDEX " . $slave_table . "_i_itime" |
|
438 |
|
. " ON " . $slave_table |
|
439 |
|
. " (itime)"; |
|
440 |
|
$res = rg_sql_query($db, $sql); |
|
441 |
|
if ($res === FALSE) { |
|
442 |
|
$ok = FALSE; |
|
443 |
|
break; |
|
444 |
|
} |
|
445 |
|
rg_sql_free_result($res); |
|
446 |
|
} |
|
447 |
|
$ts = $next_ts; |
|
448 |
|
} while ($ts < $next_month_ts); |
|
449 |
|
if ($ok === FALSE) |
|
450 |
|
break; |
|
451 |
|
|
|
452 |
|
$r = rg_state_set($db, "slaves_create_last_ts", $next_month_ts); |
|
453 |
|
if ($r !== TRUE) { |
|
454 |
|
rg_log("Cannot create slave (" . rg_state_error() . ")"); |
|
455 |
|
break; |
|
456 |
|
} |
|
457 |
|
|
|
458 |
|
if (rg_sql_commit($db) !== TRUE) |
|
459 |
|
break; |
|
460 |
|
|
|
461 |
|
$rollback = 0; |
|
462 |
|
$ret = TRUE; |
|
463 |
|
} while (0); |
|
464 |
|
|
|
465 |
|
if ($rollback == 1) |
|
466 |
|
rg_sql_rollback($db); |
|
467 |
|
|
|
468 |
|
rg_unlock("slave_create.lock"); |
|
469 |
|
|
|
470 |
|
rg_prof_end("sql_struct_slaves_update"); |
|
471 |
|
return $ret; |
|
472 |
|
} |
340 |
473 |
?> |
?> |
File inc/user.inc.php changed (mode: 100644) (index 26ff599..9248762) |
... |
... |
require_once($INC . "/log.inc.php"); |
4 |
4 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
5 |
5 |
require_once($INC . "/sess.inc.php"); |
require_once($INC . "/sess.inc.php"); |
6 |
6 |
require_once($INC . "/rights.inc.php"); |
require_once($INC . "/rights.inc.php"); |
|
7 |
|
require_once($INC . "/events.inc.php"); |
7 |
8 |
|
|
8 |
9 |
$rg_user_rights = array( |
$rg_user_rights = array( |
9 |
10 |
"C" => "Create repositories", |
"C" => "Create repositories", |
|
... |
... |
$rg_user_rights = array( |
12 |
13 |
|
|
13 |
14 |
rg_rights_register("user", $rg_user_rights); |
rg_rights_register("user", $rg_user_rights); |
14 |
15 |
|
|
|
16 |
|
$rg_user_error = ""; |
|
17 |
|
|
15 |
18 |
function rg_user_set_error($str) |
function rg_user_set_error($str) |
16 |
19 |
{ |
{ |
17 |
|
global $_rg_user_error; |
|
18 |
|
|
|
19 |
|
$_rg_user_error = $str; |
|
|
20 |
|
global $rg_user_error; |
|
21 |
|
$rg_user_error = $str; |
20 |
22 |
} |
} |
21 |
23 |
|
|
22 |
24 |
function rg_user_error() |
function rg_user_error() |
23 |
25 |
{ |
{ |
24 |
|
global $_rg_user_error; |
|
25 |
|
return $_rg_user_error; |
|
|
26 |
|
global $rg_user_error; |
|
27 |
|
return $rg_user_error; |
|
28 |
|
} |
|
29 |
|
|
|
30 |
|
/* |
|
31 |
|
* Event functions |
|
32 |
|
*/ |
|
33 |
|
$rg_user_functions = array( |
|
34 |
|
2000 => "rg_user_event_new", |
|
35 |
|
2002 => "rg_user_event_notify_user" |
|
36 |
|
); |
|
37 |
|
rg_event_register_functions($rg_user_functions); |
|
38 |
|
|
|
39 |
|
/* |
|
40 |
|
* Event for adding a new user |
|
41 |
|
*/ |
|
42 |
|
function rg_user_event_new($db, $event) |
|
43 |
|
{ |
|
44 |
|
$ret = array(); |
|
45 |
|
|
|
46 |
|
$event['op'] = "new"; |
|
47 |
|
// notify user |
|
48 |
|
$ret[] = array_merge($event, array("category" => 2002, "prio" => 100)); |
|
49 |
|
|
|
50 |
|
return $ret; |
|
51 |
|
} |
|
52 |
|
|
|
53 |
|
/* |
|
54 |
|
* Notify user: welcome |
|
55 |
|
*/ |
|
56 |
|
function rg_user_event_notify_user($db, $event) |
|
57 |
|
{ |
|
58 |
|
rg_log("user_event_notify_user: event=" . rg_array2string($event)); |
|
59 |
|
|
|
60 |
|
$r = rg_mail("mail/user/welcome", $event); |
|
61 |
|
if ($r === FALSE) |
|
62 |
|
return FALSE; |
|
63 |
|
|
|
64 |
|
return array(); |
26 |
65 |
} |
} |
27 |
66 |
|
|
28 |
67 |
/* |
/* |
|
... |
... |
function rg_user_edit($db, $d) |
181 |
220 |
// invalidate cache |
// invalidate cache |
182 |
221 |
$rg_user_info_cache = array(); |
$rg_user_info_cache = array(); |
183 |
222 |
|
|
|
223 |
|
if ($d['uid'] == 0) { // add |
|
224 |
|
$event = array("category" => 2000, "prio" => 50, |
|
225 |
|
"email" => $d['email'] |
|
226 |
|
); |
|
227 |
|
$r = rg_event_add($db, $event); |
|
228 |
|
if ($r === FALSE) { |
|
229 |
|
rg_user_set_error("Canot add event!"); |
|
230 |
|
return FALSE; |
|
231 |
|
} |
|
232 |
|
} |
|
233 |
|
|
184 |
234 |
return TRUE; |
return TRUE; |
185 |
235 |
} |
} |
186 |
236 |
|
|
File inc/user/repo-page.php changed (mode: 100644) (index db81318..ddb649e) |
... |
... |
$repo_dir = rg_repo_name2base($rr) . $rr['repo'] . ".git"; |
67 |
67 |
rg_log("repo_dir=$repo_dir"); |
rg_log("repo_dir=$repo_dir"); |
68 |
68 |
putenv("GIT_DIR=$repo_dir"); |
putenv("GIT_DIR=$repo_dir"); |
69 |
69 |
|
|
70 |
|
// default is "source" tab |
|
71 |
|
if (empty($subop)) |
|
72 |
|
$subop = "source"; |
|
73 |
|
|
|
74 |
70 |
$repo_more['repo_body'] = ""; |
$repo_more['repo_body'] = ""; |
75 |
71 |
$repo_more['repo_right'] = ""; |
$repo_more['repo_right'] = ""; |
76 |
72 |
$repo_more['branches_and_tags'] = ""; |
$repo_more['branches_and_tags'] = ""; |
|
... |
... |
if ($rg_git_port != 0) |
85 |
81 |
$urls[]['HTML:url'] = '<a href="' . $repo_more['git'] . '">' . $repo_more['git'] . '</a>'; |
$urls[]['HTML:url'] = '<a href="' . $repo_more['git'] . '">' . $repo_more['git'] . '</a>'; |
86 |
82 |
$repo_more['HTML:urls'] = rg_template_table("repo/urls", $urls, $repo_more); |
$repo_more['HTML:urls'] = rg_template_table("repo/urls", $urls, $repo_more); |
87 |
83 |
|
|
88 |
|
if (strcmp($subop, "admin") == 0) { |
|
|
84 |
|
// default is "source" tab |
|
85 |
|
if (empty($subop)) |
|
86 |
|
$subop = "history"; |
|
87 |
|
|
|
88 |
|
if (strcmp($subop, "history") == 0) { |
|
89 |
|
$hist = rg_repo_history_load($db, $ri['repo_id'], 0, 20, 0); |
|
90 |
|
if ($hist === FALSE) |
|
91 |
|
$_repo_body .= rg_warning("Cannot load history. Try again later."); |
|
92 |
|
else |
|
93 |
|
$_repo_body .= rg_template_table("repo/history", $hist, $repo_more); |
|
94 |
|
} else if (strcmp($subop, "admin") == 0) { |
89 |
95 |
include($INC . "/user/repo/admin/admin.php"); |
include($INC . "/user/repo/admin/admin.php"); |
90 |
96 |
$_repo_body .= $_admin; |
$_repo_body .= $_admin; |
91 |
97 |
} else if (strcmp($subop, "source") == 0) { |
} else if (strcmp($subop, "source") == 0) { |
File inc/util.inc.php changed (mode: 100644) (index 2ad030f..30d9412) |
... |
... |
require_once($INC . "/log.inc.php"); |
5 |
5 |
set_error_handler("rg_error_handler"); |
set_error_handler("rg_error_handler"); |
6 |
6 |
register_shutdown_function("rg_shutdown_error"); |
register_shutdown_function("rg_shutdown_error"); |
7 |
7 |
|
|
|
8 |
|
$rg_util_error = ""; |
|
9 |
|
|
8 |
10 |
function rg_util_set_error($str) |
function rg_util_set_error($str) |
9 |
11 |
{ |
{ |
10 |
|
global $_rg_util_error; |
|
11 |
|
$_rg_util_error = $str; |
|
|
12 |
|
global $rg_util_error; |
|
13 |
|
$rg_util_error = $str; |
12 |
14 |
} |
} |
13 |
15 |
|
|
14 |
16 |
function rg_util_error() |
function rg_util_error() |
15 |
17 |
{ |
{ |
16 |
|
global $_rg_util_error; |
|
17 |
|
return $_rg_util_error; |
|
|
18 |
|
global $rg_util_error; |
|
19 |
|
return $rg_util_error; |
18 |
20 |
} |
} |
19 |
21 |
|
|
20 |
22 |
function rg_1024($v) |
function rg_1024($v) |
|
... |
... |
function rg_unlock($file) |
102 |
104 |
{ |
{ |
103 |
105 |
global $_lock; |
global $_lock; |
104 |
106 |
|
|
105 |
|
fclose($_lock[$file]); |
|
|
107 |
|
if (isset($_lock[$file])) |
|
108 |
|
fclose($_lock[$file]); |
106 |
109 |
} |
} |
107 |
110 |
|
|
108 |
111 |
function rg_load() |
function rg_load() |
|
... |
... |
function rg_var_str($name) |
211 |
214 |
{ |
{ |
212 |
215 |
$ret = ""; |
$ret = ""; |
213 |
216 |
|
|
214 |
|
if (isset($_COOKIE[$name])) |
|
|
217 |
|
if (isset($_SERVER[$name])) |
|
218 |
|
$ret = $_SERVER[$name]; |
|
219 |
|
else if (isset($_COOKIE[$name])) |
215 |
220 |
$ret = $_COOKIE[$name]; |
$ret = $_COOKIE[$name]; |
216 |
221 |
else if (isset($_POST[$name])) |
else if (isset($_POST[$name])) |
217 |
222 |
$ret = $_POST[$name]; |
$ret = $_POST[$name]; |
|
... |
... |
function rg_prepare_replace(&$data, &$what, &$values) |
532 |
537 |
*/ |
*/ |
533 |
538 |
function rg_file_get_contents($f) |
function rg_file_get_contents($f) |
534 |
539 |
{ |
{ |
535 |
|
if (!file_exists($f)) |
|
|
540 |
|
if (!file_exists($f)) { |
|
541 |
|
rg_log("File $f does not exists."); |
536 |
542 |
return ""; |
return ""; |
|
543 |
|
} |
537 |
544 |
|
|
538 |
545 |
return @file_get_contents($f); |
return @file_get_contents($f); |
539 |
546 |
} |
} |
|
... |
... |
function rg_template_table($dir, $data, $more) |
547 |
554 |
global $rg_scripts; |
global $rg_scripts; |
548 |
555 |
|
|
549 |
556 |
$xdir = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $dir; |
$xdir = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $dir; |
550 |
|
if (!is_dir($xdir)) |
|
|
557 |
|
if (!is_dir($xdir)) { |
|
558 |
|
rg_log("$xdir not found."); |
551 |
559 |
$xdir = $rg_scripts . "/root/themes/default/" . $dir; |
$xdir = $rg_scripts . "/root/themes/default/" . $dir; |
|
560 |
|
rg_log("Using [$xdir]"); |
|
561 |
|
} |
552 |
562 |
|
|
553 |
563 |
$m_what = array(); $m_values = array(); |
$m_what = array(); $m_values = array(); |
554 |
564 |
rg_prepare_replace($more, $m_what, $m_values); |
rg_prepare_replace($more, $m_what, $m_values); |
|
... |
... |
function rg_date2ts_last_second($s) |
951 |
961 |
return gmmktime(0, 0, 0, $f[1], $f[2] + 1, $f[0]) - 1; |
return gmmktime(0, 0, 0, $f[1], $f[2] + 1, $f[0]) - 1; |
952 |
962 |
} |
} |
953 |
963 |
|
|
|
964 |
|
/* |
|
965 |
|
* Function to send e-mails |
|
966 |
|
* TODO: Replace mail() wil rg_mail everywhere. |
|
967 |
|
*/ |
|
968 |
|
function rg_mail($template, $more) |
|
969 |
|
{ |
|
970 |
|
global $rg_admin_name, $rg_admin_email; |
|
971 |
|
|
|
972 |
|
rg_prof_start("mail"); |
|
973 |
|
rg_log("mail: $template, more=" . rg_array2string($more)); |
|
974 |
|
|
|
975 |
|
|
|
976 |
|
$more['HTML:rg_admin_email'] = $rg_admin_email; |
|
977 |
|
$more['HTML:utf8_rg_admin_name'] = "=?UTF-8?B?" |
|
978 |
|
. base64_encode($rg_admin_name) . "?="; |
|
979 |
|
|
|
980 |
|
$subject = rg_template($template . ".subj.txt", $more); |
|
981 |
|
$subject = "=?UTF-8?B?" . base64_encode(trim($subject)) . "?="; |
|
982 |
|
$header = rg_template($template . ".head.txt", $more); |
|
983 |
|
$body = rg_template($template . ".body.txt", $more); |
|
984 |
|
|
|
985 |
|
$ret = mail($more['email'], $subject, $body, $header, "-f $rg_admin_email"); |
|
986 |
|
if ($ret === FALSE) |
|
987 |
|
rg_log("Sending mail failed!"); |
|
988 |
|
|
|
989 |
|
rg_prof_end("mail"); |
|
990 |
|
return $ret; |
|
991 |
|
} |
|
992 |
|
|
954 |
993 |
?> |
?> |
File rocketgit.spec.in changed (mode: 100644) (index a47d6af..ca06a83) |
... |
... |
rm -rf ${RPM_BUILD_ROOT} |
51 |
51 |
|
|
52 |
52 |
%files |
%files |
53 |
53 |
%attr (-,root,root) |
%attr (-,root,root) |
54 |
|
@USR_SHARE@/@PRJ@ |
|
55 |
|
%doc README LICENSE Changelog TODO |
|
56 |
|
%dir /etc/@PRJ@ |
|
57 |
|
%config(noreplace) /etc/@PRJ@/config.php |
|
58 |
|
/etc/@PRJ@/config.php.sample |
|
59 |
|
/etc/cron.d/rocketgit |
|
60 |
|
%config(noreplace) /etc/xinetd.d/rocketgit |
|
61 |
|
%config(noreplace) /etc/httpd/conf.d/rocketgit.conf |
|
62 |
|
%attr(0700,rocketgit,rocketgit) %dir /var/log/@PRJ@ |
|
63 |
|
%attr(0700,apache,apache) %dir /var/log/@PRJ@-web |
|
64 |
|
%attr(0755,rocketgit,rocketgit) %dir /var/lib/@PRJ@ |
|
65 |
|
%attr(0700,rocketgit,rocketgit) %dir /var/lib/@PRJ@/locks |
|
66 |
|
%attr(0755,rocketgit,rocketgit) %dir /var/lib/@PRJ@/repos |
|
67 |
|
%attr(0700,rocketgit,rocketgit) %dir /var/lib/@PRJ@/q_merge_requests |
|
68 |
|
%config(noreplace) /etc/logrotate.d/rocketgit |
|
|
54 |
|
%attr(0755,root,root) %dir @USR_SHARE@/@PRJ@ |
|
55 |
|
%attr(0755,root,root) %doc README LICENSE Changelog TODO |
|
56 |
|
%attr(0755,root,root) %dir @ETC@/@PRJ@ |
|
57 |
|
%attr(0755,root,root) %config(noreplace) @ETC@/@PRJ@/config.php |
|
58 |
|
%attr(0755,root,root) @ETC@/@PRJ@/config.php.sample |
|
59 |
|
%attr(0755,root,root) @ETC@/cron.d/rocketgit |
|
60 |
|
%attr(0755,roor,root) %config(noreplace) @ETC@/xinetd.d/rocketgit |
|
61 |
|
%attr(0755,root,root) %config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf |
|
62 |
|
%attr(0755,root,root) %config(noreplace) @ETC@/logrotate.d/rocketgit |
|
63 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@ |
|
64 |
|
%attr(0700,apache,apache) %dir @VAR_LOG@/@PRJ@-web |
|
65 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@ |
|
66 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/locks |
|
67 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos |
|
68 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests |
|
69 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets |
69 |
70 |
|
|
70 |
71 |
%changelog |
%changelog |
71 |
72 |
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dor ro> 0.10 |
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dor ro> 0.10 |
File scripts/events.php added (mode: 100644) (index 0000000..5553891) |
|
1 |
|
<?php |
|
2 |
|
// This is called by cron, and is persistent. |
|
3 |
|
// It takes care of any background job received. |
|
4 |
|
// It will receive signals using a UNIX socket. |
|
5 |
|
// TODO: This will obsolete q.php |
|
6 |
|
error_reporting(E_ALL); |
|
7 |
|
ini_set("track_errors", "On"); |
|
8 |
|
|
|
9 |
|
$now = time(); |
|
10 |
|
$_s = microtime(TRUE); |
|
11 |
|
|
|
12 |
|
require_once("/etc/rocketgit/config.php"); |
|
13 |
|
|
|
14 |
|
$INC = dirname(__FILE__) . "/../inc"; |
|
15 |
|
require_once($INC . "/init.inc.php"); |
|
16 |
|
require_once($INC . "/log.inc.php"); |
|
17 |
|
require_once($INC . "/sql.inc.php"); |
|
18 |
|
require_once($INC . "/struct.inc.php"); |
|
19 |
|
require_once($INC . "/events.inc.php"); |
|
20 |
|
require_once($INC . "/repo.inc.php"); |
|
21 |
|
require_once($INC . "/prof.inc.php"); |
|
22 |
|
require_once($INC . "/mr.inc.php"); |
|
23 |
|
require_once($INC . "/keys.inc.php"); |
|
24 |
|
require_once($INC . "/user.inc.php"); |
|
25 |
|
|
|
26 |
|
rg_prof_start("MAIN"); |
|
27 |
|
|
|
28 |
|
rg_log_set_file($rg_log_dir . "/events.log"); |
|
29 |
|
|
|
30 |
|
// locking |
|
31 |
|
rg_lock_or_exit("events.lock"); |
|
32 |
|
|
|
33 |
|
rg_log("Start..."); |
|
34 |
|
|
|
35 |
|
$db = rg_sql_open($rg_sql); |
|
36 |
|
if ($db === FALSE) { |
|
37 |
|
rg_internal_error("Cannot connect to database!"); |
|
38 |
|
// TODO: inform admin - already by e-mail? |
|
39 |
|
exit(1); |
|
40 |
|
} |
|
41 |
|
|
|
42 |
|
$r = rg_sql_struct_update($db, 0); |
|
43 |
|
if ($r !== TRUE) |
|
44 |
|
exit(1); |
|
45 |
|
|
|
46 |
|
// Remove the socket, else we will get error |
|
47 |
|
if (file_exists($rg_event_socket)) |
|
48 |
|
unlink($rg_event_socket); |
|
49 |
|
|
|
50 |
|
// Prepare socket for signaling |
|
51 |
|
$socket = socket_create(AF_UNIX, SOCK_DGRAM, 0); |
|
52 |
|
if ($socket === FALSE) { |
|
53 |
|
rg_internal_error("Cannot create events socket!"); |
|
54 |
|
exit(1); |
|
55 |
|
} |
|
56 |
|
|
|
57 |
|
$r = socket_bind($socket, $rg_event_socket); |
|
58 |
|
if ($r === FALSE) { |
|
59 |
|
rg_internal_error("Cannot bind socket!"); |
|
60 |
|
exit(1); |
|
61 |
|
} |
|
62 |
|
|
|
63 |
|
// Allow apache to connect to socket |
|
64 |
|
$r = chmod($rg_event_socket, 0666); |
|
65 |
|
if ($r === FALSE) { |
|
66 |
|
rg_internal_error("Cannot set rights on event socket!"); |
|
67 |
|
exit(1); |
|
68 |
|
} |
|
69 |
|
|
|
70 |
|
$original_mtime = filemtime(__FILE__); |
|
71 |
|
do { |
|
72 |
|
// Check our mtime so we can upgrade the software and this script |
|
73 |
|
// will restart. |
|
74 |
|
clearstatcache(); |
|
75 |
|
$mtime = filemtime(__FILE__); |
|
76 |
|
rg_log("mtime=$mtime, original_mtime=$original_mtime"); |
|
77 |
|
if ($mtime != $original_mtime) { |
|
78 |
|
rg_log("File changed. Exiting..."); |
|
79 |
|
break; |
|
80 |
|
} |
|
81 |
|
|
|
82 |
|
// check machine load - if too big we will delay |
|
83 |
|
$load = rg_load(); |
|
84 |
|
if ($load > 10) { |
|
85 |
|
rg_log("\tLoad too big!"); |
|
86 |
|
sleep(10); |
|
87 |
|
continue; |
|
88 |
|
} |
|
89 |
|
|
|
90 |
|
do { |
|
91 |
|
$r = rg_event_process_queue($db); |
|
92 |
|
if ($r === FALSE) |
|
93 |
|
break; |
|
94 |
|
} while ($r > 0); |
|
95 |
|
if ($r === FALSE) |
|
96 |
|
break; |
|
97 |
|
|
|
98 |
|
// Wait for signal |
|
99 |
|
rg_log("Waiting for signal..."); |
|
100 |
|
socket_recvfrom($socket, $buf, 1024, 0, $from); |
|
101 |
|
} while (1); |
|
102 |
|
|
|
103 |
|
socket_close($socket); |
|
104 |
|
|
|
105 |
|
rg_prof_end("MAIN"); |
|
106 |
|
rg_prof_log("rg_log"); |
|
107 |
|
?> |
File tests/event.php added (mode: 100644) (index 0000000..d55cd6a) |
|
1 |
|
<?php |
|
2 |
|
error_reporting(E_ALL | E_STRICT); |
|
3 |
|
ini_set("track_errors", "On"); |
|
4 |
|
|
|
5 |
|
// override the default |
|
6 |
|
$rg_event_socket = "event.sock"; |
|
7 |
|
|
|
8 |
|
$INC = "../inc"; |
|
9 |
|
require_once($INC . "/init.inc.php"); |
|
10 |
|
require_once($INC . "/events.inc.php"); |
|
11 |
|
require_once($INC . "/sql.inc.php"); |
|
12 |
|
require_once($INC . "/struct.inc.php"); |
|
13 |
|
|
|
14 |
|
rg_log_set_file("event.log"); |
|
15 |
|
|
|
16 |
|
$rg_sql_debug = 1; |
|
17 |
|
|
|
18 |
|
$db = rg_sql_open("dbname=trg"); |
|
19 |
|
if ($db === FALSE) { |
|
20 |
|
rg_log("Cannot create a database (" . rg_sql_error() . ")!"); |
|
21 |
|
exit(1); |
|
22 |
|
} |
|
23 |
|
|
|
24 |
|
$r = rg_sql_struct_update($db, RG_DROP_TABLES|RG_IGNORE_ERRORS); |
|
25 |
|
if ($r !== TRUE) { |
|
26 |
|
rg_log("Cannot create struct (" . rg_sql_error() . ")!"); |
|
27 |
|
exit(1); |
|
28 |
|
} |
|
29 |
|
|
|
30 |
|
$sql = "TRUNCATE TABLE events"; |
|
31 |
|
$res = rg_sql_query($db, $sql); |
|
32 |
|
if ($res === FALSE) { |
|
33 |
|
echo "Cannot truncate table!\n"; |
|
34 |
|
exit(1); |
|
35 |
|
} |
|
36 |
|
rg_sql_free_result($res); |
|
37 |
|
|
|
38 |
|
/* |
|
39 |
|
* This function will generate an array of sub-events |
|
40 |
|
*/ |
|
41 |
|
function notif_new_repo($db, $ev) |
|
42 |
|
{ |
|
43 |
|
rg_log("notif_new_repo: ev=" . rg_array2string($ev)); |
|
44 |
|
|
|
45 |
|
$ret = array(); |
|
46 |
|
|
|
47 |
|
// Send mail to the owner |
|
48 |
|
$ret[] = array_merge($ev, "category" => 1); |
|
49 |
|
|
|
50 |
|
// Send mail to admin |
|
51 |
|
$ret[] = array_merge($ev, "category" => 2); |
|
52 |
|
|
|
53 |
|
// Other junk |
|
54 |
|
$ret[] = array_merge($ev, "category" => 3); |
|
55 |
|
|
|
56 |
|
return $ret; |
|
57 |
|
} |
|
58 |
|
|
|
59 |
|
// Register an event function |
|
60 |
|
$functions = array(); |
|
61 |
|
$functions[1] = "notif_new_repo"; |
|
62 |
|
$r = rg_event_register_functions($functions); |
|
63 |
|
if ($r !== TRUE) { |
|
64 |
|
echo "Cannot register functions!\n"; |
|
65 |
|
exit(1); |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
// defaults |
|
69 |
|
$event = array( |
|
70 |
|
"type" => 0, |
|
71 |
|
"data" => array( |
|
72 |
|
"category" => 1, |
|
73 |
|
"repo_id" => 200 |
|
74 |
|
) |
|
75 |
|
); |
|
76 |
|
|
|
77 |
|
$r = rg_event_add($db, $event); |
|
78 |
|
if ($r !== TRUE) { |
|
79 |
|
echo "Cannot add event (" . rg_event_error() . ")!\n"; |
|
80 |
|
exit(1); |
|
81 |
|
} |
|
82 |
|
|
|
83 |
|
$r = rg_event_process_queue($db); |
|
84 |
|
if ($r !== TRUE) { |
|
85 |
|
echo "Cannot process queue (" . rg_event_error() . ")!\n"; |
|
86 |
|
exit(1); |
|
87 |
|
} |
|
88 |
|
|
|
89 |
|
rg_sql_close($db); |
|
90 |
|
|
|
91 |
|
echo "event: OK!\n"; |
|
92 |
|
?> |