File TODO changed (mode: 100644) (index a4f9b6d..cdb786f) |
1 |
1 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
2 |
|
[ ] Seems that an annotated tag cannot be overwritten, even with rights. |
|
3 |
|
[ ] Test bug.php is not working. Seems that repo_info is not working right for |
|
4 |
|
an inexistent repo_id! |
|
5 |
|
[ ] From arora I cannot login! See a tcpdump. |
|
6 |
|
[ ] Rights management |
|
7 |
|
- A user is trying to push some commits in a branch B, for a file F |
|
8 |
|
- The set of rights may be: |
|
9 |
|
Branch File/dir Rights |
|
10 |
|
B2 dir/*.png FPA |
|
11 |
|
* dir2 A |
|
12 |
|
* * F |
|
13 |
|
refs/heads/x/ * ??? - allow to push in private "ns" 'x' |
|
14 |
|
x/ * ??? - same as above. |
|
15 |
|
refs/tags/v[0-9] ??? - allow tags that starts with v. |
|
16 |
|
USER/ * ??? - give rights to any user to a |
|
17 |
|
private branch (refs/heads/USER/...). |
|
18 |
|
* USER/ ??? - give rights to any user to a |
|
19 |
|
private dir. |
|
20 |
|
- Also limit by IP and by time. |
|
21 |
|
- We have a problem: some rights do not map correctly to the plan above. |
|
22 |
|
For example, A(admin) |
|
23 |
|
- Also, we will have problems classifying a project as public or private. |
|
24 |
|
Maybe we can compute the rights as an event after any rights change. |
|
25 |
|
Maybe we should let the user what type of project it is, and, if is |
|
26 |
|
public, to grant fetch right. |
|
27 |
|
- Should I add "Create users right"? |
2 |
28 |
|
|
3 |
|
== BEFORE FIRST RELEASE! == |
|
4 |
|
[ ] Increment usage on keys should be done by events, with a predefined interval |
|
5 |
|
to not kill the database. |
|
6 |
|
[ ] Uploading/deleting a key will generate an event. |
|
7 |
|
[ ] Add first usage of ssh keys. |
|
8 |
|
[ ] Add count of usage for ssh keys. |
|
9 |
|
[ ] Reorder ssh keys by usage to speed up ssh login. |
|
10 |
|
[ ] In documentation, because of SELinux, we may want to restart some services. |
|
11 |
|
At least: xinetd, cron etc. Probably not, but I must test this. |
|
|
29 |
|
== BEFORE NEXT RELEASE == |
|
30 |
|
[ ] Does it makes sense to have a local cache (user/repo/etc.) when we have |
|
31 |
|
another local cache (cache.inc.php). |
|
32 |
|
[ ] Search for "parmas" and "$e_". |
|
33 |
|
[ ] Remove all db escaping after switching to params! |
|
34 |
|
[ ] keys.inc.php - convert to params! |
|
35 |
|
[ ] Switch from pg_query to pg_query_params. |
|
36 |
|
[ ] Finish high level sql function. |
|
37 |
|
[ ] When we escape, it will try to connect to database, that may fail. |
|
38 |
|
This is not good at all and it seems a little bit hard to fix. |
|
39 |
|
Maybe switch to prepared statements? |
|
40 |
|
[ ] pg_fetch_assoc returns FALSE if error or no more rows. |
|
41 |
|
We must know the difference! |
|
42 |
|
[ ] Check "suspend"/"make admin"/etc. in admin area. Maybe use a checkbox and |
|
43 |
|
an operation to avoid CSRF and to be consistent with ssh keys forms? |
|
44 |
|
[ ] Fix rights saga on user side. We may remove user_allow and replace with |
|
45 |
|
rights_check? |
|
46 |
|
[ ] Riths use-cases: |
|
47 |
|
[ ] An admin may not have "Remove" access. |
|
48 |
|
[ ] An admin may not have "Suspend" access. |
|
49 |
|
[ ] An admin may have only add/edit rights. |
|
50 |
|
[ ] "Reset password" in admin area? |
|
51 |
|
[ ] "Make admin" will be replaced by "Edit"? |
|
52 |
|
[ ] Problems trying to push to rg1 because of SELinux: |
|
53 |
|
type=SELINUX_ERR msg=audit(1366526640.307:1449979): security_compute_sid: |
|
54 |
|
invalid context unconfined_u:unconfined_r:rocketgit_t:s0-s0:c0.c1023 |
|
55 |
|
for scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 |
|
56 |
|
tcontext=system_u:object_r:rocketgit_exec_t:s0 tclass=process |
12 |
57 |
[ ] Check if adding/editing a bug generates notifications correctly. |
[ ] Check if adding/editing a bug generates notifications correctly. |
13 |
58 |
Maybe use a global function for notify_one. |
Maybe use a global function for notify_one. |
14 |
59 |
[ ] When we cannot process an event, mark it as failed and do not touch it again. |
[ ] When we cannot process an event, mark it as failed and do not touch it again. |
|
19 |
64 |
[ ] Checking for "rg_ui['uid'] == 0" may not be enough. |
[ ] Checking for "rg_ui['uid'] == 0" may not be enough. |
20 |
65 |
Maybe rg_ui[['uid'] = repo['uid']? |
Maybe rg_ui[['uid'] = repo['uid']? |
21 |
66 |
Or, everywhere add 'uid = ?' in queries. |
Or, everywhere add 'uid = ?' in queries. |
22 |
|
[ ] All operations must be verified with tokens. |
|
|
67 |
|
Scenario: a user pass a list of ids to be del but s/he's not the owner. |
23 |
68 |
[ ] Check if we can give rights for a non-owning repo! |
[ ] Check if we can give rights for a non-owning repo! |
24 |
69 |
We should check if the user that gives rights is the owner or has admin |
We should check if the user that gives rights is the owner or has admin |
25 |
70 |
rights! |
rights! |
|
71 |
|
[ ] Add "lock ip" to settings and use them as default. |
|
72 |
|
Also use it for confirmation. |
|
73 |
|
But, if the IP changes, the user will have to relogin. Hm. |
|
74 |
|
[ ] The rights should be stored on different rows? Probably not. |
|
75 |
|
[ ] Adding an account seems to just show "Account was created". |
|
76 |
|
Maybe redirect to user page? Only if there is no need to confirm. |
|
77 |
|
What about lock_ip? |
|
78 |
|
[ ] Where to check if plan exists (rg_user_edit_high_level). |
26 |
79 |
|
|
27 |
80 |
== Medium == |
== Medium == |
|
81 |
|
[ ] Allow user to change timezone! |
|
82 |
|
[ ] Prea mult spatiu gol la notificarea de schimbare repo. |
|
83 |
|
[ ] @@if: if after {{/}} follows a \n, just remove it? |
|
84 |
|
[ ] Think about moving unused tokens to a new session after login. |
|
85 |
|
[ ] Security: Edit info: user can chage the uid behind my back in form! |
|
86 |
|
This is fixed with rg_user_allow_access. It should be used everywhere. |
|
87 |
|
[ ] Maybe do not deny account creation, but put them on a special state |
|
88 |
|
and ask admin to allow it? |
|
89 |
|
[ ] $sid to be masked behind a function (rg_user_get_sid). |
|
90 |
|
[ ] Use curl to auto test all web functionality fast. |
|
91 |
|
[ ] info.php shouldn't be converted to high-level function?! |
|
92 |
|
[ ] Move sending e-mails to event. |
|
93 |
|
[ ] Think about renaming repositories to projects. Because they contain also |
|
94 |
|
the bug tracker. Maybe in the future the admin would want to disable |
|
95 |
|
some modules (git/bug tracket/etc.). |
|
96 |
|
[ ] When a push/etc. taskes places, add an event to recompute disk size! |
|
97 |
|
Then, remove this from cron. |
|
98 |
|
[ ] If user applies for open-source type account, do not allow private repos. |
|
99 |
|
[ ] Move rg_account_allow_creation and other configuration stuff into admin area. |
|
100 |
|
[ ] How to set default rights for new users? Maybe a section in admin area? |
|
101 |
|
[ ] Computing disk size must invalidate the user cache. Or update it? |
|
102 |
|
[ ] Check in remote.php that for the user connecting we are updating stats. |
|
103 |
|
Better, update stats for both connecting user and repo is connecting to. |
|
104 |
|
As an event? |
|
105 |
|
[ ] Allow user to change the plan somehow. |
|
106 |
|
[ ] In documentation, because of SELinux, we may want to restart some services. |
|
107 |
|
At least: xinetd, cron etc. Probably not, but I must test this. |
|
108 |
|
[ ] Think about generating more tokens. Maybe just sign them to not be forced |
|
109 |
|
to save them in database. At least generate more than one and cache them. |
|
110 |
|
[ ] There is a small possibility for files that are called from cron to not |
|
111 |
|
have correct context (cron instead rocketgit_t). Seems I fixed it |
|
112 |
|
with check_context function. |
|
113 |
|
[ ] Allow upload a ssh key as a file, not only paste it in textarea. |
|
114 |
|
[ ] Merge $more in all places where we add events. |
|
115 |
|
[ ] Invite a friend. |
|
116 |
|
[ ] In a lot of places seems I use rg_log instead of rg_*_set_error! |
|
117 |
|
[ ] Auto login after account creation? What about locking by IP? Maybe just redirect to |
|
118 |
|
login page with (at least) username pre-filled? Or ask only about "lock ip"? |
|
119 |
|
[ ] sess: just mark it as invalid and store it in cache to not connect to |
|
120 |
|
database? Cron will clean them up. |
|
121 |
|
[ ] Transaction for bugs_max should be shorter. Now is very long. Hm. |
|
122 |
|
[ ] Protect sh scripts to be run as rocletgit user and not other. |
|
123 |
|
[ ] To not have too many keys in authorized_keys, investigate certificates. |
|
124 |
|
[ ] Add cache in: |
|
125 |
|
- rg_keys_count |
|
126 |
|
- etc. |
|
127 |
|
[ ] Add transaction in all places where event_add is called. |
|
128 |
|
Maybe also in other places. Do an audit. |
|
129 |
|
[ ] Remove 'repo/dirty' stuff and replace with events. |
|
130 |
|
[ ] When we delete a user, should we remove from cache the name_to_id/email_to_id? |
|
131 |
|
[ ] Delete repo - check if all is deleted. Seems not. |
|
132 |
|
[ ] Audit all operations to be verified with tokens. |
|
133 |
|
[ ] Create repo on demand when a user pushes. |
|
134 |
|
[ ] Compute how many users are per plan, as an event when a user is |
|
135 |
|
added/deleted/changed plans. Better, from cron. |
|
136 |
|
[ ] Increment usage on keys should be done by events, with a predefined interval |
|
137 |
|
to not kill the database. |
|
138 |
|
[ ] Allow user management by ssh: |
|
139 |
|
ssh rocketgit@host create-account --ssh-key `cat key.pub` <name>. |
|
140 |
|
ssh rocketgit@host disable-account <name>. |
|
141 |
|
Of course, check rights. |
|
142 |
|
[ ] Add unit testing for high level functions. |
|
143 |
|
[ ] Add unit testing for plans and rg_user_over_limit. |
|
144 |
|
[ ] Switch to *_high_level functions. |
|
145 |
|
[ ] When user press submit in a form and session expired, save in a cookie all |
|
146 |
|
data, invite user to login and redirect to old page will all fields |
|
147 |
|
filled in! But if the user is in a cafe, s/he will lose that info. |
|
148 |
|
Better store locally. |
|
149 |
|
[ ] Add rights for "Transform merge request in e-mail". |
|
150 |
|
[ ] Check if all forms keep old values in case of an error. |
|
151 |
|
[ ] Limit the number of e-mails to not flood the inbox. |
|
152 |
|
[ ] Record in some stats how long took a push in terms of cpu/time/etc. |
|
153 |
|
[ ] We should have a log with logins, not only last_login per user. |
|
154 |
|
So, we should have an event on login and explode it in several queries. |
|
155 |
|
Also session may be updated from this event, but still with a 1 min gap. |
|
156 |
|
[ ] Max number of users must be removed from repo. No need for it. |
|
157 |
|
[ ] Max commit size must be added per repo. |
|
158 |
|
[ ] A script to check if all CSS classes in templates are present in css file. |
|
159 |
|
[ ] Export/import a repo (xml maybe). |
28 |
160 |
[ ] Add groups. |
[ ] Add groups. |
29 |
161 |
[ ] We should warn the user if some users have lower rights than the default! |
[ ] We should warn the user if some users have lower rights than the default! |
30 |
162 |
[ ] Auto-create repos at clonse phase, not only at push phase. |
[ ] Auto-create repos at clonse phase, not only at push phase. |
|
39 |
171 |
[ ] SELinux: what about rocketgit_t access to postgresql through apache? |
[ ] SELinux: what about rocketgit_t access to postgresql through apache? |
40 |
172 |
[ ] Check why only 'tageted' policy is installed. |
[ ] Check why only 'tageted' policy is installed. |
41 |
173 |
[ ] Should I move the socket to /var/run (using tmp.d)? |
[ ] Should I move the socket to /var/run (using tmp.d)? |
42 |
|
[ ] Use (organization, user, repo) instead of user/repo only. |
|
43 |
174 |
[ ] Bug:List: saved searches with spaces inside the name are not correctly escaped. |
[ ] Bug:List: saved searches with spaces inside the name are not correctly escaped. |
44 |
175 |
Use _ instead of space, or properly escape it (ugly: %20 etc.)? |
Use _ instead of space, or properly escape it (ugly: %20 etc.)? |
45 |
176 |
[ ] "if ($res === FALSE) break" must set the error message! |
[ ] "if ($res === FALSE) break" must set the error message! |
46 |
177 |
[ ] Carefull order the events. We do not want to build list notifications |
[ ] Carefull order the events. We do not want to build list notifications |
47 |
178 |
before adding a user to the watch list. |
before adding a user to the watch list. |
48 |
179 |
[ ] If description is empty, do not insert a \n in 'new repo' e-mail. |
[ ] If description is empty, do not insert a \n in 'new repo' e-mail. |
49 |
|
[ ] Remove last form in PHP: user.form.php. |
|
50 |
180 |
[ ] Current menu is not correctly shown as selected. |
[ ] Current menu is not correctly shown as selected. |
51 |
181 |
[ ] If the confirmation code is truncated, an internal error is generated |
[ ] If the confirmation code is truncated, an internal error is generated |
52 |
182 |
instead of a user error! |
instead of a user error! |
|
85 |
215 |
[ ] We have a little problem: we need the ssh keyring to regenerate fast but |
[ ] We have a little problem: we need the ssh keyring to regenerate fast but |
86 |
216 |
we may have a big events queue. We may want to signal directly |
we may have a big events queue. We may want to signal directly |
87 |
217 |
the regeneration script and to not store mark-dirty state. Hm. |
the regeneration script and to not store mark-dirty state. Hm. |
88 |
|
[ ] Optimize keyring invalidation. |
|
89 |
|
[ ] Put "create user" on login page! |
|
|
218 |
|
[ ] Optimize keyring invalidation. Store in cache the ts of last regenerate and |
|
219 |
|
ignore request before that timestamp. |
90 |
220 |
[ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT. |
[ ] We should make stuff more robust. For example: CREATE REPO + HISTORY_INSERT. |
91 |
|
[ ] What happens if we unlock an unlocked resource? |
|
92 |
221 |
[ ] We have to record the renaming in the repo history. |
[ ] We have to record the renaming in the repo history. |
93 |
222 |
[ ] What happends if a user is doing a downgrade? Must not allow it. |
[ ] What happends if a user is doing a downgrade? Must not allow it. |
94 |
223 |
[ ] Use another home page for logged in users. |
[ ] Use another home page for logged in users. |
|
96 |
225 |
No. But use some combinations of paras. |
No. But use some combinations of paras. |
97 |
226 |
[ ] Why we use "FOR UPDATE" on 'events' table?! events.php is the only user. |
[ ] Why we use "FOR UPDATE" on 'events' table?! events.php is the only user. |
98 |
227 |
[ ] We need to parallelize the event processing. |
[ ] We need to parallelize the event processing. |
99 |
|
[ ] We need to add organization parameters next to repo_name! |
|
100 |
228 |
[ ] Check if there are unused parameters after name2base(_path). |
[ ] Check if there are unused parameters after name2base(_path). |
101 |
229 |
[ ] Remove any trace of $rr. |
[ ] Remove any trace of $rr. |
102 |
|
[ ] After the switch from username to uid, should we pass uid into forms? |
|
103 |
230 |
[ ] How to deal with browser accessing an old name (after rename)? |
[ ] How to deal with browser accessing an old name (after rename)? |
104 |
231 |
[ ] repo.php tests does not say "ok". |
[ ] repo.php tests does not say "ok". |
105 |
232 |
[ ] Functions from util.inc.php set rg_util_error(). Use it. |
[ ] Functions from util.inc.php set rg_util_error(). Use it. |
|
... |
... |
them after processing is done. |
125 |
252 |
[ ] Profiling in not reentrant. We should use a stack! |
[ ] Profiling in not reentrant. We should use a stack! |
126 |
253 |
[ ] We should not store repo_id0 into cache! |
[ ] We should not store repo_id0 into cache! |
127 |
254 |
[ ] We are redirecting the user to history page. Do not wait for git dir! |
[ ] We are redirecting the user to history page. Do not wait for git dir! |
128 |
|
[ ] Implement a cache like event.php. |
|
129 |
255 |
[ ] Set a policy in config.php and do the cleaning/compress of the log files. |
[ ] Set a policy in config.php and do the cleaning/compress of the log files. |
130 |
256 |
[ ] Fix the mail headers (+dkim) to avoid spam. |
[ ] Fix the mail headers (+dkim) to avoid spam. |
131 |
257 |
[ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu) |
[ ] http://joeyh.name/blog/entry/git_push_over_XMPP/ (ialbescu) |
|
... |
... |
them after processing is done. |
133 |
259 |
[ ] Add history also for user. |
[ ] Add history also for user. |
134 |
260 |
[ ] template_table can deal with a FALSE para: load error.html file in list/ |
[ ] template_table can deal with a FALSE para: load error.html file in list/ |
135 |
261 |
[ ] Put in history how many visitors received. |
[ ] Put in history how many visitors received. |
136 |
|
Maybe only whn hitting some limits? |
|
|
262 |
|
Maybe only when hitting some limits? |
137 |
263 |
[ ] Run shaX 1000 times for login? |
[ ] Run shaX 1000 times for login? |
138 |
264 |
[ ] There is no back button in tree browsing. |
[ ] There is no back button in tree browsing. |
139 |
265 |
[ ] Allow users to have templates repo to be used when creating a new repo. |
[ ] Allow users to have templates repo to be used when creating a new repo. |
140 |
266 |
Also define global templates. |
Also define global templates. |
141 |
|
[ ] In logs we should log the version! |
|
142 |
267 |
[ ] GeoIP |
[ ] GeoIP |
143 |
268 |
[ ] Specify a timeout for push/fetch. |
[ ] Specify a timeout for push/fetch. |
144 |
269 |
[ ] Describe also the instalation. |
[ ] Describe also the instalation. |
|
... |
... |
them after processing is done. |
147 |
272 |
[ ] Detect hexa strings and link them to commits. |
[ ] Detect hexa strings and link them to commits. |
148 |
273 |
[ ] Any user on a machine can look at repositories. |
[ ] Any user on a machine can look at repositories. |
149 |
274 |
Any user can connect to database. Fix also the README after fixing this. |
Any user can connect to database. Fix also the README after fixing this. |
150 |
|
[ ] Provide OpenVPN tunnels. |
|
|
275 |
|
[ ] (Commercially) Provide OpenVPN tunnels to be sure you can push/fetch safely. |
151 |
276 |
[ ] Errors should signal what field is not ok. |
[ ] Errors should signal what field is not ok. |
152 |
|
[ ] Replace all *.form.php with templates. |
|
153 |
277 |
[ ] Also log errmsg[] array! |
[ ] Also log errmsg[] array! |
154 |
278 |
[ ] Do we need subop=1 into login.html? |
[ ] Do we need subop=1 into login.html? |
155 |
|
[ ] Add possibility to donload the "CV" of a user. |
|
|
279 |
|
[ ] Add possibility to download the "CV" of a user. |
156 |
280 |
[ ] Happy birthday for projects/users/etc. |
[ ] Happy birthday for projects/users/etc. |
157 |
|
[ ] Check if if we remove rocketgit, the repos stay! |
|
|
281 |
|
[ ] Check if we remove rocketgit, the repos stay! |
158 |
282 |
[ ] Bug rights: add note, anonymous add note, add label, add global search. |
[ ] Bug rights: add note, anonymous add note, add label, add global search. |
159 |
283 |
[ ] Allow user to specify if is on windows/linux/etc. to be able to give |
[ ] Allow user to specify if is on windows/linux/etc. to be able to give |
160 |
|
specific hints. Hm. THe user may have multiple OSs. |
|
161 |
|
[ ] The selected menu is not colored different. |
|
|
284 |
|
specific hints. Hm. The user may have multiple OSs. |
162 |
285 |
[ ] http://rg.embedromix.ro:8000/user/catab/a13/admin/rights?edit_uid=19 |
[ ] http://rg.embedromix.ro:8000/user/catab/a13/admin/rights?edit_uid=19 |
163 |
286 |
should give an error! |
should give an error! |
164 |
287 |
[ ] Pay attention to: https://github.com/sitaramc/gitolite/wiki: |
[ ] Pay attention to: https://github.com/sitaramc/gitolite/wiki: |
|
... |
... |
them after processing is done. |
188 |
311 |
[ ] When repo is empty, we should not show the Log/Tree menu. |
[ ] When repo is empty, we should not show the Log/Tree menu. |
189 |
312 |
[ ] @@branch@@ is not defined for merge requests. Should it? Probably yes, to filter them. |
[ ] @@branch@@ is not defined for merge requests. Should it? Probably yes, to filter them. |
190 |
313 |
[ ] Fix diff output. Cannot deal with renames/removes/etc. |
[ ] Fix diff output. Cannot deal with renames/removes/etc. |
191 |
|
[ ] Check admin creatin of an account. |
|
|
314 |
|
[ ] Check admin creating of an account. |
192 |
315 |
[ ] Add possibility to reject merge requests, to apply, to delete etc. |
[ ] Add possibility to reject merge requests, to apply, to delete etc. |
193 |
316 |
[ ] Do we need to escape some chars in console (ssh rocketgit@host repo X)? |
[ ] Do we need to escape some chars in console (ssh rocketgit@host repo X)? |
194 |
317 |
[ ] We need to switch to a template for the user form to get rid of a lot of |
[ ] We need to switch to a template for the user form to get rid of a lot of |
195 |
318 |
mambo-jumbo with the _u array passed! |
mambo-jumbo with the _u array passed! |
196 |
319 |
[ ] Show the API on the webpage, exactly like Blender. |
[ ] Show the API on the webpage, exactly like Blender. |
197 |
|
[ ] We can pass in authorized_keys aslo the key id. Maybe for usage? |
|
198 |
320 |
[ ] Migrate to a single function to deal with a request so we can do better |
[ ] Migrate to a single function to deal with a request so we can do better |
199 |
321 |
unit testing. |
unit testing. |
200 |
322 |
[ ] We should have a 'policy' table where we have something like: |
[ ] We should have a 'policy' table where we have something like: |
|
... |
... |
them after processing is done. |
203 |
325 |
Example: user X paid some money, and we assign it to level 2 |
Example: user X paid some money, and we assign it to level 2 |
204 |
326 |
Level 2 has 4 users, max 100MiB disk space, 1Mbit/s speed. |
Level 2 has 4 users, max 100MiB disk space, 1Mbit/s speed. |
205 |
327 |
He creates a repo and assigns 2 users to it. |
He creates a repo and assigns 2 users to it. |
206 |
|
[ ] Notifications when disk space is low. |
|
|
328 |
|
[ ] Notifications when disk space is low. |
207 |
329 |
[ ] Check webSSO for authentification. |
[ ] Check webSSO for authentification. |
208 |
330 |
[ ] Check http://gitlist.org/ |
[ ] Check http://gitlist.org/ |
209 |
|
[ ] use do {} while(0) to respect profiling! |
|
210 |
331 |
[ ] Enforce Signoff-by lines per project (a new permission) |
[ ] Enforce Signoff-by lines per project (a new permission) |
211 |
332 |
= reject commits without signoff! |
= reject commits without signoff! |
212 |
333 |
Maybe, do it generic, allow a text field to enumerate what should be in a commit! |
Maybe, do it generic, allow a text field to enumerate what should be in a commit! |
|
... |
... |
them after processing is done. |
218 |
339 |
[ ] Merge requests e-mail: explanation of why to pull, diffstat! Maybe also the |
[ ] Merge requests e-mail: explanation of why to pull, diffstat! Maybe also the |
219 |
340 |
patch if is small. |
patch if is small. |
220 |
341 |
[ ] Check git-request-pull |
[ ] Check git-request-pull |
221 |
|
[ ] Show the size of a repository. Also when you ssh from terminal. |
|
222 |
|
See git-count-objects and http://stackoverflow.com/questions/8185276/find-size-of-git-repo. |
|
223 |
342 |
[ ] Logo for project. Blender? |
[ ] Logo for project. Blender? |
224 |
343 |
[ ] Default branch per project[/user]. |
[ ] Default branch per project[/user]. |
225 |
344 |
[ ] Main language of the project. |
[ ] Main language of the project. |
|
... |
... |
them after processing is done. |
228 |
347 |
|
|
229 |
348 |
== Normal priority == |
== Normal priority == |
230 |
349 |
[ ] |
[ ] |
231 |
|
[ ] Show last time use of a ssh key, or how many times was used, or both. |
|
232 |
350 |
[ ] Add hint about "ssh rocketgit@server" to quickly find status etc. |
[ ] Add hint about "ssh rocketgit@server" to quickly find status etc. |
233 |
351 |
[ ] rg_redirect does not record profiling information! |
[ ] rg_redirect does not record profiling information! |
234 |
352 |
[ ] git bundle |
[ ] git bundle |
235 |
353 |
[ ] How to sign merge requests?! |
[ ] How to sign merge requests?! |
236 |
|
[ ] Signal, with red, if a key was uploaded in the last X days. |
|
237 |
354 |
[ ] Store in a cookie the last uid used, and if > 0, lookup e-mail and prefill |
[ ] Store in a cookie the last uid used, and if > 0, lookup e-mail and prefill |
238 |
355 |
forgot password e-mail field. Not good. An attacker may iterate over all |
forgot password e-mail field. Not good. An attacker may iterate over all |
239 |
356 |
uids. But, with a token will be nice! |
uids. But, with a token will be nice! |
240 |
357 |
[ ] Yeah BitBucket's pricing is much better they only charge on the number of collaborators. |
[ ] Yeah BitBucket's pricing is much better they only charge on the number of collaborators. |
241 |
358 |
[ ] Permit "log" to see more rows. |
[ ] Permit "log" to see more rows. |
242 |
|
[ ] Allow admin to upload keys for a user. |
|
243 |
359 |
[ ] Make an option to not allow a client to upload keys. Why? |
[ ] Make an option to not allow a client to upload keys. Why? |
244 |
360 |
To restrict this to admin? |
To restrict this to admin? |
245 |
361 |
[ ] Can we bypass ssh auth to allow pushes? |
[ ] Can we bypass ssh auth to allow pushes? |
246 |
362 |
This way maybe we can identify client by fingerprint. |
This way maybe we can identify client by fingerprint. |
247 |
|
[ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renmaes, copies etc. |
|
|
363 |
|
[ ] Use rg_git_diff_tree to test for path based restrictions. Also, take care of renames, copies etc. |
248 |
364 |
[ ] See Gerrit: https://codereview.qt-project.org/#change,22764 |
[ ] See Gerrit: https://codereview.qt-project.org/#change,22764 |
249 |
365 |
[ ] user-conf: option: auto-create-repo-on-push |
[ ] user-conf: option: auto-create-repo-on-push |
250 |
366 |
[ ] Use git push to do all kind of commands: create repo, delete repo, update description etc. |
[ ] Use git push to do all kind of commands: create repo, delete repo, update description etc. |
251 |
|
[ ] Allow user to create a template for repositories. |
|
252 |
367 |
[ ] Optionally init a repo with some files (README, TODO etc.) |
[ ] Optionally init a repo with some files (README, TODO etc.) |
253 |
368 |
[ ] Check https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html |
[ ] Check https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html |
254 |
369 |
[ ] Add RocketGit to https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html |
[ ] Add RocketGit to https://git.wiki.kernel.org/articles/g/i/t/GitHosting_2036.html |
|
... |
... |
them after processing is done. |
257 |
372 |
[ ] Statistics (number, tool etc.) for project access. |
[ ] Statistics (number, tool etc.) for project access. |
258 |
373 |
[ ] For bugtracker use BerliOS as a starting point. |
[ ] For bugtracker use BerliOS as a starting point. |
259 |
374 |
[ ] Allow (anonymous) editing files on web and transform them in merge request. |
[ ] Allow (anonymous) editing files on web and transform them in merge request. |
|
375 |
|
How to bundle multiple edits in a single commit? |
260 |
376 |
[ ] On the first page no search form! It is useless! |
[ ] On the first page no search form! It is useless! |
261 |
377 |
[ ] Add stats for a repo. Some stuff is already in git.inc.php. |
[ ] Add stats for a repo. Some stuff is already in git.inc.php. |
262 |
378 |
[ ] Anti-spam: hide e-mail addresses! |
[ ] Anti-spam: hide e-mail addresses! |
|
... |
... |
them after processing is done. |
267 |
383 |
[ ] Order tags by mtime desc. |
[ ] Order tags by mtime desc. |
268 |
384 |
[ ] rg_repos should be split in rg_repos and rg_var_lib. |
[ ] rg_repos should be split in rg_repos and rg_var_lib. |
269 |
385 |
[ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced! |
[ ] $blocks = explode("@@left@@-=ROCKETGIT=-@@left@@", $a) - seems that \0 is replaced! |
270 |
|
[ ] Changing repo name probably is not working right. |
|
271 |
386 |
[ ] Check XSRF attacks and other types. |
[ ] Check XSRF attacks and other types. |
272 |
387 |
[ ] Validate e-mails. |
[ ] Validate e-mails. |
273 |
388 |
[ ] Take care of PHP's time limit to not interfere with the rest. |
[ ] Take care of PHP's time limit to not interfere with the rest. |
274 |
|
[ ] Run update.php before rpm upgrade the scripts. |
|
275 |
|
[ ] Store by uid the repos, and make links to them. Make a function to rename |
|
276 |
|
a username. We have to keep track of renames so old links will |
|
277 |
|
still work. |
|
278 |
389 |
[ ] Differentiate between owner of a repository, currently logged in user and admin. |
[ ] Differentiate between owner of a repository, currently logged in user and admin. |
279 |
390 |
[ ] Warn before deleting a repo! |
[ ] Warn before deleting a repo! |
280 |
391 |
[ ] Switch all menus to templates. |
[ ] Switch all menus to templates. |
|
... |
... |
them after processing is done. |
285 |
396 |
[ ] admin: "Lock all accounts" and "Reset password for all accounts and send mail". |
[ ] admin: "Lock all accounts" and "Reset password for all accounts and send mail". |
286 |
397 |
[ ] rg_repo_allow seems to not be used. |
[ ] rg_repo_allow seems to not be used. |
287 |
398 |
[ ] Get memory statistics from /proc. |
[ ] Get memory statistics from /proc. |
288 |
|
[ ] Delay connection to database. |
|
289 |
399 |
[ ] Add support for refs/notes/ pushes. |
[ ] Add support for refs/notes/ pushes. |
290 |
400 |
[ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_. |
[ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_. |
291 |
401 |
[ ] Ask password when doing any critical change of the account and send mail. |
[ ] Ask password when doing any critical change of the account and send mail. |
292 |
|
[ ] Add commercial posibility for VPNs to be sure you can push/fetch safely. |
|
293 |
402 |
[ ] Add a possibility (link shown in push message) to delete/update/etc. the |
[ ] Add a possibility (link shown in push message) to delete/update/etc. the |
294 |
403 |
merge request. |
merge request. |
295 |
404 |
[ ] Allow a nonstandard port for web. |
[ ] Allow a nonstandard port for web. |
|
... |
... |
them after processing is done. |
306 |
415 |
Only owner will have access. |
Only owner will have access. |
307 |
416 |
We may add also a text that will be output to clients. |
We may add also a text that will be output to clients. |
308 |
417 |
[ ] List chages introduced by a merge: git diff-tree --always [--cc] -m -p f7d5b5770f4c6b5a124dad6358bed310d56bf909 |
[ ] List chages introduced by a merge: git diff-tree --always [--cc] -m -p f7d5b5770f4c6b5a124dad6358bed310d56bf909 |
309 |
|
[ ] ACL per IP (only for private repos). |
|
310 |
418 |
[ ] Check pack-protocol.txt! |
[ ] Check pack-protocol.txt! |
311 |
419 |
[ ] When push is executed with success, show a nice message from RocketGit. |
[ ] When push is executed with success, show a nice message from RocketGit. |
312 |
420 |
[ ] Move is_private member in repo array, not test for empty on default rights |
[ ] Move is_private member in repo array, not test for empty on default rights |
|
... |
... |
them after processing is done. |
318 |
426 |
Disk space accounting? |
Disk space accounting? |
319 |
427 |
[ ] We should make a repo dirty only if user pushed something with success. |
[ ] We should make a repo dirty only if user pushed something with success. |
320 |
428 |
[ ] <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNrgAWjYBSMArgAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNrgJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNrgAWjYBSMArgAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNrgAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/> |
[ ] <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNrgAWjYBSMArgAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNrgJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNrgAWjYBSMArgAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNrgAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/> |
321 |
|
[ ] "Add key" form may be joined with list keys command! |
|
322 |
429 |
[ ] Allow to recover a deleted repository. |
[ ] Allow to recover a deleted repository. |
323 |
430 |
[ ] Deny access in all functions to deleted repositories. |
[ ] Deny access in all functions to deleted repositories. |
324 |
431 |
[ ] Count the numbers of clones/pushes/pulls. |
[ ] Count the numbers of clones/pushes/pulls. |
325 |
|
[ ] Add memcache caching for all database lookups. |
|
326 |
432 |
[ ] Allow to configure the limit of the patch size to prevent abuses. |
[ ] Allow to configure the limit of the patch size to prevent abuses. |
327 |
433 |
[ ] Allow to configure to refuse binary files. |
[ ] Allow to configure to refuse binary files. |
328 |
|
[ ] Add a repo_prop_set/get function that will set/get a file in .git folder. |
|
329 |
|
This way we can speed up some lookups (no need for database). Hm. |
|
330 |
|
[ ] When we delete a repository, we will do repo_prop_set(repo, disabled) and we will |
|
331 |
|
return OK, in the background we will do the removing. |
|
332 |
|
Do not forget to also remove clones. Hm. |
|
333 |
434 |
[ ] E-mail aliases section. |
[ ] E-mail aliases section. |
334 |
435 |
[ ] User details section (blog, avatar, mail notifications). |
[ ] User details section (blog, avatar, mail notifications). |
335 |
|
[ ] Check if user is over-quota on push. |
|
336 |
|
[ ] The cron will have to: |
|
337 |
|
[ ] Compute disk usage, ignoring hard links. Hm. Probably we will add |
|
338 |
|
only the owner, even if the files have multiple links. TBD. |
|
339 |
|
[ ] |
|
340 |
436 |
[ ] UTF-8 checks of patches. |
[ ] UTF-8 checks of patches. |
341 |
437 |
[ ] W3C validation on all pages. |
[ ] W3C validation on all pages. |
342 |
438 |
[ ] Validate user and repo names. Probably other things. |
[ ] Validate user and repo names. Probably other things. |
|
... |
... |
them after processing is done. |
354 |
450 |
[ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ to block updates that have not pull - a la SVN |
[ ] Check http://plathrop.tertiusfamily.net/blog/2010/05/11/git-hooks-branch-acls-and-more/ to block updates that have not pull - a la SVN |
355 |
451 |
[ ] Maybe we should mark the repository as dirty, only in the post-receive hook? Or update is the best place? |
[ ] Maybe we should mark the repository as dirty, only in the post-receive hook? Or update is the best place? |
356 |
452 |
[ ] Limit number of commits per push. |
[ ] Limit number of commits per push. |
357 |
|
[ ] Compute disk_used_mb per user. |
|
358 |
|
[ ] Enforce disk quota. |
|
359 |
453 |
[ ] RSS |
[ ] RSS |
360 |
454 |
[ ] Config file must be able to be set from a env var, to be able to run |
[ ] Config file must be able to be set from a env var, to be able to run |
361 |
455 |
multiple instances of rocketgit on the same server. |
multiple instances of rocketgit on the same server. |
|
... |
... |
them after processing is done. |
371 |
465 |
[ ] git-notes may be used to attach messages to commits. Nice. |
[ ] git-notes may be used to attach messages to commits. Nice. |
372 |
466 |
[ ] Store also the size of the patch along history/commit info. |
[ ] Store also the size of the patch along history/commit info. |
373 |
467 |
[ ] Check SELinux MLS |
[ ] Check SELinux MLS |
374 |
|
[ ] Test if 'first_install' state is working correctly. |
|
375 |
468 |
[ ] Deal with empty repositories (rg_git_ls_tree etc.). |
[ ] Deal with empty repositories (rg_git_ls_tree etc.). |
376 |
469 |
[ ] Show age of an user/org/repo. Example: 1 year, 3 months, 4 days. |
[ ] Show age of an user/org/repo. Example: 1 year, 3 months, 4 days. |
377 |
470 |
[ ] The rewrite engine should pass a single op for user and for org, but with |
[ ] The rewrite engine should pass a single op for user and for org, but with |
|
... |
... |
them after processing is done. |
398 |
491 |
automatically to the specified queues. |
automatically to the specified queues. |
399 |
492 |
[ ] At push time we may generate some nice informative output (commits, |
[ ] At push time we may generate some nice informative output (commits, |
400 |
493 |
last time when current user commited etc.) |
last time when current user commited etc.) |
401 |
|
[ ] Team suports |
|
402 |
494 |
[ ] Bulk add users/teams/repos/bugs/etc. |
[ ] Bulk add users/teams/repos/bugs/etc. |
403 |
495 |
|
|
404 |
496 |
== Low priority == |
== Low priority == |
|
... |
... |
them after processing is done. |
422 |
514 |
* |
* |
423 |
515 |
|
|
424 |
516 |
|
|
425 |
|
== Rights management - to be implemented == |
|
426 |
|
|
|
427 |
|
- A user is trying to push some commits in a branch B, for a file F |
|
428 |
|
- The set of rights may be: |
|
429 |
|
Branch File Rights |
|
430 |
|
B2 dir/*.png FPA |
|
431 |
|
* dir2 A |
|
432 |
|
* * F |
|
File inc/bug.inc.php changed (mode: 100644) (index 679ef0d..1cb7d2c) |
... |
... |
function rg_bug_next_id($db, $repo_id) |
210 |
210 |
|
|
211 |
211 |
$next_bug_id = FALSE; |
$next_bug_id = FALSE; |
212 |
212 |
do { |
do { |
|
213 |
|
$params = array($repo_id); |
213 |
214 |
$sql = "UPDATE bugs_max SET last_bug_id = last_bug_id + 1" |
$sql = "UPDATE bugs_max SET last_bug_id = last_bug_id + 1" |
214 |
|
. " WHERE repo_id = $repo_id" |
|
|
215 |
|
. " WHERE repo_id = $1" |
215 |
216 |
. " RETURNING last_bug_id AS next_bug_id"; |
. " RETURNING last_bug_id AS next_bug_id"; |
216 |
|
$res = rg_sql_query($db, $sql); |
|
|
217 |
|
$res = rg_sql_query_params($db, $sql, $params); |
217 |
218 |
if ($res === FALSE) { |
if ($res === FALSE) { |
218 |
219 |
rg_bug_set_error("cannot get/update max (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot get/update max (" . rg_sql_error() . ")"); |
219 |
220 |
break; |
break; |
|
... |
... |
function rg_bug_next_id($db, $repo_id) |
244 |
245 |
* and we obtain the lock. So, we have to check if a insert |
* and we obtain the lock. So, we have to check if a insert |
245 |
246 |
* took place. |
* took place. |
246 |
247 |
*/ |
*/ |
247 |
|
$sql = "SELECT 1 FROM bugs_max WHERE repo_id = $repo_id"; |
|
248 |
|
$res = rg_sql_query($db, $sql); |
|
|
248 |
|
$params = array($repo_id); |
|
249 |
|
$sql = "SELECT 1 FROM bugs_max WHERE repo_id = $1"; |
|
250 |
|
$res = rg_sql_query_params($db, $sql, $params); |
249 |
251 |
if ($res === FALSE) { |
if ($res === FALSE) { |
250 |
252 |
rg_bug_set_error("cannot select 1 from max table (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot select 1 from max table (" . rg_sql_error() . ")"); |
251 |
253 |
break; |
break; |
|
... |
... |
function rg_bug_next_id($db, $repo_id) |
255 |
257 |
|
|
256 |
258 |
if ($rows == 0) { |
if ($rows == 0) { |
257 |
259 |
// We were faster, just insert. |
// We were faster, just insert. |
|
260 |
|
$params = array($repo_id); |
258 |
261 |
$sql = "INSERT INTO bugs_max (repo_id, last_bug_id)" |
$sql = "INSERT INTO bugs_max (repo_id, last_bug_id)" |
259 |
|
. " VALUES ($repo_id, 1)"; |
|
260 |
|
$res = rg_sql_query($db, $sql); |
|
|
262 |
|
. " VALUES ($1, 1)"; |
|
263 |
|
$res = rg_sql_query_params($db, $sql, $params); |
261 |
264 |
if ($res === FALSE) { |
if ($res === FALSE) { |
262 |
265 |
rg_bug_set_error("cannot insert into max table (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot insert into max table (" . rg_sql_error() . ")"); |
263 |
266 |
break; |
break; |
|
... |
... |
function rg_bug_info($db, $repo_id, $bug_id) |
358 |
361 |
break; |
break; |
359 |
362 |
} |
} |
360 |
363 |
|
|
|
364 |
|
$params = array($repo_id, $bug_id); |
361 |
365 |
$sql = "SELECT * FROM bugs" |
$sql = "SELECT * FROM bugs" |
362 |
|
. " WHERE repo_id = " . $repo_id |
|
363 |
|
. " AND bug_id = " . $bug_id; |
|
364 |
|
$res = rg_sql_query($db, $sql); |
|
|
366 |
|
. " WHERE repo_id = $1" |
|
367 |
|
. " AND bug_id = $2"; |
|
368 |
|
$res = rg_sql_query_params($db, $sql, $params); |
365 |
369 |
if ($res === FALSE) { |
if ($res === FALSE) { |
366 |
370 |
rg_bug_set_error("cannot list bugs (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot list bugs (" . rg_sql_error() . ")"); |
367 |
371 |
break; |
break; |
|
... |
... |
function rg_bug_edit($db, $ri, $login_ui, $data) |
396 |
400 |
|
|
397 |
401 |
// TODO: test if user is allowed to add/edit a bug |
// TODO: test if user is allowed to add/edit a bug |
398 |
402 |
|
|
399 |
|
$e_data = $data; |
|
400 |
|
$e_data['title'] = rg_sql_escape($db, $data['title']); |
|
401 |
|
$e_data['body'] = rg_sql_escape($db, $data['body']); |
|
402 |
|
$e_data['state'] = sprintf("%u", $data['state']); |
|
403 |
|
$e_data['labels'] = isset($data['labels']) ? rg_sql_escape($db, $data['labels']) : ""; |
|
|
403 |
|
$data['labels'] = isset($data['labels']) ? $data['labels'] : ""; |
404 |
404 |
|
|
405 |
405 |
$itime = time(); |
$itime = time(); |
406 |
406 |
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ""; |
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ""; |
|
... |
... |
function rg_bug_edit($db, $ri, $login_ui, $data) |
458 |
458 |
} |
} |
459 |
459 |
|
|
460 |
460 |
if ($data['bug_id'] == 0) { |
if ($data['bug_id'] == 0) { |
|
461 |
|
$params = array($bug_id, $itime, $ri['repo_id'], |
|
462 |
|
$login_ui['uid'], $ip, $data['title'], |
|
463 |
|
$data['body'], $data['state'], $assigned_uid); |
461 |
464 |
$sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id" |
$sql = "INSERT INTO bugs (bug_id, itime, utime, repo_id" |
462 |
465 |
. ", uid, ip, title, body, state, assigned_uid" |
. ", uid, ip, title, body, state, assigned_uid" |
463 |
466 |
. ", deleted)" |
. ", deleted)" |
464 |
|
. " VALUES ($bug_id, $itime, 0" |
|
465 |
|
. ", " . $ri['repo_id'] |
|
466 |
|
. ", " . $login_ui['uid'] |
|
467 |
|
. ", '$ip', '" . $e_data['title'] . "'" |
|
468 |
|
. ", '" . $e_data['body'] . "'" |
|
469 |
|
. ", " . $e_data['state'] |
|
470 |
|
. ", " . $assigned_uid |
|
471 |
|
. ", 0)"; |
|
|
467 |
|
. " VALUES ($1, $2, 0, $3, $4, $5, $6, $7, $8, $9, 0)"; |
472 |
468 |
} else { |
} else { |
473 |
|
$sql = "UPDATE bugs SET utime = $itime" |
|
474 |
|
. ", title = '" . $e_data['title'] . "'" |
|
475 |
|
. ", body = '" . $e_data['body'] . "'" |
|
476 |
|
. ", state = " . $e_data['state'] |
|
477 |
|
. ", assigned_uid = " . $assigned_uid |
|
478 |
|
. " WHERE repo_id = " . $ri['repo_id'] |
|
479 |
|
. " AND bug_id = $bug_id"; |
|
|
469 |
|
$params = array($itime, $data['title'], $data['body'], |
|
470 |
|
$data['state'], $assigned_uid, $ri['repo_id'], |
|
471 |
|
$bug_id); |
|
472 |
|
$sql = "UPDATE bugs SET utime = $1" |
|
473 |
|
. ", title = $2" |
|
474 |
|
. ", body = $3" |
|
475 |
|
. ", state = $4" |
|
476 |
|
. ", assigned_uid = $5" |
|
477 |
|
. " WHERE repo_id = $6" |
|
478 |
|
. " AND bug_id = $7"; |
480 |
479 |
} |
} |
481 |
|
$res = rg_sql_query($db, $sql); |
|
|
480 |
|
$res = rg_sql_query_params($db, $sql, $params); |
482 |
481 |
if ($res === FALSE) { |
if ($res === FALSE) { |
483 |
482 |
rg_bug_set_error("cannot insert bug (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot insert bug (" . rg_sql_error() . ")"); |
484 |
483 |
break; |
break; |
|
... |
... |
function rg_bug_delete($db, $repo_id, $bug_id) |
553 |
552 |
$now = time(); |
$now = time(); |
554 |
553 |
|
|
555 |
554 |
// Only mark it as such, deletion will happen in background |
// Only mark it as such, deletion will happen in background |
556 |
|
$sql = "UPDATE bugs SET deleted = $now" |
|
557 |
|
. " WHERE repo_id = $repo_id" |
|
558 |
|
. " AND bug_id = $bug_id"; |
|
559 |
|
$res = rg_sql_query($db, $sql); |
|
|
555 |
|
$params = array($now, $repo_id, $bug_id); |
|
556 |
|
$sql = "UPDATE bugs SET deleted = $1" |
|
557 |
|
. " WHERE repo_id = $2" |
|
558 |
|
. " AND bug_id = $3"; |
|
559 |
|
$res = rg_sql_query_params($db, $sql, $params); |
560 |
560 |
if ($res === FALSE) { |
if ($res === FALSE) { |
561 |
561 |
rg_bug_set_error("Cannot delete bug (" . rg_sql_error() . ")"); |
rg_bug_set_error("Cannot delete bug (" . rg_sql_error() . ")"); |
562 |
562 |
break; |
break; |
|
... |
... |
function rg_bug_delete($db, $repo_id, $bug_id) |
572 |
572 |
/* |
/* |
573 |
573 |
* List bugs |
* List bugs |
574 |
574 |
*/ |
*/ |
575 |
|
function rg_bug_list_query($db, $sql) |
|
|
575 |
|
function rg_bug_list_query($db, $sql, $params) |
576 |
576 |
{ |
{ |
577 |
577 |
rg_prof_start("bug_list_query"); |
rg_prof_start("bug_list_query"); |
578 |
578 |
rg_log("bug_list_query: sql=$sql..."); |
rg_log("bug_list_query: sql=$sql..."); |
579 |
579 |
|
|
580 |
580 |
$ret = FALSE; |
$ret = FALSE; |
581 |
581 |
do { |
do { |
582 |
|
$res = rg_sql_query($db, $sql); |
|
|
582 |
|
$res = rg_sql_query_params($db, $sql, $params); |
583 |
583 |
if ($res === FALSE) { |
if ($res === FALSE) { |
584 |
584 |
rg_bug_set_error("cannot list by query (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot list by query (" . rg_sql_error() . ")"); |
585 |
585 |
break; |
break; |
|
... |
... |
function rg_bug_search_load_all($db, $repo_id, $uid) |
608 |
608 |
|
|
609 |
609 |
$ret = FALSE; |
$ret = FALSE; |
610 |
610 |
do { |
do { |
|
611 |
|
$params = array($repo_id, $uid); |
611 |
612 |
$sql = "SELECT name FROM bug_search" |
$sql = "SELECT name FROM bug_search" |
612 |
|
. " WHERE (repo_id = $repo_id OR repo_id = 0)" |
|
613 |
|
. " AND uid = $uid" |
|
|
613 |
|
. " WHERE (repo_id = $1 OR repo_id = 0)" |
|
614 |
|
. " AND uid = $2" |
614 |
615 |
. " ORDER BY repo_id, name"; |
. " ORDER BY repo_id, name"; |
615 |
|
$res = rg_sql_query($db, $sql); |
|
|
616 |
|
$res = rg_sql_query_params($db, $sql, $params); |
616 |
617 |
if ($res === FALSE) { |
if ($res === FALSE) { |
617 |
618 |
rg_bug_set_error("cannot load searches (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot load searches (" . rg_sql_error() . ")"); |
618 |
619 |
break; |
break; |
|
... |
... |
function rg_bug_search_load($db, $repo_id, $uid, $name) |
682 |
683 |
break; |
break; |
683 |
684 |
} |
} |
684 |
685 |
|
|
685 |
|
$e_name = rg_sql_escape($db, $name); |
|
686 |
|
|
|
|
686 |
|
$params = array($repo_id, $uid, $name); |
687 |
687 |
$sql = "SELECT uid, name, data, for_all_users" |
$sql = "SELECT uid, name, data, for_all_users" |
688 |
688 |
. " FROM bug_search" |
. " FROM bug_search" |
689 |
|
. " WHERE (repo_id = $repo_id OR repo_id = 0)" |
|
690 |
|
. " AND (uid = $uid OR for_all_users = 1)" |
|
691 |
|
. " AND name = '$e_name'" |
|
|
689 |
|
. " WHERE (repo_id = $1 OR repo_id = 0)" |
|
690 |
|
. " AND (uid = $2 OR for_all_users = 1)" |
|
691 |
|
. " AND name = $3" |
692 |
692 |
. " ORDER BY name"; |
. " ORDER BY name"; |
693 |
|
$res = rg_sql_query($db, $sql); |
|
|
693 |
|
$res = rg_sql_query_params($db, $sql, $params); |
694 |
694 |
if ($res === FALSE) { |
if ($res === FALSE) { |
695 |
695 |
rg_bug_set_error("cannot search load (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot search load (" . rg_sql_error() . ")"); |
696 |
696 |
break; |
break; |
|
... |
... |
function rg_bug_search_save($db, $repo_id, $uid, $q) |
739 |
739 |
if ($old === FALSE) |
if ($old === FALSE) |
740 |
740 |
break; |
break; |
741 |
741 |
|
|
742 |
|
$s = serialize($q); |
|
743 |
|
$e_data = rg_sql_escape($db, $s); |
|
744 |
|
$e_name = rg_sql_escape($db, $name); |
|
|
742 |
|
$data = serialize($q); |
745 |
743 |
|
|
746 |
744 |
// Global? |
// Global? |
747 |
745 |
if (isset($q['global']) && (strcmp($q['global'], "on") == 0)) |
if (isset($q['global']) && (strcmp($q['global'], "on") == 0)) |
748 |
|
$e_repo_id = 0; |
|
|
746 |
|
$repo_id = 0; |
749 |
747 |
else |
else |
750 |
|
$e_repo_id = $repo_id; |
|
|
748 |
|
$repo_id = $repo_id; |
751 |
749 |
|
|
752 |
750 |
if (isset($q['for_all_users']) && (strcmp($q['for_all_users'], "on") == 0)) |
if (isset($q['for_all_users']) && (strcmp($q['for_all_users'], "on") == 0)) |
753 |
|
$e_for_all_users = 1; |
|
|
751 |
|
$for_all_users = 1; |
754 |
752 |
else |
else |
755 |
|
$e_for_all_users = 0; |
|
|
753 |
|
$for_all_users = 0; |
756 |
754 |
|
|
757 |
755 |
// We will not overwrite somebody else's search |
// We will not overwrite somebody else's search |
|
756 |
|
// TODO: race? |
758 |
757 |
rg_log("DEBUG: old: " . rg_array2string($old)); |
rg_log("DEBUG: old: " . rg_array2string($old)); |
759 |
758 |
if (empty($old) || ($old['uid'] != $uid)) { |
if (empty($old) || ($old['uid'] != $uid)) { |
|
759 |
|
$params = array($repo_id, $uid, $name, $data, $for_all_users); |
760 |
760 |
$sql = "INSERT INTO bug_search (repo_id, uid, name" |
$sql = "INSERT INTO bug_search (repo_id, uid, name" |
761 |
761 |
. ", data, for_all_users)" |
. ", data, for_all_users)" |
762 |
|
. " VALUES ($e_repo_id, $uid, '$e_name'" |
|
763 |
|
. ", '$e_data', $e_for_all_users)"; |
|
|
762 |
|
. " VALUES ($1, $2, $3, $4, $5)"; |
764 |
763 |
} else { |
} else { |
|
764 |
|
$params = array($data, $for_all_users, $repo_id, $uid, $name); |
765 |
765 |
$sql = "UPDATE bug_search" |
$sql = "UPDATE bug_search" |
766 |
|
. " SET data = '$e_data'" |
|
767 |
|
. ", for_all_users = $e_for_all_users" |
|
768 |
|
. " WHERE repo_id = $e_repo_id" |
|
769 |
|
. " AND uid = $uid" |
|
770 |
|
. " AND name = '$e_name'"; |
|
|
766 |
|
. " SET data = $1" |
|
767 |
|
. ", for_all_users = $2" |
|
768 |
|
. " WHERE repo_id = $3" |
|
769 |
|
. " AND uid = $4" |
|
770 |
|
. " AND name = $5"; |
771 |
771 |
} |
} |
772 |
|
$res = rg_sql_query($db, $sql); |
|
|
772 |
|
$res = rg_sql_query_params($db, $sql, $params); |
773 |
773 |
if ($res === FALSE) { |
if ($res === FALSE) { |
774 |
774 |
rg_bug_set_error("cannot save search (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot save search (" . rg_sql_error() . ")"); |
775 |
775 |
break; |
break; |
|
... |
... |
function rg_bug_search($db, $repo_id, $uid, $q) |
802 |
802 |
rg_bug_set_error("cannot lookup user (reported_by)"); |
rg_bug_set_error("cannot lookup user (reported_by)"); |
803 |
803 |
break; |
break; |
804 |
804 |
} |
} |
805 |
|
$add[] = "uid = " . $_ui['uid']; |
|
|
805 |
|
$add[] = "AND uid = " . $_ui['uid']; |
806 |
806 |
} |
} |
807 |
807 |
|
|
808 |
808 |
// assigned to |
// assigned to |
|
... |
... |
function rg_bug_search($db, $repo_id, $uid, $q) |
862 |
862 |
break; |
break; |
863 |
863 |
} |
} |
864 |
864 |
|
|
|
865 |
|
$params = array($repo_id); |
865 |
866 |
$sql = "SELECT * FROM bugs" |
$sql = "SELECT * FROM bugs" |
866 |
|
. " WHERE repo_id = $repo_id" |
|
|
867 |
|
. " WHERE repo_id = $1" |
867 |
868 |
. " AND deleted = 0" |
. " AND deleted = 0" |
868 |
869 |
. " " . implode(" ", $add) |
. " " . implode(" ", $add) |
869 |
870 |
. " ORDER BY itime" |
. " ORDER BY itime" |
|
... |
... |
function rg_bug_search($db, $repo_id, $uid, $q) |
871 |
872 |
|
|
872 |
873 |
// TODO: order |
// TODO: order |
873 |
874 |
|
|
874 |
|
$ret = rg_bug_list_query($db, $sql); |
|
|
875 |
|
$ret = rg_bug_list_query($db, $sql, $params); |
875 |
876 |
if ($ret === FALSE) |
if ($ret === FALSE) |
876 |
877 |
break; |
break; |
877 |
878 |
} while (0); |
} while (0); |
|
... |
... |
function rg_bug_search_remove($db, $repo_id, $uid, $name) |
891 |
892 |
|
|
892 |
893 |
$ret = FALSE; |
$ret = FALSE; |
893 |
894 |
do { |
do { |
894 |
|
$e_name = rg_sql_escape($db, $name); |
|
895 |
|
|
|
|
895 |
|
$params = array($repo_id, $uid, $name); |
896 |
896 |
$sql = "DELETE FROM bug_search" |
$sql = "DELETE FROM bug_search" |
897 |
|
. " WHERE repo_id = $repo_id" |
|
898 |
|
. " AND uid = $uid" |
|
899 |
|
. " AND name = '$e_name'"; |
|
900 |
|
$res = rg_sql_query($db, $sql); |
|
|
897 |
|
. " WHERE repo_id = $1" |
|
898 |
|
. " AND uid = $2" |
|
899 |
|
. " AND name = $3"; |
|
900 |
|
$res = rg_sql_query_params($db, $sql, $params); |
901 |
901 |
if ($res === FALSE) { |
if ($res === FALSE) { |
902 |
902 |
rg_bug_set_error("cannot remove search (" . rg_sql_error() . ")"); |
rg_bug_set_error("cannot remove search (" . rg_sql_error() . ")"); |
903 |
903 |
break; |
break; |
|
... |
... |
function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data) |
925 |
925 |
do { |
do { |
926 |
926 |
// TODO: test if user is allowed to add a note |
// TODO: test if user is allowed to add a note |
927 |
927 |
|
|
928 |
|
$e_data = $data; |
|
929 |
|
$e_data['note'] = rg_sql_escape($db, trim($data['note'])); |
|
930 |
|
|
|
931 |
928 |
$itime = time(); |
$itime = time(); |
932 |
929 |
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?"; |
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "?"; |
933 |
930 |
|
|
|
931 |
|
$params = array($repo_id, $bug_id, $itime, $login_uid, $ip, |
|
932 |
|
$data['note']); |
934 |
933 |
$sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip" |
$sql = "INSERT INTO bug_notes (repo_id, bug_id, itime, uid, ip" |
935 |
934 |
. ", note)" |
. ", note)" |
936 |
|
. " VALUES ($repo_id, $bug_id, $itime, $login_uid, '$ip'" |
|
937 |
|
. ", '" . $e_data['note'] . "')"; |
|
938 |
|
$res = rg_sql_query($db, $sql); |
|
|
935 |
|
. " VALUES ($1, $2, $3, $4, $5, $6)"; |
|
936 |
|
$res = rg_sql_query_params($db, $sql, $params); |
939 |
937 |
if ($res === FALSE) { |
if ($res === FALSE) { |
940 |
938 |
rg_bug_set_error("Cannot insert bug note (" . rg_sql_error() . ")"); |
rg_bug_set_error("Cannot insert bug note (" . rg_sql_error() . ")"); |
941 |
939 |
break; |
break; |
|
... |
... |
function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data) |
948 |
946 |
. " (" . rg_repo_error() . ")"); |
. " (" . rg_repo_error() . ")"); |
949 |
947 |
break; |
break; |
950 |
948 |
} |
} |
|
949 |
|
rg_log_ml("_ri: " . print_r($_ri, TRUE)); |
951 |
950 |
|
|
952 |
951 |
$_bi = rg_bug_info($db, $repo_id, $bug_id); |
$_bi = rg_bug_info($db, $repo_id, $bug_id); |
953 |
952 |
if ($_bi === FALSE) |
if ($_bi === FALSE) |
|
... |
... |
function rg_bug_note_list($db, $repo_id, $bug_id, $offset) |
996 |
995 |
do { |
do { |
997 |
996 |
// TODO: test if user is allowed to see a note |
// TODO: test if user is allowed to see a note |
998 |
997 |
|
|
|
998 |
|
$params = array($repo_id, $bug_id); |
999 |
999 |
$sql = "SELECT * FROM bug_notes" |
$sql = "SELECT * FROM bug_notes" |
1000 |
|
. " WHERE repo_id = $repo_id" |
|
1001 |
|
. " AND bug_id = $bug_id" |
|
|
1000 |
|
. " WHERE repo_id = $1" |
|
1001 |
|
. " AND bug_id = $2" |
1002 |
1002 |
. " ORDER BY itime" |
. " ORDER BY itime" |
1003 |
1003 |
. " OFFSET $offset"; |
. " OFFSET $offset"; |
1004 |
|
$res = rg_sql_query($db, $sql); |
|
|
1004 |
|
$res = rg_sql_query_params($db, $sql, $params); |
1005 |
1005 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1006 |
1006 |
rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")"); |
rg_bug_set_error("Cannot select bug notes (" . rg_sql_error() . ")"); |
1007 |
1007 |
break; |
break; |
|
... |
... |
function rg_bug_label_get($db, $repo_id, $bug_id) |
1090 |
1090 |
|
|
1091 |
1091 |
$ret = FALSE; |
$ret = FALSE; |
1092 |
1092 |
do { |
do { |
|
1093 |
|
$params = array($repo_id, $bug_id); |
1093 |
1094 |
$sql = "SELECT DISTINCT label FROM bug_labels" |
$sql = "SELECT DISTINCT label FROM bug_labels" |
1094 |
|
. " WHERE repo_id = $repo_id" |
|
1095 |
|
. " AND bug_id = $bug_id" |
|
|
1095 |
|
. " WHERE repo_id = $1" |
|
1096 |
|
. " AND bug_id = $2" |
1096 |
1097 |
. " ORDER BY label"; |
. " ORDER BY label"; |
1097 |
|
$res = rg_sql_query($db, $sql); |
|
|
1098 |
|
$res = rg_sql_query_params($db, $sql, $params); |
1098 |
1099 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1099 |
1100 |
rg_bug_set_error("Cannot select labels (" . rg_sql_error() . ")"); |
rg_bug_set_error("Cannot select labels (" . rg_sql_error() . ")"); |
1100 |
1101 |
break; |
break; |
|
... |
... |
function rg_bug_label_insert($db, $repo_id, $bug_id, $labels) |
1138 |
1139 |
break; |
break; |
1139 |
1140 |
} |
} |
1140 |
1141 |
|
|
|
1142 |
|
// TODO: switch to params |
1141 |
1143 |
$list = array(); |
$list = array(); |
1142 |
1144 |
foreach ($diff as $label) { |
foreach ($diff as $label) { |
1143 |
1145 |
$e_label = rg_sql_escape($db, $label); |
$e_label = rg_sql_escape($db, $label); |
1144 |
1146 |
$list[] = "($repo_id, $bug_id, '$e_label')"; |
$list[] = "($repo_id, $bug_id, '$e_label')"; |
1145 |
1147 |
} |
} |
1146 |
1148 |
$sql = "INSERT INTO bug_labels (repo_id, bug_id, label)" |
$sql = "INSERT INTO bug_labels (repo_id, bug_id, label)" |
1147 |
|
. " VALUES " . implode(",", $list); |
|
|
1149 |
|
. " VALUES " . implode(", ", $list); |
1148 |
1150 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
1149 |
1151 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1150 |
1152 |
rg_bug_set_error("Cannot insert labels (" . rg_sql_error() . ")"); |
rg_bug_set_error("Cannot insert labels (" . rg_sql_error() . ")"); |
File inc/keys.inc.php changed (mode: 100644) (index 6265587..8636b86) |
... |
... |
function rg_keys_error() |
24 |
24 |
$rg_keys_functions = array( |
$rg_keys_functions = array( |
25 |
25 |
1000 => "rg_keys_event_new", |
1000 => "rg_keys_event_new", |
26 |
26 |
1001 => "rg_keys_event_del", |
1001 => "rg_keys_event_del", |
27 |
|
1002 => "rg_keys_event_mark_dirty", |
|
|
27 |
|
1002 => "rg_keys_event_regen", |
28 |
28 |
1003 => "rg_keys_event_notify_user" |
1003 => "rg_keys_event_notify_user" |
29 |
29 |
); |
); |
30 |
30 |
rg_event_register_functions($rg_keys_functions); |
rg_event_register_functions($rg_keys_functions); |
|
... |
... |
function rg_keys_event_del($db, $event) |
61 |
61 |
} |
} |
62 |
62 |
|
|
63 |
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 |
|
|
64 |
|
* Regenrate keyring. |
|
65 |
|
* We ignore requests that were inserted in queue after we already |
|
66 |
|
* regenerated the keys. |
|
67 |
|
* We must regenerate now to not let the user wait too much. |
|
68 |
|
* TODO: When we will have support in sshd for key lookup, we will not need to regenerate. |
66 |
69 |
*/ |
*/ |
67 |
|
function rg_keys_event_mark_dirty($db, $event) |
|
|
70 |
|
function rg_keys_event_regen($db, $event) |
68 |
71 |
{ |
{ |
69 |
|
$r = rg_keys_mark_dirty($db); |
|
70 |
|
if ($r === FALSE) |
|
71 |
|
return FALSE; |
|
|
72 |
|
rg_log("keys_event_regen"); |
|
73 |
|
|
|
74 |
|
$last = rg_cache_get("key::last_regen_time"); |
|
75 |
|
if ($last === FALSE) |
|
76 |
|
$last = 0; |
|
77 |
|
|
|
78 |
|
if ($event['itime'] < $last) { |
|
79 |
|
rg_log("DEBUG: event itime(" . $event['itime'] . ") < last($last)." |
|
80 |
|
. " Skip regeneration of keys."); |
|
81 |
|
} else { |
|
82 |
|
$r = rg_keys_regen($db); |
|
83 |
|
if ($r === FALSE) |
|
84 |
|
return FALSE; |
|
85 |
|
} |
72 |
86 |
|
|
73 |
87 |
return array(); |
return array(); |
74 |
88 |
} |
} |
|
... |
... |
function rg_keys_event_notify_user($db, $event) |
84 |
98 |
// TODO: load info about the keys and put the fingerprint in e-mail |
// TODO: load info about the keys and put the fingerprint in e-mail |
85 |
99 |
// TODO: Maybe put also the body in the e-mail, so it can be re-uploaded. |
// TODO: Maybe put also the body in the e-mail, so it can be re-uploaded. |
86 |
100 |
// TODO: Maybe add also the statistics. |
// TODO: Maybe add also the statistics. |
|
101 |
|
// TODO: Do not forget that here we have a list |
|
102 |
|
// TODO: Take care: we already deleted the keys. We cannot inspect |
|
103 |
|
// them anymore! Maybe put info in the event. |
87 |
104 |
|
|
88 |
105 |
$r = rg_mail("mail/user/key/" . $event['op'], $event); |
$r = rg_mail("mail/user/key/" . $event['op'], $event); |
89 |
106 |
if ($r === FALSE) |
if ($r === FALSE) |
|
... |
... |
function rg_keys_info($key) |
115 |
132 |
} |
} |
116 |
133 |
|
|
117 |
134 |
$ret['type'] = $t[0]; |
$ret['type'] = $t[0]; |
118 |
|
$ret['key'] = isset($t[1]) ? $t[1] : ""; |
|
|
135 |
|
$ret['key'] = $t[1]; |
119 |
136 |
$ret['comment'] = isset($t[2]) ? $t[2] : ""; |
$ret['comment'] = isset($t[2]) ? $t[2] : ""; |
120 |
137 |
|
|
121 |
138 |
$d = base64_decode($ret['key']); |
$d = base64_decode($ret['key']); |
|
... |
... |
function rg_keys_info($key) |
128 |
145 |
$a = array(); |
$a = array(); |
129 |
146 |
for ($i = 0; $i < 16; $i++) |
for ($i = 0; $i < 16; $i++) |
130 |
147 |
$a[] = substr($digest, $i * 2, 2); |
$a[] = substr($digest, $i * 2, 2); |
131 |
|
|
|
132 |
148 |
$ret['fingerprint'] = implode(":", $a); |
$ret['fingerprint'] = implode(":", $a); |
133 |
149 |
|
|
134 |
150 |
$ret['ok'] = 1; |
$ret['ok'] = 1; |
|
... |
... |
function rg_keys_info($key) |
139 |
155 |
} |
} |
140 |
156 |
|
|
141 |
157 |
/* |
/* |
142 |
|
* Mark state as dirty |
|
143 |
|
*/ |
|
144 |
|
function rg_keys_mark_dirty($db) |
|
145 |
|
{ |
|
146 |
|
rg_prof_start("keys_mark_dirty"); |
|
147 |
|
|
|
148 |
|
$ret = TRUE; |
|
149 |
|
if (rg_state_set($db, "authorized_keys", 1) === FALSE) { |
|
150 |
|
rg_keys_set_error("cannot make state dirty (" . rg_state_error() . ")!"); |
|
151 |
|
$ret = FALSE; |
|
152 |
|
} |
|
153 |
|
|
|
154 |
|
rg_prof_end("keys_mark_dirty"); |
|
155 |
|
return $ret; |
|
156 |
|
} |
|
157 |
|
|
|
158 |
|
/* |
|
159 |
|
* Remove a key from database for user 'ui' |
|
160 |
|
* TODO: Remove "multi" function and make this accepts an array of keys. |
|
161 |
|
* TODO: Here we must have a transaction! |
|
|
158 |
|
* Remove keys from database for user 'ui' |
162 |
159 |
*/ |
*/ |
163 |
|
function rg_keys_remove($db, $ui, $key_id, $flags) |
|
|
160 |
|
function rg_keys_remove($db, $ui, $list) |
164 |
161 |
{ |
{ |
165 |
162 |
rg_prof_start("keys_remove"); |
rg_prof_start("keys_remove"); |
166 |
|
rg_log("keys_remove: key_id=$key_id flags=" . rg_array2string($flags)); |
|
|
163 |
|
rg_log("keys_remove: list=" . rg_array2string($list)); |
167 |
164 |
|
|
168 |
165 |
$ret = FALSE; |
$ret = FALSE; |
169 |
166 |
do { |
do { |
170 |
|
// Do not move this to caller. |
|
171 |
|
// TODO: Do rg_var_array that will enforce index to be numeric? |
|
172 |
|
$e_key_id = sprintf("%u", $key_id); |
|
|
167 |
|
$my_list = array(); |
|
168 |
|
foreach ($list as $key_id => $junk) |
|
169 |
|
$my_list[] = sprintf("%u", $key_id); |
173 |
170 |
|
|
|
171 |
|
$params = array($ui['uid']); |
|
172 |
|
$sql_list = implode(", ", $my_list); |
174 |
173 |
$sql = "DELETE FROM keys" |
$sql = "DELETE FROM keys" |
175 |
|
. " WHERE uid = " . $ui['uid'] |
|
176 |
|
. " AND key_id = $e_key_id"; |
|
177 |
|
$res = rg_sql_query($db, $sql); |
|
|
174 |
|
. " WHERE uid = $1" |
|
175 |
|
. " AND key_id IN (" . $sql_list . ")"; |
|
176 |
|
$res = rg_sql_query_params($db, $sql, $params); |
178 |
177 |
if ($res === FALSE) { |
if ($res === FALSE) { |
179 |
|
rg_keys_set_error("cannot delete key $key_id (" . rg_sql_error() . ")"); |
|
|
178 |
|
rg_keys_set_error("cannot delete keys" |
|
179 |
|
. " (" . rg_sql_error() . ")"); |
180 |
180 |
break; |
break; |
181 |
181 |
} |
} |
182 |
182 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
183 |
183 |
|
|
184 |
184 |
$event = array("category" => 1001, "prio" => 50, |
$event = array("category" => 1001, "prio" => 50, |
185 |
|
"email" => $ui['email'], |
|
|
185 |
|
"ui.email" => $ui['email'], |
186 |
186 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
187 |
|
"key_id" => $key_id); |
|
|
187 |
|
"keys" => implode(",", $my_list)); |
188 |
188 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
189 |
189 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
190 |
190 |
rg_keys_set_error("cannot add event" |
rg_keys_set_error("cannot add event" |
|
... |
... |
function rg_keys_remove($db, $ui, $key_id, $flags) |
199 |
199 |
return $ret; |
return $ret; |
200 |
200 |
} |
} |
201 |
201 |
|
|
202 |
|
/* |
|
203 |
|
* Remove multiple keys from database |
|
204 |
|
*/ |
|
205 |
|
function rg_keys_remove_multi($db, $ui, $list) |
|
206 |
|
{ |
|
207 |
|
rg_prof_start("keys_remove_multi"); |
|
208 |
|
rg_log("keys_remove_multi: list=" . rg_array2string($list)); |
|
209 |
|
|
|
210 |
|
$ret = FALSE; |
|
211 |
|
do { |
|
212 |
|
if (empty($list)) { |
|
213 |
|
rg_keys_set_error("no keys provided"); |
|
214 |
|
break; |
|
215 |
|
} |
|
216 |
|
|
|
217 |
|
$flags = array("no_dirty" => 1); |
|
218 |
|
foreach ($list as $key_id => $junk) { |
|
219 |
|
$r = rg_keys_remove($db, $ui, $key_id, $flags); |
|
220 |
|
if ($r !== TRUE) |
|
221 |
|
break; |
|
222 |
|
} |
|
223 |
|
|
|
224 |
|
if (rg_keys_mark_dirty($db) != TRUE) |
|
225 |
|
break; |
|
226 |
|
|
|
227 |
|
$ret = TRUE; |
|
228 |
|
} while (0); |
|
229 |
|
|
|
230 |
|
rg_prof_end("keys_remove_multi"); |
|
231 |
|
return $ret; |
|
232 |
|
} |
|
233 |
|
|
|
234 |
202 |
/* |
/* |
235 |
203 |
* Count the number of keys per user |
* Count the number of keys per user |
236 |
204 |
*/ |
*/ |
|
... |
... |
function rg_keys_count($db, $uid) |
240 |
208 |
|
|
241 |
209 |
$ret = FALSE; |
$ret = FALSE; |
242 |
210 |
do { |
do { |
243 |
|
$sql = "SELECT COUNT(*) AS count FROM keys WHERE uid = $uid"; |
|
244 |
|
$res = rg_sql_query($db, $sql); |
|
|
211 |
|
$params = array($uid); |
|
212 |
|
$sql = "SELECT COUNT(*) AS count FROM keys" |
|
213 |
|
. " WHERE uid = $1"; |
|
214 |
|
$res = rg_sql_query_params($db, $sql, $params); |
245 |
215 |
if ($res === FALSE) { |
if ($res === FALSE) { |
246 |
216 |
rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); |
rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); |
247 |
217 |
break; |
break; |
|
... |
... |
function rg_keys_count($db, $uid) |
259 |
229 |
/* |
/* |
260 |
230 |
* Add a key |
* Add a key |
261 |
231 |
* Returns the key_id of the key. |
* Returns the key_id of the key. |
262 |
|
* TODO: Transaction! |
|
263 |
232 |
*/ |
*/ |
264 |
233 |
function rg_keys_add($db, $ui, $key) |
function rg_keys_add($db, $ui, $key) |
265 |
234 |
{ |
{ |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
269 |
238 |
rg_log("keys_add: $key=$key"); |
rg_log("keys_add: $key=$key"); |
270 |
239 |
|
|
271 |
240 |
$ret = FALSE; |
$ret = FALSE; |
|
241 |
|
$do_rollback = 0; |
272 |
242 |
do { |
do { |
273 |
243 |
$itime = time(); |
$itime = time(); |
274 |
|
$e_key = rg_sql_escape($db, $key); |
|
275 |
244 |
|
|
276 |
245 |
$ki = rg_keys_info($key); |
$ki = rg_keys_info($key); |
277 |
246 |
if ($ki['ok'] != 1) |
if ($ki['ok'] != 1) |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
286 |
255 |
break; |
break; |
287 |
256 |
|
|
288 |
257 |
if ($no_of_keys >= $rg_max_ssh_keys) { |
if ($no_of_keys >= $rg_max_ssh_keys) { |
289 |
|
rg_keys_set_error("too many keys; please delete some"); |
|
|
258 |
|
rg_keys_set_error("too many keys" |
|
259 |
|
. " (" . $no_of_keys . "); please delete some"); |
|
260 |
|
break; |
|
261 |
|
} |
|
262 |
|
|
|
263 |
|
$r = rg_sql_begin($db); |
|
264 |
|
if ($r !== TRUE) { |
|
265 |
|
rg_keys_set_error("cannot start transaction" |
|
266 |
|
. " (" . rg_sql_error() . ")"); |
290 |
267 |
break; |
break; |
291 |
268 |
} |
} |
|
269 |
|
$do_rollback = 1; |
292 |
270 |
|
|
|
271 |
|
$params = array($itime, $ui['uid'], $key); |
293 |
272 |
$sql = "INSERT INTO keys (itime, uid, key)" |
$sql = "INSERT INTO keys (itime, uid, key)" |
294 |
|
. " VALUES ($itime, " . $ui['uid'] . ", '$e_key')" |
|
|
273 |
|
. " VALUES ($1, $2, $3)" |
295 |
274 |
. " RETURNING key_id"; |
. " RETURNING key_id"; |
296 |
|
$res = rg_sql_query($db, $sql); |
|
|
275 |
|
$res = rg_sql_query_params($db, $sql, $params); |
297 |
276 |
if ($res === FALSE) { |
if ($res === FALSE) { |
298 |
|
rg_keys_set_error("cannot insert key (" . rg_sql_error() . ")"); |
|
|
277 |
|
rg_keys_set_error("cannot insert key" |
|
278 |
|
. " (" . rg_sql_error() . ")"); |
299 |
279 |
break; |
break; |
300 |
280 |
} |
} |
301 |
281 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
303 |
283 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
304 |
284 |
|
|
305 |
285 |
$event = array("category" => 1000, "prio" => 50, |
$event = array("category" => 1000, "prio" => 50, |
306 |
|
"email" => $ui['email'], |
|
|
286 |
|
"ui.email" => $ui['email'], |
307 |
287 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
308 |
288 |
"key_id" => $key_id); |
"key_id" => $key_id); |
309 |
289 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
313 |
293 |
break; |
break; |
314 |
294 |
} |
} |
315 |
295 |
|
|
|
296 |
|
$r = rg_sql_commit($db); |
|
297 |
|
if ($r !== TRUE) { |
|
298 |
|
rg_keys_set_error("cannot commit transaction" |
|
299 |
|
. " (" . rg_sql_error() . ")"); |
|
300 |
|
break; |
|
301 |
|
} |
|
302 |
|
$do_rollback = 0; |
|
303 |
|
|
316 |
304 |
$ret = $key_id; |
$ret = $key_id; |
317 |
305 |
} while (0); |
} while (0); |
318 |
306 |
|
|
|
307 |
|
if ($do_rollback == 1) |
|
308 |
|
rg_sql_rollback($db); |
|
309 |
|
|
319 |
310 |
rg_prof_end("keys_add"); |
rg_prof_end("keys_add"); |
320 |
311 |
return $ret; |
return $ret; |
321 |
312 |
} |
} |
322 |
313 |
|
|
323 |
314 |
/* |
/* |
324 |
|
* Update last_use and last_ip |
|
|
315 |
|
* Update first_use, last_use, last_ip and count |
325 |
316 |
*/ |
*/ |
326 |
317 |
function rg_keys_update_use($db, $key_id, $ip) |
function rg_keys_update_use($db, $key_id, $ip) |
327 |
318 |
{ |
{ |
|
... |
... |
function rg_keys_update_use($db, $key_id, $ip) |
332 |
323 |
do { |
do { |
333 |
324 |
$now = time(); |
$now = time(); |
334 |
325 |
|
|
335 |
|
$e_ip = rg_sql_escape($db, $ip); |
|
|
326 |
|
$params = array($now, $key_id); |
|
327 |
|
$sql = "UPDATE keys SET first_use = $1" |
|
328 |
|
. " WHERE first_use = 0" |
|
329 |
|
. " AND key_id = $2"; |
|
330 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
331 |
|
if ($res === FALSE) { |
|
332 |
|
rg_keys_set_error("cannot update key's first use" |
|
333 |
|
. " (" . rg_sql_error() . ")"); |
|
334 |
|
break; |
|
335 |
|
} |
336 |
336 |
|
|
337 |
|
$sql = "UPDATE keys SET last_use = $now, last_ip = '$e_ip'" |
|
338 |
|
. " WHERE key_id = $key_id"; |
|
339 |
|
$res = rg_sql_query($db, $sql); |
|
|
337 |
|
$params = array($now, $ip, $key_id); |
|
338 |
|
$sql = "UPDATE keys SET last_use = $1" |
|
339 |
|
. ", last_ip = $2" |
|
340 |
|
. ", count = count + 1" |
|
341 |
|
. " WHERE key_id = $3"; |
|
342 |
|
$res = rg_sql_query_params($db, $sql, $params); |
340 |
343 |
if ($res === FALSE) { |
if ($res === FALSE) { |
341 |
|
rg_keys_set_error("cannot update key (" . rg_sql_error() . ")"); |
|
|
344 |
|
rg_keys_set_error("cannot update key" |
|
345 |
|
. " (" . rg_sql_error() . ")"); |
342 |
346 |
break; |
break; |
343 |
347 |
} |
} |
344 |
348 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
|
... |
... |
function rg_keys_regen($db) |
360 |
364 |
|
|
361 |
365 |
rg_prof_start("keys_regen"); |
rg_prof_start("keys_regen"); |
362 |
366 |
|
|
|
367 |
|
$now = time(); |
363 |
368 |
$ret = FALSE; |
$ret = FALSE; |
364 |
369 |
do { |
do { |
365 |
|
$dirty = rg_state_get($db, "authorized_keys"); |
|
366 |
|
if (!file_exists($rg_keys_file)) { |
|
367 |
|
rg_log("Keys file does not exists, force dirty 1."); |
|
368 |
|
$dirty = 1; |
|
369 |
|
} |
|
370 |
|
if ($dirty == 0) { |
|
371 |
|
// Skip generation because is not dirty |
|
372 |
|
$ret = TRUE; |
|
373 |
|
break; |
|
374 |
|
} |
|
375 |
|
|
|
376 |
370 |
// create .ssh folder if does not exists |
// create .ssh folder if does not exists |
377 |
371 |
$dir = dirname($rg_keys_file); |
$dir = dirname($rg_keys_file); |
378 |
372 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
379 |
373 |
if (!@mkdir($dir, 0700, TRUE)) { |
if (!@mkdir($dir, 0700, TRUE)) { |
380 |
|
rg_keys_set_error("cannot create dir $dir ($php_errormsg)"); |
|
|
374 |
|
rg_keys_set_error("cannot create dir [$dir] ($php_errormsg)"); |
381 |
375 |
break; |
break; |
382 |
376 |
} |
} |
383 |
377 |
} |
} |
|
... |
... |
function rg_keys_regen($db) |
395 |
389 |
break; |
break; |
396 |
390 |
} |
} |
397 |
391 |
|
|
398 |
|
// mark file as clean |
|
399 |
|
rg_state_set($db, "authorized_keys", 0); |
|
400 |
|
|
|
401 |
|
$sql = "SELECT key_id, uid, key FROM keys"; |
|
|
392 |
|
$sql = "SELECT key_id, uid, key FROM keys ORDER BY count DESC"; |
402 |
393 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
403 |
394 |
if ($res === FALSE) { |
if ($res === FALSE) { |
404 |
395 |
rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); |
rg_keys_set_error("cannot query (" . rg_sql_error() . ")"); |
405 |
396 |
break; |
break; |
406 |
397 |
} |
} |
|
398 |
|
$errors = 0; |
407 |
399 |
while (($row = rg_sql_fetch_array($res))) { |
while (($row = rg_sql_fetch_array($res))) { |
408 |
|
rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']); |
|
|
400 |
|
//rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']); |
409 |
401 |
$buf = "command=\"" |
$buf = "command=\"" |
410 |
402 |
. $rg_scripts . "/scripts/remote.sh" |
. $rg_scripts . "/scripts/remote.sh" |
411 |
403 |
. " " . $row['uid'] |
. " " . $row['uid'] |
|
... |
... |
function rg_keys_regen($db) |
413 |
405 |
. "," . $rg_ssh_paras |
. "," . $rg_ssh_paras |
414 |
406 |
. " " . $row['key'] . "\n"; |
. " " . $row['key'] . "\n"; |
415 |
407 |
if (@fwrite($f, $buf) === FALSE) { |
if (@fwrite($f, $buf) === FALSE) { |
416 |
|
rg_keys_set_error("cannot write. Disk space problems? ($php_errormsg)"); |
|
417 |
|
fclose($f); |
|
418 |
|
unlink($tmp); |
|
419 |
|
rg_sql_free_result($res); |
|
|
408 |
|
rg_keys_set_error("cannot write; disk space problems? ($php_errormsg)"); |
|
409 |
|
$errors = 1; |
420 |
410 |
break; |
break; |
421 |
411 |
} |
} |
422 |
412 |
} |
} |
423 |
413 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
424 |
414 |
|
|
425 |
415 |
fclose($f); |
fclose($f); |
|
416 |
|
if ($errors == 1) { |
|
417 |
|
unlink($tmp); |
|
418 |
|
break; |
|
419 |
|
} |
426 |
420 |
|
|
427 |
421 |
if (@rename($tmp, $rg_keys_file) === FALSE) { |
if (@rename($tmp, $rg_keys_file) === FALSE) { |
428 |
422 |
rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)"); |
rg_keys_set_error("cannot rename $tmp to $rg_keys_file ($php_errormsg)"); |
|
... |
... |
function rg_keys_regen($db) |
430 |
424 |
break; |
break; |
431 |
425 |
} |
} |
432 |
426 |
|
|
|
427 |
|
rg_cache_set("key::last_regen_time", $now); |
|
428 |
|
|
433 |
429 |
$ret = TRUE; |
$ret = TRUE; |
434 |
430 |
} while (0); |
} while (0); |
435 |
431 |
|
|
|
... |
... |
function rg_keys_list($db, $ui) |
447 |
443 |
|
|
448 |
444 |
$ret = FALSE; |
$ret = FALSE; |
449 |
445 |
do { |
do { |
450 |
|
$sql = "SELECT * FROM keys WHERE uid = " . $ui['uid'] |
|
|
446 |
|
$params = array($ui['uid']); |
|
447 |
|
$sql = "SELECT * FROM keys WHERE uid = $1" |
451 |
448 |
. " ORDER BY itime DESC"; |
. " ORDER BY itime DESC"; |
452 |
|
$res = rg_sql_query($db, $sql); |
|
|
449 |
|
$res = rg_sql_query_params($db, $sql, $params); |
453 |
450 |
if ($res === FALSE) { |
if ($res === FALSE) { |
454 |
451 |
rg_keys_set_error("Cannot query (" . rg_sql_error() . ")"); |
rg_keys_set_error("Cannot query (" . rg_sql_error() . ")"); |
455 |
452 |
break; |
break; |
|
... |
... |
function rg_keys_list($db, $ui) |
467 |
464 |
$t['key_id'] = $row['key_id']; |
$t['key_id'] = $row['key_id']; |
468 |
465 |
$t['itime'] = gmdate("Y-m-d H:i", $row['itime']); |
$t['itime'] = gmdate("Y-m-d H:i", $row['itime']); |
469 |
466 |
|
|
|
467 |
|
if ($row['first_use'] == 0) |
|
468 |
|
$t['first_use'] = "-"; |
|
469 |
|
else |
|
470 |
|
$t['first_use'] = gmdate("Y-m-d H:i", $row['first_use']); |
|
471 |
|
|
470 |
472 |
if (empty($row['last_ip'])) |
if (empty($row['last_ip'])) |
471 |
473 |
$t['last_ip'] = "-"; |
$t['last_ip'] = "-"; |
472 |
474 |
else |
else |
|
... |
... |
function rg_keys_list($db, $ui) |
477 |
479 |
else |
else |
478 |
480 |
$t['last_use'] = gmdate("Y-m-d H:i", $row['last_use']); |
$t['last_use'] = gmdate("Y-m-d H:i", $row['last_use']); |
479 |
481 |
|
|
|
482 |
|
$t['count'] = $row['count']; |
|
483 |
|
|
480 |
484 |
$ret[] = $t; |
$ret[] = $t; |
481 |
485 |
} |
} |
482 |
486 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
File inc/plan.inc.php changed (mode: 100644) (index 180476b..21c662b) |
2 |
2 |
require_once($INC . "/util.inc.php"); |
require_once($INC . "/util.inc.php"); |
3 |
3 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
4 |
4 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
5 |
|
require_once($INC . "/sess.inc.php"); |
|
6 |
|
require_once($INC . "/rights.inc.php"); |
|
7 |
5 |
require_once($INC . "/events.inc.php"); |
require_once($INC . "/events.inc.php"); |
8 |
6 |
require_once($INC . "/cache.inc.php"); |
require_once($INC . "/cache.inc.php"); |
9 |
7 |
|
|
10 |
|
$rg_user_rights = array( |
|
11 |
|
"C" => "Create repositories", |
|
12 |
|
"U" => "Add users" |
|
13 |
|
); |
|
|
8 |
|
$rg_plan_error = ""; |
14 |
9 |
|
|
15 |
|
rg_rights_register("user", $rg_user_rights); |
|
16 |
|
|
|
17 |
|
$rg_user_error = ""; |
|
18 |
|
|
|
19 |
|
function rg_user_set_error($str) |
|
|
10 |
|
function rg_plan_set_error($str) |
20 |
11 |
{ |
{ |
21 |
|
global $rg_user_error; |
|
22 |
|
$rg_user_error = $str; |
|
|
12 |
|
global $rg_plan_error; |
|
13 |
|
$rg_plan_error = $str; |
23 |
14 |
} |
} |
24 |
15 |
|
|
25 |
|
function rg_user_error() |
|
26 |
|
{ |
|
27 |
|
global $rg_user_error; |
|
28 |
|
return $rg_user_error; |
|
29 |
|
} |
|
30 |
|
|
|
31 |
|
/* |
|
32 |
|
* Event functions |
|
33 |
|
*/ |
|
34 |
|
$rg_user_functions = array( |
|
35 |
|
2000 => "rg_user_event_new", |
|
36 |
|
2002 => "rg_user_event_notify_user", |
|
37 |
|
2005 => "rg_user_event_rename", |
|
38 |
|
2006 => "rg_user_link_by_name" |
|
39 |
|
); |
|
40 |
|
rg_event_register_functions($rg_user_functions); |
|
41 |
|
|
|
42 |
|
/* |
|
43 |
|
* Event for adding a new user |
|
44 |
|
*/ |
|
45 |
|
function rg_user_event_new($db, $event) |
|
|
16 |
|
function rg_plan_error() |
46 |
17 |
{ |
{ |
47 |
|
$ret = array(); |
|
48 |
|
|
|
49 |
|
$event['op'] = "new"; |
|
50 |
|
// create link by name |
|
51 |
|
$ret[] = array_merge($event, array("category" => 2006, "prio" => 200)); |
|
52 |
|
// notify user |
|
53 |
|
$ret[] = array_merge($event, array("category" => 2002, "prio" => 100)); |
|
54 |
|
|
|
55 |
|
return $ret; |
|
|
18 |
|
global $rg_plan_error; |
|
19 |
|
return $rg_plan_error; |
56 |
20 |
} |
} |
57 |
21 |
|
|
58 |
22 |
/* |
/* |
59 |
|
* Notify user: welcome |
|
|
23 |
|
* Validates plan name |
60 |
24 |
*/ |
*/ |
61 |
|
function rg_user_event_notify_user($db, $event) |
|
|
25 |
|
function rg_plan_ok($name) |
62 |
26 |
{ |
{ |
63 |
|
rg_log("user_event_notify_user: event=" . rg_array2string($event)); |
|
64 |
|
|
|
65 |
|
if (strcmp($event['op'], "rename") == 0) { |
|
66 |
|
$r = rg_mail("mail/user/rename", $event); |
|
67 |
|
if ($r === FALSE) |
|
68 |
|
return FALSE; |
|
69 |
|
} |
|
70 |
|
|
|
71 |
|
$r = rg_mail("mail/user/welcome", $event); |
|
72 |
|
if ($r === FALSE) |
|
|
27 |
|
if (empty($name)) |
73 |
28 |
return FALSE; |
return FALSE; |
74 |
29 |
|
|
75 |
|
return array(); |
|
76 |
|
} |
|
77 |
|
|
|
78 |
|
/* |
|
79 |
|
* Event for renaming an user |
|
80 |
|
*/ |
|
81 |
|
function rg_user_event_rename($db, $event) |
|
82 |
|
{ |
|
83 |
|
$ret = array(); |
|
84 |
|
|
|
85 |
|
$event['op'] = "rename"; |
|
86 |
|
// notify user |
|
87 |
|
$ret[] = array_merge($event, array("category" => 2002, "prio" => 100)); |
|
88 |
|
// TODO: notify watchers |
|
89 |
|
|
|
90 |
|
return $ret; |
|
91 |
|
} |
|
92 |
|
|
|
93 |
|
/* |
|
94 |
|
* Event for creating a link by name to the uid |
|
95 |
|
*/ |
|
96 |
|
function rg_user_link_by_name($db, $event) |
|
97 |
|
{ |
|
98 |
|
rg_log("user_link_by_name: event=" . rg_array2string($event)); |
|
99 |
|
|
|
100 |
|
$by_id = rg_user_path_by_id($event['uid']); |
|
101 |
|
if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) { |
|
102 |
|
rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); |
|
103 |
|
return FALSE; |
|
104 |
|
} |
|
105 |
|
|
|
106 |
|
$by_name = rg_user_path_by_name($event['username']); |
|
107 |
|
$by_name_parent = dirname($by_name); |
|
108 |
|
if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) { |
|
109 |
|
rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); |
|
110 |
|
return FALSE; |
|
111 |
|
} |
|
112 |
|
|
|
113 |
|
$by_id_rel = rg_user_path_by_id_rel($event['uid']); |
|
114 |
|
if (symlink($by_id_rel, $by_name) === FALSE) { |
|
115 |
|
rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!"); |
|
116 |
|
return FALSE; |
|
117 |
|
} |
|
118 |
|
|
|
119 |
|
return array(); |
|
120 |
|
} |
|
121 |
|
|
|
122 |
|
/* |
|
123 |
|
* Returns the relative path to user home based on uid |
|
124 |
|
*/ |
|
125 |
|
function rg_user_path_by_id_rel($uid) |
|
126 |
|
{ |
|
127 |
|
$xuid = sprintf("%08X", $uid); |
|
128 |
|
$uid_path = array(); |
|
129 |
|
for ($i = 0; $i < 8; $i += 2) |
|
130 |
|
$uid_path[] = $xuid[$i] . $xuid[$i + 1]; |
|
131 |
|
$uid_path = implode("/", $uid_path); |
|
132 |
|
|
|
133 |
|
return "../../../../by_id/" . $uid_path . "/" . $xuid; |
|
134 |
|
} |
|
135 |
|
|
|
136 |
|
/* |
|
137 |
|
* Returns the path to user home based on uid |
|
138 |
|
*/ |
|
139 |
|
function rg_user_path_by_id($uid) |
|
140 |
|
{ |
|
141 |
|
global $rg_repos; |
|
142 |
|
|
|
143 |
|
$xuid = sprintf("%08X", $uid); |
|
144 |
|
$uid_path = array(); |
|
145 |
|
for ($i = 0; $i < 8; $i += 2) |
|
146 |
|
$uid_path[] = $xuid[$i] . $xuid[$i + 1]; |
|
147 |
|
$uid_path = implode("/", $uid_path); |
|
148 |
|
|
|
149 |
|
return $rg_repos . "/by_id/" . $uid_path . "/" . $xuid; |
|
150 |
|
} |
|
151 |
|
|
|
152 |
|
/* |
|
153 |
|
* Returns the path to user home based on name |
|
154 |
|
*/ |
|
155 |
|
function rg_user_path_by_name($name) |
|
156 |
|
{ |
|
157 |
|
global $rg_repos; |
|
158 |
|
|
|
159 |
|
$x = $name . "__"; |
|
160 |
|
|
|
161 |
|
return $rg_repos . "/by_name/" |
|
162 |
|
. $x[0] . "/" . $x[1] . "/" . $x[2] . "/" . $name; |
|
163 |
|
} |
|
164 |
|
|
|
165 |
|
/* |
|
166 |
|
* Returns the URL to a user home based on $ui |
|
167 |
|
*/ |
|
168 |
|
function rg_user_url($ui) |
|
169 |
|
{ |
|
170 |
|
$prefix = ""; |
|
171 |
|
if ($ui['organization'] == 0) |
|
172 |
|
$prefix = "/user"; |
|
173 |
|
|
|
174 |
|
return $prefix . "/" . $ui['username']; |
|
175 |
|
} |
|
176 |
|
|
|
177 |
|
/* |
|
178 |
|
* Computes password hash |
|
179 |
|
*/ |
|
180 |
|
function rg_user_pass($salt, $pass) |
|
181 |
|
{ |
|
182 |
|
return sha1($salt . "===" . $pass); |
|
183 |
|
} |
|
184 |
|
|
|
185 |
|
/* |
|
186 |
|
* Validates a password |
|
187 |
|
*/ |
|
188 |
|
function rg_user_pass_ok($pass) |
|
189 |
|
{ |
|
190 |
|
if (strlen($pass) < 5) { |
|
191 |
|
rg_user_set_error("password is too short (less than 5 chars)"); |
|
192 |
|
return FALSE; |
|
193 |
|
} |
|
194 |
|
|
|
195 |
|
return TRUE; |
|
196 |
|
} |
|
197 |
|
|
|
198 |
|
/* |
|
199 |
|
* Returns true if the user is ok |
|
200 |
|
*/ |
|
201 |
|
function rg_user_ok($user) |
|
202 |
|
{ |
|
203 |
|
global $rg_user_allow; |
|
204 |
|
global $rg_user_min_len; |
|
205 |
|
global $rg_user_max_len; |
|
206 |
|
|
|
207 |
|
if (rg_chars_allow($user, $rg_user_allow) !== TRUE) { |
|
208 |
|
rg_user_set_error("invalid user name (invalid chars [$user] [$rg_user_allow])"); |
|
209 |
|
return FALSE; |
|
210 |
|
} |
|
211 |
|
|
|
212 |
|
if (strlen($user) < $rg_user_min_len) { |
|
213 |
|
rg_user_set_error("user name too short (shorter than $rg_user_min_len)"); |
|
214 |
|
return FALSE; |
|
215 |
|
} |
|
216 |
|
|
|
217 |
|
if (strlen($user) > $rg_user_max_len) { |
|
218 |
|
rg_user_set_error("user name too long (longer than $rg_user_max_len)"); |
|
219 |
|
return FALSE; |
|
220 |
|
} |
|
221 |
|
|
|
222 |
30 |
return TRUE; |
return TRUE; |
223 |
31 |
} |
} |
224 |
32 |
|
|
225 |
33 |
/* |
/* |
226 |
|
* Lookup in db the old names, so we can redirect the user to the new name |
|
|
34 |
|
* Add/edit a plan |
|
35 |
|
* If uid > 0 - edit, else, add |
227 |
36 |
*/ |
*/ |
228 |
|
function rg_user_lookup_by_old_name($db, $old_name) |
|
|
37 |
|
function rg_plan_edit($db, $d) |
229 |
38 |
{ |
{ |
230 |
|
rg_prof_start("user_lookup_by_old_name"); |
|
231 |
|
rg_log("user_lookup_by_old_name: old_name=$old_name"); |
|
|
39 |
|
rg_prof_start("plan_edit"); |
|
40 |
|
rg_log("plan_edit: d: " . rg_array2string($d)); |
232 |
41 |
|
|
233 |
42 |
$ret = FALSE; |
$ret = FALSE; |
234 |
43 |
do { |
do { |
235 |
|
$x = rg_cache_get("old_name::" . $old_name); |
|
236 |
|
if ($x !== FALSE) { |
|
237 |
|
$ret = $x; |
|
|
44 |
|
if (rg_plan_ok($d['name']) !== TRUE) |
238 |
45 |
break; |
break; |
|
46 |
|
|
|
47 |
|
$params = array($d['name'], $d['description'], $d['disk_mb'], |
|
48 |
|
$d['users'], $d['bw'], $d['speed'], $d['position'], |
|
49 |
|
$d['id']); |
|
50 |
|
if ($d['id'] == 0) { // add |
|
51 |
|
$sql = "INSERT INTO plans (name, description, disk_mb" |
|
52 |
|
. ", users, bw, speed, position)" |
|
53 |
|
. " VALUES ($1, $2, $3, $4, $5, $6, $7)" |
|
54 |
|
. " RETURNING id"; |
|
55 |
|
} else { // edit |
|
56 |
|
$sql = "UPDATE plans" |
|
57 |
|
. " SET name = $1" |
|
58 |
|
. ", description = $2" |
|
59 |
|
. ", disk_mb = $3" |
|
60 |
|
. ", users = $4" |
|
61 |
|
. ", bw = $5" |
|
62 |
|
. ", speed = $6" |
|
63 |
|
. ", position = $7" |
|
64 |
|
. " WHERE id = $8" |
|
65 |
|
. " RETURNING id"; |
239 |
66 |
} |
} |
240 |
67 |
|
|
241 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
242 |
|
$sql = "SELECT uid FROM users_renames" |
|
243 |
|
. " WHERE old_name = '$e_old_name'"; |
|
244 |
|
$res = rg_sql_query($db, $sql); |
|
|
68 |
|
$res = rg_sql_query_params($db, $sql, $params); |
245 |
69 |
if ($res === FALSE) { |
if ($res === FALSE) { |
246 |
|
rg_user_set_error("cannot lookup old name (" |
|
247 |
|
. rg_sql_error() . ")"); |
|
|
70 |
|
rg_plan_set_error("cannot insert/update plan" |
|
71 |
|
. " (" . rg_sql_error() . ")"); |
248 |
72 |
break; |
break; |
249 |
73 |
} |
} |
250 |
|
$rows = rg_sql_num_rows($res); |
|
251 |
|
if ($rows > 0) |
|
252 |
|
$row = rg_sql_fetch_array($res); |
|
|
74 |
|
$row = rg_sql_fetch_array($res); |
253 |
75 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
254 |
|
if ($rows == 0) |
|
255 |
|
$ret = 0; |
|
256 |
|
else |
|
257 |
|
$ret = $row['uid']; |
|
258 |
76 |
|
|
259 |
|
rg_cache_set("old_name::" . $old_name, $ret); |
|
|
77 |
|
$d['id'] = $row['id']; |
|
78 |
|
|
|
79 |
|
// invalidate cache |
|
80 |
|
rg_cache_unset("plan::list"); |
|
81 |
|
|
|
82 |
|
$ret = $row['id']; |
260 |
83 |
} while (0); |
} while (0); |
261 |
84 |
|
|
262 |
|
rg_prof_end("user_lookup_by_old_name"); |
|
|
85 |
|
rg_prof_end("plan_edit"); |
263 |
86 |
return $ret; |
return $ret; |
264 |
87 |
} |
} |
265 |
88 |
|
|
266 |
89 |
/* |
/* |
267 |
|
* Add a rename to the database |
|
|
90 |
|
* Delete plans; list is array("<id>" => "<junk>, ...) |
268 |
91 |
*/ |
*/ |
269 |
|
function rg_user_insert_rename($db, $uid, $old_name) |
|
|
92 |
|
function rg_plan_remove($db, $list) |
270 |
93 |
{ |
{ |
271 |
|
rg_prof_start("user_insert_rename"); |
|
272 |
|
rg_log("user_insert_rename: uid=$uid old_name=$old_name"); |
|
|
94 |
|
rg_prof_start("plan_remove"); |
|
95 |
|
rg_log("plan_remove: list=" . rg_array2string($list)); |
273 |
96 |
|
|
274 |
97 |
$ret = FALSE; |
$ret = FALSE; |
275 |
98 |
do { |
do { |
276 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
|
99 |
|
$my_list = array(); |
|
100 |
|
foreach ($list as $id => $junk) |
|
101 |
|
$my_list[] = sprintf("%u", $id); |
277 |
102 |
|
|
278 |
|
// Check if already exists in the database |
|
279 |
|
$r = rg_user_lookup_by_old_name($db, $old_name); |
|
280 |
|
if ($r === FALSE) |
|
281 |
|
break; |
|
282 |
|
if ($r > 0) { |
|
283 |
|
$sql = "UPDATE users_renames" |
|
284 |
|
. " SET uid = $uid" |
|
285 |
|
. " WHERE old_name = '$e_old_name'"; |
|
286 |
|
} else { |
|
287 |
|
$now = time(); |
|
288 |
|
$sql = "INSERT INTO users_renames (uid, old_name" |
|
289 |
|
. ", itime)" |
|
290 |
|
. " VALUES (" . $uid |
|
291 |
|
. ", '$e_old_name'" |
|
292 |
|
. ", $now" |
|
293 |
|
. ")"; |
|
294 |
|
} |
|
|
103 |
|
$sql_list = implode(", ", $my_list); |
|
104 |
|
$sql = "DELETE FROM plans WHERE id IN (" . $sql_list . ")"; |
295 |
105 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
296 |
106 |
if ($res === FALSE) { |
if ($res === FALSE) { |
297 |
|
rg_user_set_error("cannot link with old_name in db" |
|
|
107 |
|
rg_plan_set_error("cannot remove plan $id" |
298 |
108 |
. " (" . rg_sql_error() . ")"); |
. " (" . rg_sql_error() . ")"); |
299 |
109 |
break; |
break; |
300 |
110 |
} |
} |
|
111 |
|
rg_sql_free_result($res); |
301 |
112 |
|
|
302 |
|
rg_cache_set("old_name::" . $old_name, $uid); |
|
303 |
|
|
|
304 |
|
$ret = TRUE; |
|
305 |
|
} while (0); |
|
306 |
|
|
|
307 |
|
rg_prof_end("user_insert_rename"); |
|
308 |
|
return $ret; |
|
309 |
|
} |
|
310 |
|
|
|
311 |
|
/* |
|
312 |
|
* Rename a user |
|
313 |
|
* We keep the old name around, so the clients do not break. |
|
314 |
|
*/ |
|
315 |
|
function rg_user_rename($db, $ui, $new_name) |
|
316 |
|
{ |
|
317 |
|
rg_prof_start("user_rename"); |
|
318 |
|
rg_log("user_rename: from=[" . $ui['username'] . "]" |
|
319 |
|
. " to=[" . $new_name . "]..."); |
|
320 |
|
|
|
321 |
|
$user_path = rg_user_path_by_id($ui['uid']); |
|
322 |
|
$old_path = rg_user_path_by_id_rel($ui['uid']); |
|
323 |
|
$new_path = rg_user_path_by_name($new_name); |
|
324 |
|
rg_log("old_path=$old_path new_path=$new_path"); |
|
325 |
|
|
|
326 |
|
$ret = FALSE; |
|
327 |
|
do { |
|
328 |
|
$do_link = TRUE; |
|
329 |
|
|
|
330 |
|
// Check if we already did the rename |
|
331 |
|
if (file_exists($new_path)) { |
|
332 |
|
if (!is_link($new_path)) { |
|
333 |
|
rg_internal_error("$new_path is not a link!"); |
|
334 |
|
break; |
|
335 |
|
} |
|
336 |
|
|
|
337 |
|
$v = readlink($new_path); |
|
338 |
|
if ($v === FALSE) { |
|
339 |
|
rg_internal_error("Cannot read link $new_path!"); |
|
340 |
|
break; |
|
341 |
|
} |
|
342 |
|
rg_log("new_path points to [$v]"); |
|
343 |
|
|
|
344 |
|
if (strcmp($old_path, $v) == 0) { |
|
345 |
|
// Link already done |
|
346 |
|
$do_link = FALSE; |
|
347 |
|
} else { |
|
348 |
|
// Seems that new_path points to other place |
|
349 |
|
$r = rename($new_path, $new_path . ".BOGUS." . time()); |
|
350 |
|
if ($r !== TRUE) { |
|
351 |
|
rg_internal_error("Cannot rename bogus!"); |
|
352 |
|
break; |
|
353 |
|
} |
|
354 |
|
} |
|
355 |
|
} |
|
356 |
|
|
|
357 |
|
if ($do_link === TRUE) { |
|
358 |
|
// Now, the new name is free, do the link |
|
359 |
|
$r = symlink($old_path, $new_path); |
|
360 |
|
if ($r !== TRUE) { |
|
361 |
|
rg_internal_error("Cannot symlink $old_path -> $new_path ($php_errormsg)!"); |
|
362 |
|
break; |
|
363 |
|
} |
|
364 |
|
} |
|
365 |
|
|
|
366 |
|
// TOOD: transaction? |
|
367 |
|
$r = rg_user_insert_rename($db, $ui['uid'], $new_name); |
|
368 |
|
if ($r !== TRUE) |
|
369 |
|
break; |
|
370 |
|
|
|
371 |
|
// TODO: Check if all parameters are used. |
|
372 |
|
$event = array("category" => 2005, "prio" => 50, |
|
373 |
|
"ui.rename_from" => $ui['username'], |
|
374 |
|
"ui.rename_to" => $new_name, |
|
375 |
|
"IP" => rg_var_str("REMOTE_ADDR"), |
|
376 |
|
"ui.uid" => $ui['uid']); |
|
377 |
|
$r = rg_event_add($db, $event); |
|
378 |
|
if ($r !== TRUE) { |
|
379 |
|
rg_repo_set_error("cannot add event" |
|
380 |
|
. " (" . rg_event_error() . ")"); |
|
381 |
|
break; |
|
382 |
|
} |
|
|
113 |
|
// invalidate cache |
|
114 |
|
rg_cache_unset("plan::list"); |
383 |
115 |
|
|
384 |
116 |
$ret = TRUE; |
$ret = TRUE; |
385 |
117 |
} while (0); |
} while (0); |
386 |
118 |
|
|
387 |
|
rg_prof_end("user_rename"); |
|
|
119 |
|
rg_prof_end("plan_remove"); |
388 |
120 |
return $ret; |
return $ret; |
389 |
121 |
} |
} |
390 |
122 |
|
|
391 |
123 |
/* |
/* |
392 |
|
* Add/edit a user |
|
393 |
|
* If uid > 0 - edit, else, add |
|
|
124 |
|
* Return the list of plans |
394 |
125 |
*/ |
*/ |
395 |
|
function rg_user_edit($db, $d) |
|
|
126 |
|
function rg_plan_list($db) |
396 |
127 |
{ |
{ |
397 |
|
rg_prof_start("user_edit"); |
|
398 |
|
rg_log("user_edit: data: " . rg_array2string($d)); |
|
|
128 |
|
rg_prof_start("plan_list"); |
399 |
129 |
|
|
400 |
130 |
$ret = FALSE; |
$ret = FALSE; |
401 |
131 |
do { |
do { |
402 |
|
// DEBUG |
|
403 |
|
if (!isset($d['username'])) { |
|
404 |
|
rg_internal_error("username not passed"); |
|
|
132 |
|
$c = rg_cache_get("plan::list"); |
|
133 |
|
if ($c !== FALSE) { |
|
134 |
|
$ret = unserialize($c); |
405 |
135 |
break; |
break; |
406 |
136 |
} |
} |
407 |
137 |
|
|
408 |
|
if (rg_user_ok($d['username']) !== TRUE) |
|
409 |
|
break; |
|
410 |
|
|
|
411 |
|
$now = time(); |
|
412 |
|
$e_username = rg_sql_escape($db, $d['username']); |
|
413 |
|
$e_realname = rg_sql_escape($db, $d['realname']); |
|
414 |
|
$e_salt = rg_id(40); |
|
415 |
|
$e_pass = rg_user_pass($e_salt, $d['pass']); |
|
416 |
|
$e_email = rg_sql_escape($db, $d['email']); |
|
417 |
|
$e_rights = rg_sql_escape($db, $d['rights']); |
|
418 |
|
$e_is_admin = $d['is_admin']; |
|
419 |
|
$e_disk_quota_mb = $d['disk_quota_mb']; |
|
420 |
|
$e_session_time = $d['session_time']; |
|
421 |
|
$e_confirm_token = isset($d['confirm_token']) ? $d['confirm_token'] : ""; |
|
422 |
|
|
|
423 |
|
if (empty($d['confirm_token'])) { |
|
424 |
|
// no need to confirm account |
|
425 |
|
$e_confirmed = $now; |
|
426 |
|
} else { |
|
427 |
|
$e_confirmed = 0; |
|
428 |
|
} |
|
429 |
|
|
|
430 |
|
if ($d['uid'] == 0) { // add |
|
431 |
|
if (rg_user_pass_ok($d['pass']) !== TRUE) |
|
432 |
|
break; |
|
433 |
|
|
|
434 |
|
$sql = "INSERT INTO users (username, realname, salt, pass" |
|
435 |
|
. ", email, itime" |
|
436 |
|
. ", is_admin, disk_quota_mb, rights, session_time" |
|
437 |
|
. ", confirmed, confirm_token)" |
|
438 |
|
. " VALUES ('$e_username', '$e_realname', '$e_salt', '$e_pass'" |
|
439 |
|
. ", '$e_email', $now, $e_is_admin, $e_disk_quota_mb" |
|
440 |
|
. ", '$e_rights', $e_session_time" |
|
441 |
|
. ", $e_confirmed, '$e_confirm_token')" |
|
442 |
|
. " RETURNING uid"; |
|
443 |
|
} else { // edit |
|
444 |
|
$salt_pass_add = ""; |
|
445 |
|
if (!empty($d['pass'])) |
|
446 |
|
$salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'"; |
|
447 |
|
|
|
448 |
|
$sql = "UPDATE users" |
|
449 |
|
. " SET username = '$e_username'" |
|
450 |
|
. ", realname = '$e_realname'" |
|
451 |
|
. $salt_pass_add |
|
452 |
|
. ", email = '$e_email'" |
|
453 |
|
. ", is_admin = $e_is_admin" |
|
454 |
|
. ", disk_quota_mb = $e_disk_quota_mb" |
|
455 |
|
. ", rights = '$e_rights'" |
|
456 |
|
. ", session_time = $e_session_time" |
|
457 |
|
. " WHERE uid = " . $d['uid'] |
|
458 |
|
. " RETURNING uid"; |
|
459 |
|
} |
|
460 |
|
|
|
|
138 |
|
$sql = "SELECT * FROM plans ORDER BY position"; |
461 |
139 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
462 |
140 |
if ($res === FALSE) { |
if ($res === FALSE) { |
463 |
|
rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); |
|
|
141 |
|
rg_plan_set_error("cannot get plan list" |
|
142 |
|
. " (" . rg_sql_error() . ")"); |
464 |
143 |
break; |
break; |
465 |
144 |
} |
} |
466 |
|
$row = rg_sql_fetch_array($res); |
|
467 |
|
rg_sql_free_result($res); |
|
468 |
145 |
|
|
469 |
|
// invalidate cache |
|
470 |
|
rg_cache_unset("user::" . $d['uid']); |
|
471 |
|
|
|
472 |
|
if ($d['uid'] == 0) { // add |
|
473 |
|
$event = array("category" => 2000, "prio" => 50, |
|
474 |
|
"ui.uid" => $d['uid'], |
|
475 |
|
"ui.username" => $d['username'], |
|
476 |
|
"ui.email" => $d['email'] |
|
477 |
|
); |
|
478 |
|
$r = rg_event_add($db, $event); |
|
479 |
|
if ($r === FALSE) { |
|
480 |
|
rg_user_set_error("Canot add event!"); |
|
481 |
|
break; |
|
482 |
|
} |
|
483 |
|
} |
|
484 |
|
|
|
485 |
|
$ret = $row['uid']; |
|
486 |
|
} while (0); |
|
487 |
|
|
|
488 |
|
rg_prof_end("user_edit"); |
|
489 |
|
return $ret; |
|
490 |
|
} |
|
491 |
|
|
|
492 |
|
/* |
|
493 |
|
* Delete a user |
|
494 |
|
*/ |
|
495 |
|
function rg_user_remove($db, $uid) |
|
496 |
|
{ |
|
497 |
|
rg_prof_start("user_remove"); |
|
498 |
|
rg_log("user_remove: uid=$uid"); |
|
499 |
|
|
|
500 |
|
$ret = FALSE; |
|
501 |
|
do { |
|
502 |
|
$uid = sprintf("%u", $uid); |
|
503 |
|
|
|
504 |
|
$sql = "DELETE FROM users WHERE uid = $uid"; |
|
505 |
|
$res = rg_sql_query($db, $sql); |
|
506 |
|
if ($res === FALSE) { |
|
507 |
|
rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")"); |
|
508 |
|
break; |
|
|
146 |
|
$ret = array(); |
|
147 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
148 |
|
$row['exists'] = 1; |
|
149 |
|
$id = $row['id']; |
|
150 |
|
$ret[$id] = $row; |
509 |
151 |
} |
} |
510 |
152 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
511 |
153 |
|
|
512 |
|
// invalidate cache |
|
513 |
|
rg_cache_unset("user::" . $uid); |
|
514 |
|
|
|
515 |
|
$ret = TRUE; |
|
|
154 |
|
rg_cache_set("plan::list", serialize($ret)); |
516 |
155 |
} while (0); |
} while (0); |
517 |
156 |
|
|
518 |
|
rg_prof_end("user_remove"); |
|
|
157 |
|
rg_prof_end("plan_list"); |
519 |
158 |
return $ret; |
return $ret; |
520 |
159 |
} |
} |
521 |
160 |
|
|
522 |
161 |
/* |
/* |
523 |
|
* Returns info about a user (by uid, user or e-mail) |
|
|
162 |
|
* Returns info about a plan (by id) |
524 |
163 |
*/ |
*/ |
525 |
|
function rg_user_info($db, $uid, $user, $email) |
|
|
164 |
|
function rg_plan_info($db, $id) |
526 |
165 |
{ |
{ |
527 |
|
rg_prof_start("user_info"); |
|
|
166 |
|
rg_prof_start("plan_info"); |
528 |
167 |
|
|
529 |
168 |
$ret = array(); |
$ret = array(); |
530 |
169 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
531 |
170 |
$ret['exists'] = 0; |
$ret['exists'] = 0; |
532 |
|
$ret['uid'] = 0; |
|
533 |
|
$ret['is_admin'] = 0; |
|
534 |
|
|
|
535 |
|
$set_cache = FALSE; |
|
536 |
|
$set_cache_user = FALSE; |
|
537 |
|
$set_cache_email = FALSE; |
|
538 |
|
while (1) { |
|
539 |
|
//rg_log("user_info: uid=$uid user=$user email=$email."); |
|
540 |
171 |
|
|
541 |
|
if ($uid > 0) { |
|
542 |
|
$c = rg_cache_get("user::" . $uid); |
|
543 |
|
if ($c !== FALSE) { |
|
544 |
|
$ret = unserialize($c); |
|
545 |
|
if ($ret !== FALSE) |
|
546 |
|
break; |
|
547 |
|
} |
|
548 |
|
$add = " AND uid = " . sprintf("%u", $uid); |
|
549 |
|
$set_cache = TRUE; |
|
550 |
|
} else if (!empty($user)) { |
|
551 |
|
if (rg_user_ok($user) !== TRUE) |
|
552 |
|
break; |
|
553 |
|
|
|
554 |
|
$c = rg_cache_get("username_to_uid::" . $user); |
|
555 |
|
if ($c !== FALSE) { |
|
556 |
|
$uid = $c; |
|
557 |
|
continue; |
|
558 |
|
} |
|
559 |
|
|
|
560 |
|
$e_user = rg_sql_escape($db, $user); |
|
561 |
|
$add = " AND username = '$e_user'"; |
|
562 |
|
$set_cache_user = TRUE; |
|
563 |
|
} else if (!empty($email)) { |
|
564 |
|
$c = rg_cache_get("email_to_uid::" . $email); |
|
565 |
|
if ($c != FALSE) { |
|
566 |
|
$uid = $c; |
|
567 |
|
continue; |
|
568 |
|
} |
|
569 |
|
|
|
570 |
|
$e_email = rg_sql_escape($db, $email); |
|
571 |
|
$add = " AND email = '$e_email'"; |
|
572 |
|
$set_cache_email = TRUE; |
|
573 |
|
} |
|
574 |
|
|
|
575 |
|
$sql = "SELECT * FROM users WHERE 1 = 1" . $add; |
|
576 |
|
$res = rg_sql_query($db, $sql); |
|
577 |
|
if ($res === FALSE) { |
|
578 |
|
rg_user_set_error("cannot get info (" . rg_sql_error() . ")"); |
|
|
172 |
|
do { |
|
173 |
|
$list = rg_plan_list($db); |
|
174 |
|
if ($list === FALSE) { |
|
175 |
|
rg_plan_set_error("cannot load plans" |
|
176 |
|
. " (" . rg_sql_error() . ")"); |
579 |
177 |
break; |
break; |
580 |
178 |
} |
} |
581 |
179 |
|
|
582 |
180 |
$ret['ok'] = 1; |
$ret['ok'] = 1; |
583 |
|
$rows = rg_sql_num_rows($res); |
|
584 |
|
if ($rows > 0) |
|
585 |
|
$row = rg_sql_fetch_array($res); |
|
586 |
|
rg_sql_free_result($res); |
|
587 |
|
if ($rows == 0) { |
|
588 |
|
rg_user_set_error("user not found"); |
|
589 |
|
break; |
|
590 |
|
} |
|
591 |
|
|
|
592 |
|
$row['ok'] = 1; |
|
593 |
|
$row['exists'] = 1; |
|
594 |
|
|
|
595 |
|
$ret = $row; |
|
596 |
|
break; |
|
597 |
|
}; |
|
598 |
181 |
|
|
599 |
|
if ($ret['exists'] == 1) { |
|
600 |
|
if ($set_cache) |
|
601 |
|
rg_cache_set("user::" . $ret['uid'], serialize($ret)); |
|
602 |
|
} |
|
603 |
|
|
|
604 |
|
if ($ret['exists'] == 1) { |
|
605 |
|
if ($set_cache_user) |
|
606 |
|
rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']); |
|
|
182 |
|
$id = sprintf("%u", $id); |
|
183 |
|
if (!isset($list[$id])) |
|
184 |
|
break; |
607 |
185 |
|
|
608 |
|
if ($set_cache_email) |
|
609 |
|
rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']); |
|
610 |
|
} |
|
|
186 |
|
$ret = array_merge($ret, $list[$id]); |
|
187 |
|
} while (0); |
611 |
188 |
|
|
612 |
|
rg_prof_end("user_info"); |
|
|
189 |
|
rg_prof_end("plan_info"); |
613 |
190 |
return $ret; |
return $ret; |
614 |
191 |
} |
} |
615 |
192 |
|
|
616 |
193 |
/* |
/* |
617 |
|
* Loads ui based on sid, if possible |
|
|
194 |
|
* Returns a select list |
618 |
195 |
*/ |
*/ |
619 |
|
function rg_user_login_by_sid($db, $sid, &$ui) |
|
|
196 |
|
function rg_plan_select($db, $plan_id) |
620 |
197 |
{ |
{ |
621 |
|
rg_log("user_login_by_sid: sid=$sid..."); |
|
|
198 |
|
$list = rg_plan_list($db); |
|
199 |
|
if ($list === FALSE) |
|
200 |
|
return rg_warning("Could not load plans."); |
622 |
201 |
|
|
623 |
|
// Make sure it is not passed by client |
|
624 |
|
$ui = array(); |
|
625 |
|
$ui['uid'] = 0; |
|
626 |
|
$ui['is_admin'] = 0; |
|
627 |
|
$ui['username'] = ""; |
|
628 |
|
|
|
629 |
|
if (empty($sid)) { |
|
630 |
|
rg_log("\tNo sid!"); |
|
631 |
|
return FALSE; |
|
|
202 |
|
$ret = "<select name=\"plan_id\">\n"; |
|
203 |
|
foreach ($list as $row) { |
|
204 |
|
$add = ""; |
|
205 |
|
if ($row['id'] == $plan_id) |
|
206 |
|
$add = " selected"; |
|
207 |
|
$ret .= "<option value=\"" . htmlspecialchars($row['id']) |
|
208 |
|
. "\"" . $add . ">" |
|
209 |
|
. htmlspecialchars($row['name']) . "</option>\n"; |
632 |
210 |
} |
} |
633 |
211 |
|
|
634 |
|
$sess = rg_sess_valid($db, $sid); |
|
635 |
|
if ($sess == FALSE) |
|
636 |
|
return FALSE; |
|
637 |
|
|
|
638 |
|
$uid = $sess['uid']; |
|
639 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
640 |
|
if ($ui['exists'] != 1) { |
|
641 |
|
rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!"); |
|
642 |
|
rg_user_set_error("invalid uid"); |
|
643 |
|
return FALSE; |
|
644 |
|
} |
|
645 |
|
|
|
646 |
|
rg_sess_update($db, $sess); |
|
647 |
|
|
|
648 |
|
rg_user_set_last_seen($db, $ui['uid']); |
|
649 |
|
|
|
650 |
|
return TRUE; |
|
651 |
|
} |
|
652 |
|
|
|
653 |
|
/* |
|
654 |
|
* Test if a password is valid |
|
655 |
|
*/ |
|
656 |
|
function rg_user_pass_valid($db, $uid, $pass) |
|
657 |
|
{ |
|
658 |
|
rg_log("user_pass_valid: uid=$uid, pass=$pass..."); |
|
659 |
|
|
|
660 |
|
if (empty($pass)) { |
|
661 |
|
rg_user_set_error("password is empty"); |
|
662 |
|
return FALSE; |
|
663 |
|
} |
|
|
212 |
|
$ret .= "</select>\n"; |
664 |
213 |
|
|
665 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
666 |
|
if ($ui['exists'] != 1) { |
|
667 |
|
rg_user_set_error("user does not exists"); |
|
668 |
|
return FALSE; |
|
669 |
|
} |
|
670 |
|
|
|
671 |
|
$sha1pass = rg_user_pass($ui['salt'], $pass); |
|
672 |
|
if (strcmp($sha1pass, $ui['pass']) != 0) { |
|
673 |
|
rg_user_set_error("password is not ok"); |
|
674 |
|
return FALSE; |
|
675 |
|
} |
|
676 |
|
|
|
677 |
|
rg_log("\tPass is valid."); |
|
678 |
|
return TRUE; |
|
679 |
|
} |
|
680 |
|
|
|
681 |
|
/* |
|
682 |
|
* Auto login the user |
|
683 |
|
*/ |
|
684 |
|
function rg_user_auto_login($db, $uid, $lock_ip, &$ui) |
|
685 |
|
{ |
|
686 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
687 |
|
if ($ui['ok'] != 1) |
|
688 |
|
return FALSE; |
|
689 |
|
|
|
690 |
|
if ($ui['exists'] != 1) |
|
691 |
|
return FALSE; |
|
692 |
|
|
|
693 |
|
$secure = FALSE; |
|
694 |
|
if (isset($_SERVER['HTTPS'])) |
|
695 |
|
$secure = TRUE; |
|
696 |
|
|
|
697 |
|
$sid = rg_id(40); |
|
698 |
|
rg_sess_add($db, $uid, $sid, $ui['session_time'], $lock_ip); |
|
699 |
|
setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'], |
|
700 |
|
$secure, TRUE /* httponly */); |
|
701 |
|
|
|
702 |
|
return TRUE; |
|
703 |
|
} |
|
704 |
|
|
|
705 |
|
/* |
|
706 |
|
* Test if login is OK |
|
707 |
|
*/ |
|
708 |
|
function rg_user_login_by_user_pass($db, $user, $pass, $lock_ip, &$ui) |
|
709 |
|
{ |
|
710 |
|
rg_log("user_login_by_user_pass: user=$user, pass=$pass lock_ip=$lock_ip"); |
|
711 |
|
|
|
712 |
|
$ui = array(); |
|
713 |
|
$ui['uid'] = 0; |
|
714 |
|
$ui['is_admin'] = 0; |
|
715 |
|
|
|
716 |
|
if (empty($user) || empty($pass)) { |
|
717 |
|
rg_user_set_error("invalid user or pass"); |
|
718 |
|
return FALSE; |
|
719 |
|
} |
|
720 |
|
|
|
721 |
|
$ui0 = rg_user_info($db, 0, $user, ""); |
|
722 |
|
if ($ui0['ok'] != 1) { |
|
723 |
|
rg_user_set_error("internal error"); |
|
724 |
|
return FALSE; |
|
725 |
|
} |
|
726 |
|
if ($ui0['exists'] != 1) { |
|
727 |
|
rg_user_set_error("invalid user or pass"); |
|
728 |
|
return FALSE; |
|
729 |
|
} |
|
730 |
|
|
|
731 |
|
if ($ui0['suspended'] > 0) { |
|
732 |
|
rg_user_set_error("invalid user or pass"); |
|
733 |
|
return FALSE; |
|
734 |
|
} |
|
735 |
|
|
|
736 |
|
if ($ui0['confirmed'] == 0) { |
|
737 |
|
rg_user_set_error("invalid user or pass"); |
|
738 |
|
return FALSE; |
|
739 |
|
} |
|
740 |
|
|
|
741 |
|
$sha1pass = rg_user_pass($ui0['salt'], $pass); |
|
742 |
|
if (strcmp($sha1pass, $ui0['pass']) != 0) { |
|
743 |
|
rg_user_set_error("invalid user or pass"); |
|
744 |
|
return FALSE; |
|
745 |
|
} |
|
746 |
|
|
|
747 |
|
$ui = $ui0; |
|
748 |
|
rg_user_auto_login($db, $ui['uid'], $lock_ip, $ui); |
|
749 |
|
|
|
750 |
|
rg_user_set_last_seen($db, $ui['uid']); |
|
751 |
|
|
|
752 |
|
return TRUE; |
|
753 |
|
} |
|
754 |
|
|
|
755 |
|
/* |
|
756 |
|
* Suspend an account |
|
757 |
|
* 1=suspend, 0=unsuspend |
|
758 |
|
*/ |
|
759 |
|
function rg_user_suspend($db, $uid, $op) |
|
760 |
|
{ |
|
761 |
|
rg_log("user_suspend: uid=$uid, op=$op"); |
|
762 |
|
|
|
763 |
|
$now = time(); |
|
764 |
|
|
|
765 |
|
if ($op == 1) |
|
766 |
|
$v = $now; |
|
767 |
|
else |
|
768 |
|
$v = 0; |
|
769 |
|
|
|
770 |
|
$sql = "UPDATE users SET suspended = $v WHERE uid = $uid"; |
|
771 |
|
$res = rg_sql_query($db, $sql); |
|
772 |
|
if ($res === FALSE) { |
|
773 |
|
rg_user_set_error("cannot suspend (" . rg_sql_error() . ")"); |
|
774 |
|
return FALSE; |
|
775 |
|
} |
|
776 |
|
rg_sql_free_result($res); |
|
777 |
|
|
|
778 |
|
// Invalidate cache. |
|
779 |
|
rg_cache_unset("user::" . $uid); |
|
780 |
|
|
|
781 |
|
return TRUE; |
|
782 |
|
} |
|
783 |
|
|
|
784 |
|
/* |
|
785 |
|
* Make/remove admin |
|
786 |
|
* 1=make, 0=remove |
|
787 |
|
*/ |
|
788 |
|
function rg_user_make_admin($db, $uid, $op) |
|
789 |
|
{ |
|
790 |
|
rg_log("user_make_admin: uid=$uid, op=$op"); |
|
791 |
|
|
|
792 |
|
$sql = "UPDATE users SET is_admin = $op WHERE uid = $uid"; |
|
793 |
|
$res = rg_sql_query($db, $sql); |
|
794 |
|
if ($res === FALSE) { |
|
795 |
|
rg_user_set_error("cannot make admin (" . rg_sql_error() . ")"); |
|
796 |
|
return FALSE; |
|
797 |
|
} |
|
798 |
|
rg_sql_free_result($res); |
|
799 |
|
|
|
800 |
|
// Invalidate cache. |
|
801 |
|
rg_cache_unset("user::" . $uid); |
|
802 |
|
|
|
803 |
|
return TRUE; |
|
804 |
|
} |
|
805 |
|
|
|
806 |
|
/* |
|
807 |
|
* Update last_seen field |
|
808 |
|
*/ |
|
809 |
|
function rg_user_set_last_seen($db, $uid) |
|
810 |
|
{ |
|
811 |
|
rg_log("user_set_last_seen: uid=$uid"); |
|
812 |
|
|
|
813 |
|
$now = time(); |
|
814 |
|
|
|
815 |
|
$sql = "UPDATE users SET last_seen = $now WHERE uid = $uid"; |
|
816 |
|
$res = rg_sql_query($db, $sql); |
|
817 |
|
if ($res === FALSE) { |
|
818 |
|
rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")"); |
|
819 |
|
return FALSE; |
|
820 |
|
} |
|
821 |
|
rg_sql_free_result($res); |
|
822 |
|
|
|
823 |
|
// TODO: check if we need to invalidate cache |
|
824 |
|
|
|
825 |
|
return TRUE; |
|
|
214 |
|
return $ret; |
826 |
215 |
} |
} |
827 |
216 |
|
|
828 |
217 |
/* |
/* |
829 |
|
* List users |
|
|
218 |
|
* High-level function for rg_plan_list |
830 |
219 |
*/ |
*/ |
831 |
|
function rg_user_list($db, $url) |
|
|
220 |
|
function rg_plan_list_high_level($db, $sid, $more) |
832 |
221 |
{ |
{ |
833 |
|
rg_log("user_list, url=$url..."); |
|
834 |
|
|
|
835 |
222 |
$ret = ""; |
$ret = ""; |
836 |
223 |
|
|
837 |
|
$uid = rg_var_uint("uid"); |
|
838 |
|
|
|
839 |
|
$suspend = rg_var_uint("suspend"); |
|
840 |
|
if ($suspend == 1) { |
|
841 |
|
if (!rg_user_suspend($db, $uid, 1)) |
|
842 |
|
$ret .= "<font color=red>Cannot suspend!</font><br />"; |
|
843 |
|
} |
|
844 |
|
|
|
845 |
|
$unsuspend = rg_var_uint("unsuspend"); |
|
846 |
|
if ($unsuspend == 1) { |
|
847 |
|
if (!rg_user_suspend($db, $uid, 0)) |
|
848 |
|
$ret .= "<font color=red>Cannot unsuspend!</font><br />"; |
|
849 |
|
} |
|
850 |
|
|
|
851 |
|
$make_admin = rg_var_uint("make_admin"); |
|
852 |
|
if ($make_admin == 1) { |
|
853 |
|
if (!rg_user_make_admin($db, $uid, 1)) |
|
854 |
|
$ret .= "<font color=red>Cannot make admin!</font><br />"; |
|
855 |
|
} |
|
856 |
|
|
|
857 |
|
$remove_admin = rg_var_uint("remove_admin"); |
|
858 |
|
if ($remove_admin == 1) { |
|
859 |
|
if (!rg_user_make_admin($db, $uid, 0)) |
|
860 |
|
$ret .= "<font color=red>Cannot remove admin!</font><br />"; |
|
861 |
|
} |
|
|
224 |
|
$list_errmsg = array(); |
|
225 |
|
$del_errmsg = array(); |
862 |
226 |
|
|
863 |
|
$remove = rg_var_uint("remove"); |
|
864 |
|
if ($remove > 0) { |
|
865 |
|
if (!rg_user_remove($db, $uid)) |
|
866 |
|
$ret .= "<font color=red>Cannot remove!</font><br />"; |
|
867 |
|
} |
|
868 |
|
|
|
869 |
|
$sql = "SELECT * FROM users ORDER BY username"; |
|
870 |
|
$res = rg_sql_query($db, $sql); |
|
871 |
|
if ($res === FALSE) { |
|
872 |
|
rg_user_set_error("cannot get info (" . rg_sql_error() . ")!"); |
|
873 |
|
return FALSE; |
|
874 |
|
} |
|
875 |
|
|
|
876 |
|
$ret .= "<table>\n"; |
|
877 |
|
$ret .= "<tr>\n"; |
|
878 |
|
$ret .= " <th>User name</th>\n"; |
|
879 |
|
$ret .= " <th>Name</th>\n"; |
|
880 |
|
$ret .= " <th>E-mail</th>\n"; |
|
881 |
|
$ret .= " <th>Admin?</th>\n"; |
|
882 |
|
$ret .= " <th>Creation date (UTC)</th>\n"; |
|
883 |
|
$ret .= " <th>Quota</th>\n"; |
|
884 |
|
$ret .= " <th>Suspended?</th>\n"; |
|
885 |
|
$ret .= " <th>Confirmed?</th>\n"; |
|
886 |
|
$ret .= " <th>Session time</th>\n"; |
|
887 |
|
$ret .= " <th>Last seen (UTC)</th>\n"; |
|
888 |
|
$ret .= " <th>Rights</th>\n"; |
|
889 |
|
$ret .= " <th>Operations</th>\n"; |
|
890 |
|
$ret .= "</tr>\n"; |
|
891 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
892 |
|
$ret .= "<tr>\n"; |
|
893 |
|
$ret .= " <td>" . $row['username'] . "</td>\n"; |
|
894 |
|
$ret .= " <td>" . $row['realname'] . "</td>\n"; |
|
895 |
|
$ret .= " <td>" . $row['email'] . "</td>\n"; |
|
896 |
|
$ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n"; |
|
897 |
|
$ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n"; |
|
898 |
|
if ($row['disk_quota_mb'] > 0) |
|
899 |
|
$_v = rg_1024($row['disk_quota_mb'] * 1024 * 1024); |
|
900 |
|
else |
|
901 |
|
$_v = "unlimited"; |
|
902 |
|
$ret .= " <td>" . $_v . "</td>\n"; |
|
903 |
|
$ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n"; |
|
904 |
|
$ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n"; |
|
905 |
|
$ret .= " <td>" . $row['session_time'] . "s</td>\n"; |
|
906 |
|
$v = $row['last_seen'] == 0 ? "-" : gmdate("Y-m-d", $row['last_seen']); |
|
907 |
|
$ret .= " <td>" . $v . "</td>\n"; |
|
908 |
|
$v = implode(", ", rg_rights_text("user", $row['rights'])); |
|
909 |
|
$ret .= " <td>" . $v . "</td>\n"; |
|
910 |
|
|
|
911 |
|
// operations |
|
912 |
|
$_url = $url . "&uid=" . $row['uid']; |
|
913 |
|
$ret .= " <td>"; |
|
914 |
|
|
|
915 |
|
// edit |
|
916 |
|
$ret .= "[<a href=\"$_url&subsubop=3\">Edit</a>]"; |
|
|
227 |
|
$delete = rg_var_uint("delete"); |
|
228 |
|
do { |
|
229 |
|
if ($delete != 1) |
|
230 |
|
break; |
917 |
231 |
|
|
918 |
|
// suspend |
|
919 |
|
$v = "suspend=1"; $t = "Suspend"; |
|
920 |
|
if ($row['suspended'] > 0) { |
|
921 |
|
$t = "Unsuspend"; |
|
922 |
|
$v = "unsuspend=1"; |
|
|
232 |
|
$token = rg_var_str("token"); |
|
233 |
|
if (!rg_token_valid($db, $sid, $token)) { |
|
234 |
|
$del_errmsg[] = "Invalid token. Try again."; |
|
235 |
|
break; |
923 |
236 |
} |
} |
924 |
|
$ret .= "[<a href=\"$_url&subsubop=1&$v\">$t</a>]"; |
|
925 |
237 |
|
|
926 |
|
// admin |
|
927 |
|
$v = "make_admin=1"; $t = "Make admin"; |
|
928 |
|
if ($row['is_admin'] == 1) { |
|
929 |
|
$t = "Remove admin"; |
|
930 |
|
$v = "remove_admin=1"; |
|
|
238 |
|
$list = rg_var_str("delete_list"); |
|
239 |
|
$r = rg_plan_remove($db, $list); |
|
240 |
|
if ($r !== TRUE) { |
|
241 |
|
$more['errmsg'] = rg_plan_error(); |
|
242 |
|
$del_errmsg[] = rg_template("admin/plans/delete_err.html", $more); |
|
243 |
|
break; |
931 |
244 |
} |
} |
932 |
|
$ret .= "[<a href=\"$_url&subsubop=1&$v\">$t</a>]"; |
|
933 |
|
|
|
934 |
|
// remove |
|
935 |
|
if ($row['suspended'] > 0) |
|
936 |
|
$ret .= "[<a href=\"$_url&subsubop=1&remove=1\">Remove!</a>]"; |
|
937 |
|
|
|
938 |
|
$ret .= " </td>"; |
|
939 |
|
$ret .= "</tr>\n"; |
|
940 |
|
} |
|
941 |
|
$ret .= "</table>\n"; |
|
942 |
|
rg_sql_free_result($res); |
|
943 |
|
|
|
944 |
|
return $ret; |
|
945 |
|
} |
|
946 |
|
|
|
947 |
|
/* |
|
948 |
|
* Returns uid by token, if not expired |
|
949 |
|
*/ |
|
950 |
|
function rg_user_forgot_pass_uid($db, $token) |
|
951 |
|
{ |
|
952 |
|
$ret = array(); |
|
953 |
|
$ret['ok'] = 0; |
|
954 |
|
$ret['uid'] = 0; |
|
955 |
|
|
|
956 |
|
rg_log("user_forgot_pass_uid: token=$token"); |
|
957 |
|
|
|
958 |
|
$now = time(); |
|
959 |
|
$e_token = rg_sql_escape($db, $token); |
|
|
245 |
|
} while (0); |
960 |
246 |
|
|
961 |
|
$sql = "SELECT uid FROM forgot_pass" |
|
962 |
|
. " WHERE token = '$e_token'" |
|
963 |
|
. " AND expire > $now"; |
|
964 |
|
$res = rg_sql_query($db, $sql); |
|
965 |
|
if ($res === FALSE) { |
|
966 |
|
rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")"); |
|
967 |
|
return $ret; |
|
|
247 |
|
$list = rg_plan_list($db); |
|
248 |
|
if ($list === FALSE) { |
|
249 |
|
$more['errmsg'] = rg_plan_error(); |
|
250 |
|
return rg_template("admin/plans/list_err.html", $more); |
968 |
251 |
} |
} |
969 |
252 |
|
|
970 |
|
$ret['ok'] = 1; |
|
971 |
|
|
|
972 |
|
$rows = rg_sql_num_rows($res); |
|
973 |
|
if ($rows > 0) |
|
974 |
|
$row = rg_sql_fetch_array($res); |
|
975 |
|
rg_sql_free_result($res); |
|
976 |
|
if ($rows == 0) |
|
977 |
|
return $ret; |
|
978 |
|
|
|
979 |
|
$ret['uid'] = $row['uid']; |
|
980 |
|
|
|
|
253 |
|
$more['rg_form_token'] = rg_token_get($db, $sid); |
|
254 |
|
$more['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg); |
|
255 |
|
$ret .= rg_template_table("admin/plans/list", $list, $more); |
981 |
256 |
return $ret; |
return $ret; |
982 |
257 |
} |
} |
983 |
258 |
|
|
984 |
259 |
/* |
/* |
985 |
|
* Reset password function (send mail) - helper |
|
|
260 |
|
* High-level function for rg_plan_edit. |
986 |
261 |
*/ |
*/ |
987 |
|
function rg_user_forgot_pass_mail_prepare($db, $email) |
|
|
262 |
|
function rg_plan_edit_high_level($db, $sid, $more) |
988 |
263 |
{ |
{ |
989 |
|
rg_log("user_forgot_pass_mail_prepare: email=$email"); |
|
|
264 |
|
rg_log("plan_edit_high_level"); |
990 |
265 |
|
|
991 |
|
$ret = array(); |
|
992 |
|
$ret['ok'] = 0; |
|
993 |
|
$ret['exists'] = 0; |
|
994 |
|
|
|
995 |
|
$expire = time() + 24 * 3600; |
|
996 |
|
$token = rg_id(20); |
|
|
266 |
|
$doit = rg_var_uint("doit"); |
|
267 |
|
$plan_id = rg_var_uint("id"); |
997 |
268 |
|
|
998 |
|
$r = rg_user_info($db, 0, "", $email); |
|
999 |
|
if ($r['ok'] == 0) { |
|
1000 |
|
rg_log("\tInternal error."); |
|
1001 |
|
return $ret; |
|
1002 |
|
} |
|
1003 |
|
if ($r['exists'] == 0) { |
|
1004 |
|
rg_log("\tUser does not exists."); |
|
1005 |
|
$ret['ok'] = 1; |
|
1006 |
|
return $ret; |
|
1007 |
|
} |
|
1008 |
|
$uid = $r['uid']; |
|
1009 |
|
|
|
1010 |
|
// store token in database |
|
1011 |
|
$sql = "INSERT INTO forgot_pass (token, uid, expire)" |
|
1012 |
|
. " VALUES ('$token', $uid, $expire)"; |
|
1013 |
|
$res = rg_sql_query($db, $sql); |
|
1014 |
|
if ($res === FALSE) { |
|
1015 |
|
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
|
1016 |
|
return $ret; |
|
|
269 |
|
$ret = ""; |
|
270 |
|
$pi = array(); |
|
271 |
|
|
|
272 |
|
if ($doit == 0) { |
|
273 |
|
if ($plan_id > 0) { |
|
274 |
|
$pi = rg_plan_info($db, $plan_id); |
|
275 |
|
if ($pi['exists'] != 1) { |
|
276 |
|
$ret .= rg_warning("Invalid plan."); |
|
277 |
|
return $ret; |
|
278 |
|
} |
|
279 |
|
} else { |
|
280 |
|
// Defaults. |
|
281 |
|
$pi['id'] = 0; |
|
282 |
|
$pi['name'] = ""; |
|
283 |
|
$pi['description'] = ""; |
|
284 |
|
$pi['disk_mb'] = "0"; |
|
285 |
|
$pi['users'] = "0"; |
|
286 |
|
$pi['bw'] = "0"; |
|
287 |
|
$pi['speed'] = "0"; |
|
288 |
|
$pi['position'] = "100"; |
|
289 |
|
} |
1017 |
290 |
} |
} |
1018 |
|
rg_sql_free_result($res); |
|
1019 |
|
|
|
1020 |
|
$ret['ok'] = 1; |
|
1021 |
|
$ret['exists'] = 1; |
|
1022 |
|
$ret['token'] = $token; |
|
1023 |
291 |
|
|
1024 |
|
rg_log("DEBUG: user_forgot_pass_mail_prepare: ret=" . rg_array2string($ret)); |
|
1025 |
|
|
|
1026 |
|
return $ret; |
|
1027 |
|
} |
|
1028 |
|
|
|
1029 |
|
/* |
|
1030 |
|
* Reset password function (send mail) |
|
1031 |
|
*/ |
|
1032 |
|
function rg_user_forgot_pass_mail($db, $email) |
|
1033 |
|
{ |
|
1034 |
|
global $rg_admin_name, $rg_admin_email; |
|
1035 |
|
|
|
1036 |
|
rg_log("user_forgot_pass_mail: email=$email"); |
|
1037 |
|
|
|
1038 |
|
$ret = array(); |
|
1039 |
|
$ret['ok'] = 0; |
|
1040 |
|
$ret['exists'] = 0; |
|
1041 |
|
|
|
1042 |
|
$r = rg_user_forgot_pass_mail_prepare($db, $email); |
|
1043 |
|
if ($r['exists'] != 1) { |
|
1044 |
|
rg_log("\tUser does not exists."); |
|
1045 |
|
return $r; |
|
1046 |
|
} |
|
|
292 |
|
$errmsg = array(); |
|
293 |
|
$load_form = TRUE; |
|
294 |
|
do { |
|
295 |
|
if ($doit != 1) |
|
296 |
|
break; |
1047 |
297 |
|
|
1048 |
|
$ret['exists'] = 1; |
|
|
298 |
|
$pi = array(); |
|
299 |
|
$pi['id'] = $plan_id; |
|
300 |
|
$pi['name'] = rg_var_str("name"); |
|
301 |
|
$pi['description'] = rg_var_str("description"); |
|
302 |
|
$pi['disk_mb'] = rg_var_uint("disk_mb"); |
|
303 |
|
$pi['users'] = rg_var_uint("users"); |
|
304 |
|
$pi['bw'] = rg_var_uint("bw"); |
|
305 |
|
$pi['speed'] = rg_var_uint("speed"); |
|
306 |
|
$pi['position'] = rg_var_uint("position"); |
|
307 |
|
$token = rg_var_str("token"); |
|
308 |
|
|
|
309 |
|
if (!rg_token_valid($db, $sid, $token)) { |
|
310 |
|
$errmsg[] = "Invalid token. Try again."; |
|
311 |
|
break; |
|
312 |
|
} |
1049 |
313 |
|
|
1050 |
|
$headers = "From: $rg_admin_name <$rg_admin_email>"; |
|
|
314 |
|
$r = rg_plan_edit($db, $pi); |
|
315 |
|
if ($r === FALSE) { |
|
316 |
|
$errmsg[] = "cannot add/edit plan: " . rg_plan_error(); |
|
317 |
|
break; |
|
318 |
|
} |
1051 |
319 |
|
|
1052 |
|
$base_url = rg_base_url(); |
|
|
320 |
|
// TODO: move to template. |
|
321 |
|
$ret = rg_ok("Plan was added with success."); |
|
322 |
|
$load_form = FALSE; |
|
323 |
|
} while (0); |
1053 |
324 |
|
|
1054 |
|
if (!mail($email, |
|
1055 |
|
"Forgot password", |
|
1056 |
|
"Hello!\n\n" |
|
1057 |
|
. "If you want to reset the password, follow:\n" |
|
1058 |
|
. $base_url |
|
1059 |
|
. rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token'] |
|
1060 |
|
. "\n\nRocketGit team", |
|
1061 |
|
$headers, |
|
1062 |
|
"-f $rg_admin_email")) { |
|
1063 |
|
rg_user_set_error("cannot send mail ($php_errormsg)!"); |
|
1064 |
|
return $ret; |
|
|
325 |
|
if ($load_form) { |
|
326 |
|
$more = array_merge($more, $pi); |
|
327 |
|
$more['HTML:errmsg'] = rg_template_errmsg($errmsg); |
|
328 |
|
$more['rg_form_token'] = rg_token_get($db, $sid); |
|
329 |
|
$ret .= rg_template("admin/plans/add_edit.html", $more); |
1065 |
330 |
} |
} |
1066 |
331 |
|
|
1067 |
|
$ret['ok'] = 1; |
|
1068 |
|
|
|
1069 |
|
rg_log("DEBUG: user_forgot_pass_mail: ret=" . rg_array2string($ret) . "."); |
|
1070 |
332 |
return $ret; |
return $ret; |
1071 |
333 |
} |
} |
1072 |
334 |
|
|
1073 |
|
/* |
|
1074 |
|
* After reseting the pass, we have to destroy all 'reset pass' requests |
|
1075 |
|
*/ |
|
1076 |
|
function rg_user_forgot_pass_destroy($db, $uid) |
|
1077 |
|
{ |
|
1078 |
|
rg_log("user_forgot_pass_destroy: uid=$uid"); |
|
1079 |
|
|
|
1080 |
|
$sql = "DELETE FROM forgot_pass WHERE uid = $uid"; |
|
1081 |
|
$res = rg_sql_query($db, $sql); |
|
1082 |
|
if ($res === FALSE) { |
|
1083 |
|
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
|
1084 |
|
return FALSE; |
|
1085 |
|
} |
|
1086 |
|
rg_sql_free_result($res); |
|
1087 |
|
|
|
1088 |
|
return TRUE; |
|
1089 |
|
} |
|
1090 |
|
|
|
1091 |
|
function rg_user_set_pass($db, $uid, $pass) |
|
1092 |
|
{ |
|
1093 |
|
rg_log("user_set_pass: uid=$uid pass=$pass"); |
|
1094 |
|
|
|
1095 |
|
$e_salt = rg_id(40); |
|
1096 |
|
$e_sha1pass = rg_user_pass($e_salt, $pass); |
|
1097 |
|
|
|
1098 |
|
$sql = "UPDATE users SET" |
|
1099 |
|
." salt = '$e_salt'" |
|
1100 |
|
. ", pass = '$e_sha1pass'" |
|
1101 |
|
. " WHERE uid = " . $uid; |
|
1102 |
|
$res = rg_sql_query($db, $sql); |
|
1103 |
|
if ($res === FALSE) { |
|
1104 |
|
rg_user_set_error("cannot update pass (" . rg_sql_error() . ")"); |
|
1105 |
|
return FALSE; |
|
1106 |
|
} |
|
1107 |
|
rg_sql_free_result($res); |
|
1108 |
|
|
|
1109 |
|
// Invalidate cache. |
|
1110 |
|
rg_cache_unset("user::" . $uid); |
|
1111 |
|
|
|
1112 |
|
return TRUE; |
|
1113 |
|
} |
|
1114 |
|
|
|
1115 |
|
/* |
|
1116 |
|
* Confirm account creation (send mail) |
|
1117 |
|
*/ |
|
1118 |
|
function rg_user_confirm_send($email, $token) |
|
1119 |
|
{ |
|
1120 |
|
global $rg_admin_name, $rg_admin_email; |
|
1121 |
|
|
|
1122 |
|
rg_log("user_confirm_send: email=$email, token=$token"); |
|
1123 |
|
|
|
1124 |
|
$headers = "From: $rg_admin_name <$rg_admin_email>"; |
|
1125 |
|
|
|
1126 |
|
$proto = "http://"; |
|
1127 |
|
if (isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'], "on") == 0)) |
|
1128 |
|
$proto = "https://"; |
|
1129 |
|
|
|
1130 |
|
if (!mail($email, |
|
1131 |
|
"Account creation confirmation", |
|
1132 |
|
"Hello!\n\n" |
|
1133 |
|
. "Please confirm your account creation following:\n" |
|
1134 |
|
. $proto |
|
1135 |
|
. @$_SERVER['HTTP_HOST'] |
|
1136 |
|
. rg_re_url("/op/confirm") . "&token=" . $token |
|
1137 |
|
. "\n\nRocketGit team", |
|
1138 |
|
$headers, |
|
1139 |
|
"-f $rg_admin_email")) { |
|
1140 |
|
rg_user_set_error("cannot send mail ($php_errormsg)!"); |
|
1141 |
|
return FALSE; |
|
1142 |
|
} |
|
1143 |
|
|
|
1144 |
|
return TRUE; |
|
1145 |
|
} |
|
1146 |
|
|
|
1147 |
|
/* |
|
1148 |
|
* Confirm account creation |
|
1149 |
|
*/ |
|
1150 |
|
function rg_user_confirm($db, $token) |
|
1151 |
|
{ |
|
1152 |
|
$now = time(); |
|
1153 |
|
|
|
1154 |
|
$sql = "SELECT uid FROM users WHERE confirm_token = '$token'"; |
|
1155 |
|
$res = rg_sql_query($db, $sql); |
|
1156 |
|
if ($res === FALSE) { |
|
1157 |
|
rg_user_set_error("cannot search for token (" . rg_sql_error() . ")"); |
|
1158 |
|
return FALSE; |
|
1159 |
|
} |
|
1160 |
|
$rows = rg_sql_num_rows($res); |
|
1161 |
|
if ($rows > 0) |
|
1162 |
|
$row = rg_sql_fetch_array($res); |
|
1163 |
|
rg_sql_free_result($res); |
|
1164 |
|
if ($rows == 0) { |
|
1165 |
|
rg_user_set_error("cannot find token (" . rg_sql_error() . ")"); |
|
1166 |
|
return FALSE; |
|
1167 |
|
} |
|
1168 |
|
$uid = $row['uid']; |
|
1169 |
|
|
|
1170 |
|
$sql = "UPDATE users SET confirmed = $now" |
|
1171 |
|
. " WHERE uid = $uid"; |
|
1172 |
|
$res = rg_sql_query($db, $sql); |
|
1173 |
|
if ($res === FALSE) { |
|
1174 |
|
rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")"); |
|
1175 |
|
return FALSE; |
|
1176 |
|
} |
|
1177 |
|
rg_sql_free_result($res); |
|
1178 |
|
|
|
1179 |
|
// TODO: invalidate cache? |
|
1180 |
|
|
|
1181 |
|
return $uid; |
|
1182 |
|
} |
|
1183 |
|
|
|
1184 |
|
/* |
|
1185 |
|
* Add a suggestion to database |
|
1186 |
|
*/ |
|
1187 |
|
function rg_user_suggestion($db, $uid, $email, $suggestion) |
|
1188 |
|
{ |
|
1189 |
|
$e_email = rg_sql_escape($db, $email); |
|
1190 |
|
$e_suggestion = rg_sql_escape($db, $suggestion); |
|
1191 |
|
|
|
1192 |
|
$sql = "INSERT INTO suggestions (uid, email, suggestion)" |
|
1193 |
|
. " VALUES ($uid, '$e_email', '$e_suggestion')"; |
|
1194 |
|
$res = rg_sql_query($db, $sql); |
|
1195 |
|
if ($res === FALSE) { |
|
1196 |
|
rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")"); |
|
1197 |
|
return FALSE; |
|
1198 |
|
} |
|
1199 |
|
rg_sql_free_result($res); |
|
1200 |
|
|
|
1201 |
|
return TRUE; |
|
1202 |
|
} |
|
1203 |
|
|
|
1204 |
335 |
?> |
?> |
File inc/repo.inc.php changed (mode: 100644) (index eba96e5..f566a7f) |
... |
... |
$rg_repo_rights = array( |
14 |
14 |
"P" => "Push", |
"P" => "Push", |
15 |
15 |
"H" => "Anonymous push", |
"H" => "Anonymous push", |
16 |
16 |
"S" => "Create annotated tag", |
"S" => "Create annotated tag", |
17 |
|
"N" => "Modify annotated tag", |
|
18 |
17 |
"n" => "Delete annotated tag", |
"n" => "Delete annotated tag", |
19 |
18 |
"Y" => "Create un-annotated tag", |
"Y" => "Create un-annotated tag", |
20 |
19 |
"U" => "Modify un-annotated tag", |
"U" => "Modify un-annotated tag", |
|
... |
... |
function rg_repo_history_insert($db, $repo_id, $category, $message) |
290 |
289 |
$ret = FALSE; |
$ret = FALSE; |
291 |
290 |
do { |
do { |
292 |
291 |
$now = time(); |
$now = time(); |
293 |
|
$e_message = rg_sql_escape($db, $message); |
|
|
292 |
|
$params = array($now, $repo_id, $category, $message); |
294 |
293 |
$sql = "INSERT INTO repo_history_" . gmdate("Y_m", $now) |
$sql = "INSERT INTO repo_history_" . gmdate("Y_m", $now) |
295 |
294 |
. " (itime, repo_id, category, message)" |
. " (itime, repo_id, category, message)" |
296 |
|
. " VALUES ($now, $repo_id, $category, '$e_message')"; |
|
297 |
|
$res = rg_sql_query($db, $sql); |
|
|
295 |
|
. " VALUES ($1, $2, $3, $4)"; |
|
296 |
|
$res = rg_sql_query_params($db, $sql, $params); |
298 |
297 |
if ($res === FALSE) |
if ($res === FALSE) |
299 |
298 |
break; |
break; |
300 |
299 |
|
|
|
... |
... |
function rg_repo_invalidate_cache($uid, $repo_id) |
435 |
434 |
} |
} |
436 |
435 |
|
|
437 |
436 |
/* |
/* |
438 |
|
* Return info about a repo |
|
|
437 |
|
* Returns info about a repo |
439 |
438 |
* If you want to lookup by repo_id or uid/repo_name |
* If you want to lookup by repo_id or uid/repo_name |
440 |
439 |
*/ |
*/ |
441 |
440 |
function rg_repo_info($db, $repo_id, $uid, $repo_name) |
function rg_repo_info($db, $repo_id, $uid, $repo_name) |
|
... |
... |
function rg_repo_info($db, $repo_id, $uid, $repo_name) |
449 |
448 |
$ret['exists'] = 0; |
$ret['exists'] = 0; |
450 |
449 |
do { |
do { |
451 |
450 |
if ($repo_id > 0) { |
if ($repo_id > 0) { |
452 |
|
$key = $repo_id; |
|
|
451 |
|
+$key = $repo_id; |
453 |
452 |
if (isset($rg_repo_info_cache[$key])) { |
if (isset($rg_repo_info_cache[$key])) { |
454 |
453 |
$ret = $rg_repo_info_cache[$key]; |
$ret = $rg_repo_info_cache[$key]; |
455 |
454 |
$ret['from_cache'] = 1; |
$ret['from_cache'] = 1; |
|
... |
... |
function rg_repo_info($db, $repo_id, $uid, $repo_name) |
458 |
457 |
} |
} |
459 |
458 |
|
|
460 |
459 |
if ($repo_id > 0) { |
if ($repo_id > 0) { |
461 |
|
$add = " AND repo_id = $repo_id"; |
|
|
460 |
|
$params = array($repo_id); |
|
461 |
|
$sql = "SELECT * FROM repos WHERE repo_id = $1"; |
462 |
462 |
} else if (!empty($repo_name)) { |
} else if (!empty($repo_name)) { |
463 |
|
$e_repo = rg_sql_escape($db, $repo_name); |
|
464 |
|
$add = " AND uid = $uid AND name = '$e_repo'"; |
|
|
463 |
|
$params = array($uid, $repo_name); |
|
464 |
|
$sql = "SELECT * FROM repos WHERE uid = $1 AND name = $2"; |
465 |
465 |
} else { |
} else { |
466 |
466 |
rg_repo_set_error("no repo_id or user/repo specified!"); |
rg_repo_set_error("no repo_id or user/repo specified!"); |
467 |
467 |
break; |
break; |
468 |
468 |
} |
} |
469 |
469 |
|
|
470 |
|
$sql = "SELECT * FROM repos WHERE 1 = 1" . $add; |
|
471 |
|
$res = rg_sql_query($db, $sql); |
|
|
470 |
|
$res = rg_sql_query_params($db, $sql, $params); |
472 |
471 |
if ($res === FALSE) { |
if ($res === FALSE) { |
473 |
472 |
rg_repo_set_error("cannot query (" . rg_sql_error() . ")"); |
rg_repo_set_error("cannot query (" . rg_sql_error() . ")"); |
474 |
473 |
break; |
break; |
475 |
474 |
} |
} |
476 |
|
$ret['ok'] = 1; |
|
477 |
475 |
$rows = rg_sql_num_rows($res); |
$rows = rg_sql_num_rows($res); |
478 |
476 |
if ($rows > 0) |
if ($rows > 0) |
479 |
477 |
$ret = rg_sql_fetch_array($res); |
$ret = rg_sql_fetch_array($res); |
480 |
478 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
|
479 |
|
$ret['ok'] = 1; |
|
480 |
|
|
481 |
481 |
if (($rows == 0) && ($repo_id == 0)) { |
if (($rows == 0) && ($repo_id == 0)) { |
482 |
482 |
// Repo not found, maybe it was renamed |
// Repo not found, maybe it was renamed |
483 |
483 |
$_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name); |
$_repo_id = rg_repo_lookup_by_old_name($db, $uid, $repo_name); |
|
... |
... |
function rg_repo_info($db, $repo_id, $uid, $repo_name) |
491 |
491 |
} |
} |
492 |
492 |
|
|
493 |
493 |
// small fixes |
// small fixes |
494 |
|
if ($rows > 0) |
|
|
494 |
|
if ($rows > 0) { |
|
495 |
|
$ret['exists'] = 1; |
495 |
496 |
$ret['HTML:description'] = nl2br($ret['description']); |
$ret['HTML:description'] = nl2br($ret['description']); |
496 |
|
|
|
497 |
|
$ret['exists'] = 1; |
|
498 |
|
$ret['ok'] = 1; |
|
|
497 |
|
} |
499 |
498 |
} while (0); |
} while (0); |
500 |
499 |
|
|
501 |
500 |
if (($repo_id > 0) && !isset($ret['from_cache'])) |
if (($repo_id > 0) && !isset($ret['from_cache'])) |
|
... |
... |
function rg_repo_create($db, $master, $ui, $name, $max_commit_size, |
585 |
584 |
break; |
break; |
586 |
585 |
} |
} |
587 |
586 |
|
|
588 |
|
$e_name = rg_sql_escape($db, $name); |
|
589 |
587 |
$description = trim($description); |
$description = trim($description); |
590 |
|
$e_description = rg_sql_escape($db, $description); |
|
591 |
|
|
|
592 |
588 |
$itime = time(); |
$itime = time(); |
593 |
589 |
|
|
|
590 |
|
$params = array($ui['uid'], $master, $name, $itime, |
|
591 |
|
$max_commit_size, $description, $rights, $max_users); |
594 |
592 |
$sql = "INSERT INTO repos (uid, master, name" |
$sql = "INSERT INTO repos (uid, master, name" |
595 |
593 |
. ", itime, max_commit_size, description, git_dir_done" |
. ", itime, max_commit_size, description, git_dir_done" |
596 |
594 |
. ", default_rights, max_users)" |
. ", default_rights, max_users)" |
597 |
|
. " VALUES (" . $ui['uid'] . ", $master, '$e_name'" |
|
598 |
|
. ", $itime, $max_commit_size, '$e_description', 0" |
|
599 |
|
. ", '$rights', $max_users)" |
|
|
595 |
|
. " VALUES ($1, $2, $3, $4, $5, $6, 0, $7, $8)" |
600 |
596 |
. " RETURNING repo_id"; |
. " RETURNING repo_id"; |
601 |
|
$res = rg_sql_query($db, $sql); |
|
|
597 |
|
$res = rg_sql_query_params($db, $sql, $params); |
602 |
598 |
if ($res === FALSE) { |
if ($res === FALSE) { |
603 |
599 |
rg_repo_set_error("Cannot insert (" . rg_sql_error() . ")"); |
rg_repo_set_error("Cannot insert (" . rg_sql_error() . ")"); |
604 |
600 |
break; |
break; |
|
... |
... |
function rg_repo_delete($db, $repo_id, $ui) |
648 |
644 |
// TODO: Check rights |
// TODO: Check rights |
649 |
645 |
// TODO: Transaction? |
// TODO: Transaction? |
650 |
646 |
|
|
|
647 |
|
$ri = rg_repo_info($db, $repo_id, 0, ""); |
|
648 |
|
if ($ri['ok'] != 1) |
|
649 |
|
break; |
|
650 |
|
if ($ri['exists'] != 1) { |
|
651 |
|
rg_repo_set_error("Repository does not exists."); |
|
652 |
|
break; |
|
653 |
|
} |
|
654 |
|
|
651 |
655 |
// Only mark it as such, deletion will happen in background |
// Only mark it as such, deletion will happen in background |
652 |
|
$sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $repo_id"; |
|
653 |
|
$res = rg_sql_query($db, $sql); |
|
|
656 |
|
$params = array($repo_id); |
|
657 |
|
$sql = "UPDATE repos SET deleted = 1 WHERE repo_id = $1"; |
|
658 |
|
$res = rg_sql_query_params($db, $sql, $params); |
654 |
659 |
if ($res === FALSE) { |
if ($res === FALSE) { |
655 |
660 |
rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")"); |
rg_repo_set_error("Cannot delete (" . rg_sql_error() . ")"); |
656 |
661 |
break; |
break; |
|
... |
... |
function rg_repo_delete($db, $repo_id, $ui) |
660 |
665 |
$event = array("category" => 3001, "prio" => 50, |
$event = array("category" => 3001, "prio" => 50, |
661 |
666 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
662 |
667 |
"ui.email" => $ui['email'], |
"ui.email" => $ui['email'], |
663 |
|
"ri.name" => $name, |
|
|
668 |
|
"ri.name" => $ri['name'], |
664 |
669 |
"ri.repo_id" => $repo_id); |
"ri.repo_id" => $repo_id); |
665 |
670 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
666 |
671 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
|
... |
... |
function rg_repo_delete($db, $repo_id, $ui) |
681 |
686 |
*/ |
*/ |
682 |
687 |
function rg_repo_lookup_by_old_name($db, $uid, $old_name) |
function rg_repo_lookup_by_old_name($db, $uid, $old_name) |
683 |
688 |
{ |
{ |
684 |
|
rg_prof_start("rg_repo_lookup_by_old_name"); |
|
|
689 |
|
rg_prof_start("repo_lookup_by_old_name"); |
685 |
690 |
rg_log("repo_lookup_by_old_name: uid=$uid old_name=$old_name"); |
rg_log("repo_lookup_by_old_name: uid=$uid old_name=$old_name"); |
686 |
691 |
|
|
687 |
692 |
$ret = FALSE; |
$ret = FALSE; |
688 |
693 |
do { |
do { |
689 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
|
694 |
|
$params = array($uid, $old_name); |
690 |
695 |
$sql = "SELECT repo_id FROM repos_renames" |
$sql = "SELECT repo_id FROM repos_renames" |
691 |
|
. " WHERE uid = " . $uid |
|
692 |
|
. " AND old_name = '$e_old_name'"; |
|
693 |
|
$res = rg_sql_query($db, $sql); |
|
|
696 |
|
. " WHERE uid = $1" |
|
697 |
|
. " AND old_name = $2"; |
|
698 |
|
$res = rg_sql_query_params($db, $sql, $params); |
694 |
699 |
if ($res === FALSE) { |
if ($res === FALSE) { |
695 |
700 |
rg_repo_set_error("cannot lookup old name (" |
rg_repo_set_error("cannot lookup old name (" |
696 |
701 |
. rg_sql_error() . ")"); |
. rg_sql_error() . ")"); |
|
... |
... |
function rg_repo_lookup_by_old_name($db, $uid, $old_name) |
706 |
711 |
$ret = $row['repo_id']; |
$ret = $row['repo_id']; |
707 |
712 |
} while (0); |
} while (0); |
708 |
713 |
|
|
709 |
|
rg_prof_end("rg_repo_lookup_by_old_name"); |
|
|
714 |
|
rg_prof_end("repo_lookup_by_old_name"); |
710 |
715 |
return $ret; |
return $ret; |
711 |
716 |
} |
} |
712 |
717 |
|
|
|
... |
... |
function rg_repo_insert_rename($db, $uid, $repo_id, $old_name) |
720 |
725 |
|
|
721 |
726 |
$ret = FALSE; |
$ret = FALSE; |
722 |
727 |
do { |
do { |
723 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
724 |
|
|
|
725 |
728 |
// Check if already exists in the database |
// Check if already exists in the database |
726 |
729 |
$r = rg_repo_lookup_by_old_name($db, $uid, $old_name); |
$r = rg_repo_lookup_by_old_name($db, $uid, $old_name); |
727 |
730 |
if ($r === FALSE) |
if ($r === FALSE) |
728 |
731 |
break; |
break; |
729 |
732 |
if ($r > 0) { |
if ($r > 0) { |
|
733 |
|
$params = array($repo_id, $uid, $old_name); |
730 |
734 |
$sql = "UPDATE repos_renames" |
$sql = "UPDATE repos_renames" |
731 |
|
. " SET repo_id = $repo_id" |
|
732 |
|
. " WHERE uid = " . $uid |
|
733 |
|
. " AND old_name = '$e_old_name'"; |
|
|
735 |
|
. " SET repo_id = $1" |
|
736 |
|
. " WHERE uid = $2" |
|
737 |
|
. " AND old_name = $3"; |
734 |
738 |
} else { |
} else { |
735 |
739 |
$now = time(); |
$now = time(); |
|
740 |
|
$params = array($uid, $old_name, $repo_id, $now); |
736 |
741 |
$sql = "INSERT INTO repos_renames (uid, old_name" |
$sql = "INSERT INTO repos_renames (uid, old_name" |
737 |
742 |
. ", repo_id, itime)" |
. ", repo_id, itime)" |
738 |
|
. " VALUES (" . $uid |
|
739 |
|
. ", '$e_old_name'" |
|
740 |
|
. ", " . $repo_id |
|
741 |
|
. ", $now" |
|
742 |
|
. ")"; |
|
|
743 |
|
. " VALUES ($1, $2, $3, $4)"; |
743 |
744 |
} |
} |
744 |
|
$res = rg_sql_query($db, $sql); |
|
|
745 |
|
$res = rg_sql_query_params($db, $sql, $params); |
745 |
746 |
if ($res === FALSE) { |
if ($res === FALSE) { |
746 |
747 |
rg_repo_set_error("cannot link with old_name in db" |
rg_repo_set_error("cannot link with old_name in db" |
747 |
748 |
. " (" . rg_sql_error() . ")"); |
. " (" . rg_sql_error() . ")"); |
|
... |
... |
function rg_repo_update($db, $login_ui, &$new) |
802 |
803 |
break; |
break; |
803 |
804 |
} |
} |
804 |
805 |
|
|
805 |
|
$e_name = rg_sql_escape($db, $new['name']); |
|
806 |
|
$new['description'] = trim($new['description']); |
|
807 |
|
$e_description = rg_sql_escape($db, $new['description']); |
|
808 |
|
|
|
809 |
|
$sql = "UPDATE repos SET name = '$e_name'" |
|
810 |
|
. ", max_commit_size = " . $new['max_commit_size'] |
|
811 |
|
. ", description = '$e_description'" |
|
812 |
|
. ", default_rights = '" . $new['default_rights'] . "'" |
|
813 |
|
. ", max_users = " . $new['max_users'] |
|
814 |
|
. " WHERE repo_id = " . $new['repo_id']; |
|
815 |
|
$res = rg_sql_query($db, $sql); |
|
|
806 |
|
$params = array($new['name'], $new['max_commit_size'], |
|
807 |
|
trim($new['description']), $new['default_rights'], |
|
808 |
|
$new['max_users'], $new['repo_id']); |
|
809 |
|
$sql = "UPDATE repos SET name = $1" |
|
810 |
|
. ", max_commit_size = $2" |
|
811 |
|
. ", description = $3" |
|
812 |
|
. ", default_rights = $4" |
|
813 |
|
. ", max_users = $5" |
|
814 |
|
. " WHERE repo_id = $6"; |
|
815 |
|
$res = rg_sql_query_params($db, $sql, $params); |
816 |
816 |
if ($res === FALSE) { |
if ($res === FALSE) { |
817 |
817 |
rg_repo_set_error("Cannot update (" . rg_sql_error() . ")"); |
rg_repo_set_error("Cannot update (" . rg_sql_error() . ")"); |
818 |
818 |
break; |
break; |
|
... |
... |
function rg_repo_update($db, $login_ui, &$new) |
846 |
846 |
/* |
/* |
847 |
847 |
* List repositories |
* List repositories |
848 |
848 |
*/ |
*/ |
849 |
|
function rg_repo_list_query($db, $url, $sql) |
|
|
849 |
|
function rg_repo_list_query($db, $url, $sql, $params) |
850 |
850 |
{ |
{ |
851 |
851 |
rg_prof_start("repo_list_query"); |
rg_prof_start("repo_list_query"); |
852 |
852 |
rg_log("repo_list_query: url=$url, sql=$sql..."); |
rg_log("repo_list_query: url=$url, sql=$sql..."); |
853 |
853 |
|
|
854 |
|
$res = rg_sql_query($db, $sql); |
|
|
854 |
|
$res = rg_sql_query_params($db, $sql, $params); |
855 |
855 |
if ($res === FALSE) { |
if ($res === FALSE) { |
856 |
856 |
rg_repo_set_error("cannot list by query (" . rg_sql_error() . ")"); |
rg_repo_set_error("cannot list by query (" . rg_sql_error() . ")"); |
857 |
857 |
return FALSE; |
return FALSE; |
|
... |
... |
function rg_repo_list_query($db, $url, $sql) |
888 |
888 |
// rights |
// rights |
889 |
889 |
$_line['rights'] = implode(", ", rg_rights_text("repo", $row['default_rights'])); |
$_line['rights'] = implode(", ", rg_rights_text("repo", $row['default_rights'])); |
890 |
890 |
|
|
891 |
|
$_max = "unlimited"; |
|
892 |
|
if ($row['disk_quota_mb'] > 0) |
|
893 |
|
$_max = rg_1024($row['disk_quota_mb'] * 1024 * 1024); |
|
894 |
|
$_line['disk_used'] = $row['disk_used_mb'] . "/" . $_max; |
|
895 |
|
|
|
896 |
|
$_line['max_commit_size'] = "unlimited"; |
|
897 |
|
if ($row['max_commit_size'] > 0) |
|
898 |
|
$_line['max_commit_size'] = rg_1024($row['max_commit_size']); |
|
899 |
|
|
|
900 |
|
$_line['max_users'] = "unlimited"; |
|
901 |
|
if ($row['max_users'] > 0) |
|
902 |
|
$_line['max_users'] = $row['max_users']; |
|
|
891 |
|
$_line['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024); |
903 |
892 |
|
|
904 |
893 |
$d[] = $_line; |
$d[] = $_line; |
905 |
894 |
} |
} |
|
... |
... |
function rg_repo_list($db, $url, $ui) |
918 |
907 |
|
|
919 |
908 |
$add = ""; |
$add = ""; |
920 |
909 |
if ($ui['uid'] > 0) |
if ($ui['uid'] > 0) |
921 |
|
$add = " AND uid = " . $ui['uid']; |
|
|
910 |
|
$add = " AND uid = $1"; |
922 |
911 |
|
|
|
912 |
|
$params = array($ui['uid']); |
923 |
913 |
$sql = "SELECT * FROM repos" |
$sql = "SELECT * FROM repos" |
924 |
914 |
. " WHERE deleted = 0" |
. " WHERE deleted = 0" |
925 |
915 |
. $add |
. $add |
926 |
916 |
. " ORDER BY name"; |
. " ORDER BY name"; |
927 |
917 |
|
|
928 |
|
return rg_repo_list_query($db, $url, $sql); |
|
|
918 |
|
return rg_repo_list_query($db, $url, $sql, $params); |
929 |
919 |
} |
} |
930 |
920 |
|
|
931 |
921 |
/* |
/* |
|
... |
... |
function rg_repo_search($db, $login_ui, $q) |
937 |
927 |
rg_prof_start("repo_search"); |
rg_prof_start("repo_search"); |
938 |
928 |
rg_log("repo_search: q=[$q]"); |
rg_log("repo_search: q=[$q]"); |
939 |
929 |
|
|
940 |
|
$e_q = rg_sql_escape($db, $q); |
|
941 |
|
|
|
942 |
930 |
$admin = 0; |
$admin = 0; |
943 |
931 |
if (isset($login_ui['admin']) && ($login_ui['admin'] == 1)) |
if (isset($login_ui['admin']) && ($login_ui['admin'] == 1)) |
944 |
932 |
$admin = 1; |
$admin = 1; |
945 |
933 |
|
|
|
934 |
|
$params = array($q, $login_ui['uid']); |
946 |
935 |
$sql = "SELECT * FROM repos" |
$sql = "SELECT * FROM repos" |
947 |
936 |
. " WHERE deleted = 0" |
. " WHERE deleted = 0" |
948 |
|
. " AND (name ILIKE '%$e_q%' OR description ILIKE '%$e_q%')" |
|
949 |
|
. " AND (uid = " . $login_ui['uid'] . " OR default_rights LIKE '%F%'" |
|
|
937 |
|
. " AND (name ILIKE '%$1%' OR description ILIKE '%$1%')" |
|
938 |
|
. " AND (uid = $2 OR default_rights LIKE '%F%'" |
950 |
939 |
. " OR " . $admin . " = 1)" |
. " OR " . $admin . " = 1)" |
951 |
940 |
. " ORDER BY master, name" |
. " ORDER BY master, name" |
952 |
941 |
. " LIMIT 10"; |
. " LIMIT 10"; |
953 |
942 |
|
|
954 |
|
$r = rg_repo_list_query($db, "", $sql); |
|
|
943 |
|
$r = rg_repo_list_query($db, "", $sql, $params); |
955 |
944 |
|
|
956 |
945 |
rg_prof_end("repo_search"); |
rg_prof_end("repo_search"); |
957 |
946 |
return $r; |
return $r; |
|
... |
... |
function rg_repo_search($db, $login_ui, $q) |
959 |
948 |
|
|
960 |
949 |
/* |
/* |
961 |
950 |
* Computes the size of a repository |
* Computes the size of a repository |
|
951 |
|
* @all - if TRUE, take in account all files. If FALSE, ignore the files with |
|
952 |
|
* many links (a clone). |
962 |
953 |
*/ |
*/ |
963 |
|
function rg_repo_disk_mb($path) |
|
|
954 |
|
function rg_repo_size($path, $all) |
964 |
955 |
{ |
{ |
965 |
|
rg_log("repo_disk_mb: path=$path..."); |
|
|
956 |
|
//rg_log("repo_disk_mb: path=$path"); |
966 |
957 |
|
|
967 |
|
// TODO |
|
|
958 |
|
$ret = FALSE; |
|
959 |
|
do { |
|
960 |
|
$dir = @opendir($path); |
|
961 |
|
if ($dir === FALSE) { |
|
962 |
|
rg_repo_set_error("Cannot open $path!"); |
|
963 |
|
break; |
|
964 |
|
} |
|
965 |
|
|
|
966 |
|
$total = 0; |
|
967 |
|
$error = FALSE; |
|
968 |
|
while (($f = readdir($dir)) !== FALSE) { |
|
969 |
|
if (strcmp($f, ".") == 0) |
|
970 |
|
continue; |
|
971 |
|
|
|
972 |
|
if (strcmp($f, "..") == 0) |
|
973 |
|
continue; |
|
974 |
|
|
|
975 |
|
if (is_dir($path . "/" . $f)) { |
|
976 |
|
$r = rg_repo_size($path . "/" . $f, $all); |
|
977 |
|
if ($r === FALSE) { |
|
978 |
|
$error = TRUE; |
|
979 |
|
break; |
|
980 |
|
} |
|
981 |
|
$total += $r; |
|
982 |
|
} |
|
983 |
|
|
|
984 |
|
if (is_file($path . "/" . $f)) { |
|
985 |
|
$s = stat($path . "/" . $f); |
|
986 |
|
if ($s === FALSE) { |
|
987 |
|
$error = TRUE; |
|
988 |
|
break; |
|
989 |
|
} |
|
990 |
|
|
|
991 |
|
$r = $s['size']; |
|
992 |
|
if ($all === FALSE) { |
|
993 |
|
if ($s['nlink'] > 1) |
|
994 |
|
$r = 0; |
|
995 |
|
} |
|
996 |
|
|
|
997 |
|
$total += $r; |
|
998 |
|
} |
|
999 |
|
} |
|
1000 |
|
closedir($dir); |
|
1001 |
|
|
|
1002 |
|
if ($error === FALSE) |
|
1003 |
|
$ret = $total; |
|
1004 |
|
} while (0); |
968 |
1005 |
|
|
969 |
|
return 10; |
|
|
1006 |
|
return $ret; |
970 |
1007 |
} |
} |
971 |
1008 |
|
|
972 |
1009 |
/* |
/* |
|
... |
... |
function rg_repo_git_done($db, $repo_id) |
979 |
1016 |
|
|
980 |
1017 |
$ret = FALSE; |
$ret = FALSE; |
981 |
1018 |
do { |
do { |
|
1019 |
|
$params = array($repo_id); |
982 |
1020 |
$sql = "UPDATE repos SET git_dir_done = 1" |
$sql = "UPDATE repos SET git_dir_done = 1" |
983 |
|
. " WHERE repo_id = $repo_id"; |
|
984 |
|
$res = rg_sql_query($db, $sql); |
|
|
1021 |
|
. " WHERE repo_id = $1"; |
|
1022 |
|
$res = rg_sql_query_params($db, $sql, $params); |
985 |
1023 |
if ($res === FALSE) { |
if ($res === FALSE) { |
986 |
1024 |
rg_repo_set_error("Cannot query (" . rg_sql_error() . ")"); |
rg_repo_set_error("Cannot query (" . rg_sql_error() . ")"); |
987 |
1025 |
break; |
break; |
|
... |
... |
function rg_repo_rights_get($db, $ri, $uid, $flags) |
1038 |
1076 |
. $r['rights'] . ")=" . $ret['rights']); |
. $r['rights'] . ")=" . $ret['rights']); |
1039 |
1077 |
$ret['ok'] = 1; |
$ret['ok'] = 1; |
1040 |
1078 |
|
|
|
1079 |
|
// add misc stuff |
|
1080 |
|
$ret = array_merge($ret, $r['misc']); |
|
1081 |
|
|
1041 |
1082 |
rg_prof_end("repo_rights_get"); |
rg_prof_end("repo_rights_get"); |
1042 |
1083 |
|
|
1043 |
1084 |
return $ret; |
return $ret; |
|
... |
... |
function rg_repo_rights_get($db, $ri, $uid, $flags) |
1046 |
1087 |
/* |
/* |
1047 |
1088 |
* Add rights for a repo |
* Add rights for a repo |
1048 |
1089 |
*/ |
*/ |
1049 |
|
function rg_repo_rights_set($db, $ri, $uid, $rights) |
|
|
1090 |
|
function rg_repo_rights_set($db, $ri, $uid, $rights, $misc) |
1050 |
1091 |
{ |
{ |
1051 |
1092 |
if (!isset($ri['repo_id'])) { |
if (!isset($ri['repo_id'])) { |
1052 |
1093 |
rg_internal_error("repo_id is not defined!"); |
rg_internal_error("repo_id is not defined!"); |
|
... |
... |
function rg_repo_rights_set($db, $ri, $uid, $rights) |
1054 |
1095 |
} |
} |
1055 |
1096 |
|
|
1056 |
1097 |
rg_log("rg_repo_rights_set: repo_id=" . $ri['repo_id'] |
rg_log("rg_repo_rights_set: repo_id=" . $ri['repo_id'] |
1057 |
|
. ", uid=$uid, rights=$rights..."); |
|
|
1098 |
|
. " uid=$uid rights=$rights misc=" . rg_array2string($misc)); |
1058 |
1099 |
|
|
1059 |
|
$r = rg_rights_set($db, "repo", $ri['repo_id'], $uid, $rights); |
|
|
1100 |
|
$r = rg_rights_set($db, "repo", $ri['repo_id'], $uid, $rights, $misc); |
1060 |
1101 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
1061 |
1102 |
rg_repo_set_error("cannot alter rights (" . rg_rights_error() . ")!"); |
rg_repo_set_error("cannot alter rights (" . rg_rights_error() . ")!"); |
1062 |
1103 |
return FALSE; |
return FALSE; |
|
... |
... |
function rg_repo_rights_load($db, $ri) |
1081 |
1122 |
return $r; |
return $r; |
1082 |
1123 |
} |
} |
1083 |
1124 |
|
|
1084 |
|
/* |
|
1085 |
|
* Returns TRUE if a repo is over limit |
|
1086 |
|
*/ |
|
1087 |
|
function rg_repo_over_limit($ri) |
|
1088 |
|
{ |
|
1089 |
|
if ($ri['disk_quota_mb'] == 0) |
|
1090 |
|
return FALSE; |
|
1091 |
|
|
|
1092 |
|
if ($ri['disk_used_mb'] >= $ri['disk_quota_mb']) |
|
1093 |
|
return TRUE; |
|
1094 |
|
|
|
1095 |
|
return FALSE; |
|
1096 |
|
} |
|
1097 |
|
|
|
1098 |
1125 |
/* |
/* |
1099 |
1126 |
* Add in queue a statistic file |
* Add in queue a statistic file |
1100 |
1127 |
*/ |
*/ |
|
... |
... |
function rg_repo_stats_push2file($a) |
1106 |
1133 |
if (!is_dir($q)) { |
if (!is_dir($q)) { |
1107 |
1134 |
$r = @mkdir($q, 0700); |
$r = @mkdir($q, 0700); |
1108 |
1135 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
1109 |
|
rg_internal_error("Cannot create dir $q ($php_errormsg)!"); |
|
|
1136 |
|
rg_internal_error("Cannot create dir [$q] ($php_errormsg)!"); |
1110 |
1137 |
return FALSE; |
return FALSE; |
1111 |
1138 |
} |
} |
1112 |
1139 |
} |
} |
File inc/user.inc.php changed (mode: 100644) (index e9616f4..ffb18bf) |
... |
... |
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 |
7 |
require_once($INC . "/events.inc.php"); |
require_once($INC . "/events.inc.php"); |
|
8 |
|
require_once($INC . "/cache.inc.php"); |
|
9 |
|
require_once($INC . "/plan.inc.php"); |
8 |
10 |
|
|
9 |
11 |
$rg_user_rights = array( |
$rg_user_rights = array( |
10 |
12 |
"C" => "Create repositories", |
"C" => "Create repositories", |
11 |
|
"U" => "Add users" |
|
|
13 |
|
"U" => "Add/edit users", |
|
14 |
|
"S" => "Suspend accounts", |
|
15 |
|
"A" => "Up/downgrade to admin level", |
|
16 |
|
"R" => "Remove account" |
12 |
17 |
); |
); |
13 |
18 |
|
|
14 |
19 |
rg_rights_register("user", $rg_user_rights); |
rg_rights_register("user", $rg_user_rights); |
|
... |
... |
function rg_user_link_by_name($db, $event) |
96 |
101 |
{ |
{ |
97 |
102 |
rg_log("user_link_by_name: event=" . rg_array2string($event)); |
rg_log("user_link_by_name: event=" . rg_array2string($event)); |
98 |
103 |
|
|
99 |
|
$by_id = rg_user_path_by_id($event['uid']); |
|
|
104 |
|
$by_id = rg_user_path_by_id($event['ui.uid']); |
100 |
105 |
if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) { |
if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) { |
101 |
106 |
rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); |
rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); |
102 |
107 |
return FALSE; |
return FALSE; |
103 |
108 |
} |
} |
104 |
109 |
|
|
105 |
|
$by_name = rg_user_path_by_name($event['username']); |
|
|
110 |
|
$by_name = rg_user_path_by_name($event['ui.username']); |
106 |
111 |
$by_name_parent = dirname($by_name); |
$by_name_parent = dirname($by_name); |
107 |
112 |
if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) { |
if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) { |
108 |
113 |
rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); |
rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); |
109 |
114 |
return FALSE; |
return FALSE; |
110 |
115 |
} |
} |
111 |
116 |
|
|
112 |
|
$by_id_rel = rg_user_path_by_id_rel($event['uid']); |
|
|
117 |
|
$by_id_rel = rg_user_path_by_id_rel($event['ui.uid']); |
113 |
118 |
if (symlink($by_id_rel, $by_name) === FALSE) { |
if (symlink($by_id_rel, $by_name) === FALSE) { |
114 |
119 |
rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!"); |
rg_user_set_error("cannot symlink $by_id_rel <- $by_name ($php_errormsg)!"); |
115 |
120 |
return FALSE; |
return FALSE; |
|
... |
... |
function rg_user_ok($user) |
226 |
231 |
*/ |
*/ |
227 |
232 |
function rg_user_lookup_by_old_name($db, $old_name) |
function rg_user_lookup_by_old_name($db, $old_name) |
228 |
233 |
{ |
{ |
229 |
|
rg_prof_start("rg_user_lookup_by_old_name"); |
|
|
234 |
|
rg_prof_start("user_lookup_by_old_name"); |
230 |
235 |
rg_log("user_lookup_by_old_name: old_name=$old_name"); |
rg_log("user_lookup_by_old_name: old_name=$old_name"); |
231 |
236 |
|
|
232 |
237 |
$ret = FALSE; |
$ret = FALSE; |
233 |
238 |
do { |
do { |
234 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
|
239 |
|
$x = rg_cache_get("old_name::" . $old_name); |
|
240 |
|
if ($x !== FALSE) { |
|
241 |
|
$ret = $x; |
|
242 |
|
break; |
|
243 |
|
} |
|
244 |
|
|
|
245 |
|
$params = array($old_name); |
235 |
246 |
$sql = "SELECT uid FROM users_renames" |
$sql = "SELECT uid FROM users_renames" |
236 |
|
. " WHERE old_name = '$e_old_name'"; |
|
237 |
|
$res = rg_sql_query($db, $sql); |
|
|
247 |
|
. " WHERE old_name = $1"; |
|
248 |
|
$res = rg_sql_query_params($db, $sql, $params); |
238 |
249 |
if ($res === FALSE) { |
if ($res === FALSE) { |
239 |
250 |
rg_user_set_error("cannot lookup old name (" |
rg_user_set_error("cannot lookup old name (" |
240 |
251 |
. rg_sql_error() . ")"); |
. rg_sql_error() . ")"); |
|
... |
... |
function rg_user_lookup_by_old_name($db, $old_name) |
248 |
259 |
$ret = 0; |
$ret = 0; |
249 |
260 |
else |
else |
250 |
261 |
$ret = $row['uid']; |
$ret = $row['uid']; |
|
262 |
|
|
|
263 |
|
rg_cache_set("old_name::" . $old_name, $ret); |
251 |
264 |
} while (0); |
} while (0); |
252 |
265 |
|
|
253 |
|
rg_prof_end("rg_user_lookup_by_old_name"); |
|
|
266 |
|
rg_prof_end("user_lookup_by_old_name"); |
254 |
267 |
return $ret; |
return $ret; |
255 |
268 |
} |
} |
256 |
269 |
|
|
|
... |
... |
function rg_user_insert_rename($db, $uid, $old_name) |
264 |
277 |
|
|
265 |
278 |
$ret = FALSE; |
$ret = FALSE; |
266 |
279 |
do { |
do { |
267 |
|
$e_old_name = rg_sql_escape($db, $old_name); |
|
268 |
|
|
|
269 |
280 |
// Check if already exists in the database |
// Check if already exists in the database |
270 |
281 |
$r = rg_user_lookup_by_old_name($db, $old_name); |
$r = rg_user_lookup_by_old_name($db, $old_name); |
271 |
282 |
if ($r === FALSE) |
if ($r === FALSE) |
272 |
283 |
break; |
break; |
273 |
284 |
if ($r > 0) { |
if ($r > 0) { |
|
285 |
|
$params = array($uid, $old_name); |
274 |
286 |
$sql = "UPDATE users_renames" |
$sql = "UPDATE users_renames" |
275 |
|
. " SET uid = $uid" |
|
276 |
|
. " WHERE old_name = '$e_old_name'"; |
|
|
287 |
|
. " SET uid = $1" |
|
288 |
|
. " WHERE old_name = $2"; |
277 |
289 |
} else { |
} else { |
278 |
|
$now = time(); |
|
|
290 |
|
$params = array($uid, $old_name, time()); |
279 |
291 |
$sql = "INSERT INTO users_renames (uid, old_name" |
$sql = "INSERT INTO users_renames (uid, old_name" |
280 |
292 |
. ", itime)" |
. ", itime)" |
281 |
|
. " VALUES (" . $uid |
|
282 |
|
. ", '$e_old_name'" |
|
283 |
|
. ", $now" |
|
284 |
|
. ")"; |
|
|
293 |
|
. " VALUES ($1, $2, $3)"; |
285 |
294 |
} |
} |
286 |
|
$res = rg_sql_query($db, $sql); |
|
|
295 |
|
$res = rg_sql_query_params($db, $sql, $params); |
287 |
296 |
if ($res === FALSE) { |
if ($res === FALSE) { |
288 |
297 |
rg_user_set_error("cannot link with old_name in db" |
rg_user_set_error("cannot link with old_name in db" |
289 |
298 |
. " (" . rg_sql_error() . ")"); |
. " (" . rg_sql_error() . ")"); |
290 |
299 |
break; |
break; |
291 |
300 |
} |
} |
292 |
301 |
|
|
|
302 |
|
rg_cache_set("old_name::" . $old_name, $uid); |
|
303 |
|
|
293 |
304 |
$ret = TRUE; |
$ret = TRUE; |
294 |
305 |
} while (0); |
} while (0); |
295 |
306 |
|
|
|
... |
... |
function rg_user_rename($db, $ui, $new_name) |
383 |
394 |
*/ |
*/ |
384 |
395 |
function rg_user_edit($db, $d) |
function rg_user_edit($db, $d) |
385 |
396 |
{ |
{ |
386 |
|
global $rg_user_info_cache; // TODO: what we do with this? |
|
|
397 |
|
global $rg_account_email_confirm; |
387 |
398 |
|
|
388 |
399 |
rg_prof_start("user_edit"); |
rg_prof_start("user_edit"); |
389 |
|
rg_log("user_edit: data: " . rg_array2string($d)); |
|
|
400 |
|
rg_log("user_edit: d: " . rg_array2string($d)); |
390 |
401 |
|
|
391 |
402 |
$ret = FALSE; |
$ret = FALSE; |
392 |
403 |
do { |
do { |
393 |
|
// DEBUG |
|
394 |
|
if (!isset($d['username'])) { |
|
395 |
|
rg_internal_error("username not passed"); |
|
396 |
|
break; |
|
397 |
|
} |
|
398 |
|
|
|
399 |
404 |
if (rg_user_ok($d['username']) !== TRUE) |
if (rg_user_ok($d['username']) !== TRUE) |
400 |
405 |
break; |
break; |
401 |
406 |
|
|
402 |
|
$now = time(); |
|
403 |
|
$e_username = rg_sql_escape($db, $d['username']); |
|
404 |
|
$e_realname = rg_sql_escape($db, $d['realname']); |
|
405 |
|
$e_salt = rg_id(40); |
|
406 |
|
$e_pass = rg_user_pass($e_salt, $d['pass']); |
|
407 |
|
$e_email = rg_sql_escape($db, $d['email']); |
|
408 |
|
$e_rights = rg_sql_escape($db, $d['rights']); |
|
409 |
|
$e_is_admin = $d['is_admin']; |
|
410 |
|
$e_disk_quota_mb = $d['disk_quota_mb']; |
|
411 |
|
$e_session_time = $d['session_time']; |
|
412 |
|
$e_confirm_token = isset($d['confirm_token']) ? $d['confirm_token'] : ""; |
|
413 |
|
|
|
414 |
|
if (empty($d['confirm_token'])) { |
|
|
407 |
|
// TODO: check rights |
|
408 |
|
// TODO - check if user is allowed to give passed rights |
|
409 |
|
|
|
410 |
|
if ($rg_account_email_confirm == 0) { |
415 |
411 |
// no need to confirm account |
// no need to confirm account |
416 |
|
$e_confirmed = $now; |
|
|
412 |
|
$confirmed = 1; // signals "no-need-to-confirm" |
417 |
413 |
} else { |
} else { |
418 |
|
$e_confirmed = 0; |
|
|
414 |
|
$confirmed = 0; |
|
415 |
|
} |
|
416 |
|
|
|
417 |
|
if (!empty($d['pass'])) { |
|
418 |
|
if (strcmp($d['pass'], $d['pass2']) != 0) { |
|
419 |
|
rg_user_set_error("passwords are not the same"); |
|
420 |
|
break; |
|
421 |
|
} |
419 |
422 |
} |
} |
420 |
423 |
|
|
|
424 |
|
$now = time(); |
|
425 |
|
$d['salt'] = rg_id(40); |
|
426 |
|
$d['pass_crypted'] = rg_user_pass($d['salt'], $d['pass']); |
|
427 |
|
|
421 |
428 |
if ($d['uid'] == 0) { // add |
if ($d['uid'] == 0) { // add |
422 |
429 |
if (rg_user_pass_ok($d['pass']) !== TRUE) |
if (rg_user_pass_ok($d['pass']) !== TRUE) |
423 |
430 |
break; |
break; |
424 |
431 |
|
|
|
432 |
|
$params = array($d['username'], $d['realname'], $d['salt'], |
|
433 |
|
$d['pass_crypted'], $d['email'], $now, $d['is_admin'], |
|
434 |
|
$d['rights'], $d['session_time'], $confirmed, |
|
435 |
|
$d['confirm_token'], $d['plan_id']); |
425 |
436 |
$sql = "INSERT INTO users (username, realname, salt, pass" |
$sql = "INSERT INTO users (username, realname, salt, pass" |
426 |
437 |
. ", email, itime" |
. ", email, itime" |
427 |
|
. ", is_admin, disk_quota_mb, rights, session_time" |
|
428 |
|
. ", confirmed, confirm_token)" |
|
429 |
|
. " VALUES ('$e_username', '$e_realname', '$e_salt', '$e_pass'" |
|
430 |
|
. ", '$e_email', $now, $e_is_admin, $e_disk_quota_mb" |
|
431 |
|
. ", '$e_rights', $e_session_time" |
|
432 |
|
. ", $e_confirmed, '$e_confirm_token')" |
|
|
438 |
|
. ", is_admin, rights, session_time" |
|
439 |
|
. ", confirmed, confirm_token, plan_id)" |
|
440 |
|
. " VALUES ($1, $2, $3, $4, $5, $6, $7" |
|
441 |
|
. ", $8, $9, $10, $11, $12)" |
433 |
442 |
. " RETURNING uid"; |
. " RETURNING uid"; |
434 |
443 |
} else { // edit |
} else { // edit |
|
444 |
|
$params = array($d['username'], $d['realname'], |
|
445 |
|
$d['email'], $d['is_admin'], $d['rights'], |
|
446 |
|
$d['session_time'], $d['uid']); |
|
447 |
|
|
435 |
448 |
$salt_pass_add = ""; |
$salt_pass_add = ""; |
436 |
|
if (!empty($d['pass'])) |
|
437 |
|
$salt_pass_add = ", pass = '$e_pass', salt = '$e_salt'"; |
|
|
449 |
|
if (!empty($d['pass'])) { |
|
450 |
|
$params[] = $d['pass_crypted']; |
|
451 |
|
$params[] = $d['salt']; |
|
452 |
|
$salt_pass_add = ", pass = $8, salt = $9"; |
|
453 |
|
} |
438 |
454 |
|
|
439 |
455 |
$sql = "UPDATE users" |
$sql = "UPDATE users" |
440 |
|
. " SET username = '$e_username'" |
|
441 |
|
. ", realname = '$e_realname'" |
|
|
456 |
|
. " SET username = $1" |
|
457 |
|
. ", realname = $2" |
|
458 |
|
. ", email = $3" |
|
459 |
|
. ", is_admin = $4" |
|
460 |
|
. ", rights = $5" |
|
461 |
|
. ", session_time = $6" |
442 |
462 |
. $salt_pass_add |
. $salt_pass_add |
443 |
|
. ", email = '$e_email'" |
|
444 |
|
. ", is_admin = $e_is_admin" |
|
445 |
|
. ", disk_quota_mb = $e_disk_quota_mb" |
|
446 |
|
. ", rights = '$e_rights'" |
|
447 |
|
. ", session_time = $e_session_time" |
|
448 |
|
. " WHERE uid = " . $d['uid'] |
|
|
463 |
|
. " WHERE uid = $7" |
449 |
464 |
. " RETURNING uid"; |
. " RETURNING uid"; |
450 |
465 |
} |
} |
451 |
466 |
|
|
452 |
|
$res = rg_sql_query($db, $sql); |
|
|
467 |
|
$res = rg_sql_query_params($db, $sql, $params); |
453 |
468 |
if ($res === FALSE) { |
if ($res === FALSE) { |
454 |
469 |
rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); |
455 |
470 |
break; |
break; |
|
... |
... |
function rg_user_edit($db, $d) |
457 |
472 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
458 |
473 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
459 |
474 |
|
|
460 |
|
// invalidate cache |
|
461 |
|
$rg_user_info_cache = array(); |
|
|
475 |
|
// invalidate cache (because we may not have the password) |
|
476 |
|
if ($d['uid'] > 0) |
|
477 |
|
rg_cache_unset("user::" . $d['uid']); |
462 |
478 |
|
|
463 |
479 |
if ($d['uid'] == 0) { // add |
if ($d['uid'] == 0) { // add |
464 |
480 |
$event = array("category" => 2000, "prio" => 50, |
$event = array("category" => 2000, "prio" => 50, |
465 |
481 |
"ui.uid" => $d['uid'], |
"ui.uid" => $d['uid'], |
466 |
482 |
"ui.username" => $d['username'], |
"ui.username" => $d['username'], |
467 |
|
"ui.email" => $d['email'] |
|
|
483 |
|
"ui.email" => $d['email'], |
|
484 |
|
"ui.confirm_token" => $d['confirm_token'], |
|
485 |
|
"rg_account_email_confirm" => $rg_account_email_confirm, |
|
486 |
|
"url" => rg_base_url() |
468 |
487 |
); |
); |
469 |
488 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
470 |
489 |
if ($r === FALSE) { |
if ($r === FALSE) { |
|
... |
... |
function rg_user_edit($db, $d) |
485 |
504 |
*/ |
*/ |
486 |
505 |
function rg_user_remove($db, $uid) |
function rg_user_remove($db, $uid) |
487 |
506 |
{ |
{ |
488 |
|
global $rg_user_info_cache; |
|
489 |
|
|
|
490 |
507 |
rg_prof_start("user_remove"); |
rg_prof_start("user_remove"); |
491 |
508 |
rg_log("user_remove: uid=$uid"); |
rg_log("user_remove: uid=$uid"); |
492 |
509 |
|
|
493 |
510 |
$ret = FALSE; |
$ret = FALSE; |
494 |
511 |
do { |
do { |
495 |
|
$uid = sprintf("%u", $uid); |
|
|
512 |
|
$login_ui = rg_get_login_ui(); |
|
513 |
|
if (!rg_rights_allow($login_ui['rights'], "R")) |
|
514 |
|
break; |
496 |
515 |
|
|
497 |
|
$sql = "DELETE FROM users WHERE uid = $uid"; |
|
498 |
|
$res = rg_sql_query($db, $sql); |
|
|
516 |
|
$params = array($uid); |
|
517 |
|
$sql = "DELETE FROM users WHERE uid = $1"; |
|
518 |
|
$res = rg_sql_query_params($db, $sql, $params); |
499 |
519 |
if ($res === FALSE) { |
if ($res === FALSE) { |
500 |
520 |
rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot remove user $uid (" . rg_sql_error() . ")"); |
501 |
521 |
break; |
break; |
|
... |
... |
function rg_user_remove($db, $uid) |
503 |
523 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
504 |
524 |
|
|
505 |
525 |
// invalidate cache |
// invalidate cache |
506 |
|
$rg_user_info_cache = array(); |
|
|
526 |
|
rg_cache_unset("user::" . $uid); |
507 |
527 |
|
|
508 |
528 |
$ret = TRUE; |
$ret = TRUE; |
509 |
529 |
} while (0); |
} while (0); |
|
... |
... |
function rg_user_remove($db, $uid) |
515 |
535 |
/* |
/* |
516 |
536 |
* Returns info about a user (by uid, user or e-mail) |
* Returns info about a user (by uid, user or e-mail) |
517 |
537 |
*/ |
*/ |
518 |
|
$rg_user_info_cache = array(); |
|
519 |
538 |
function rg_user_info($db, $uid, $user, $email) |
function rg_user_info($db, $uid, $user, $email) |
520 |
539 |
{ |
{ |
521 |
|
global $rg_user_info_cache; |
|
522 |
|
|
|
523 |
|
$key = $uid . "__" . $user . "__" . $email; |
|
524 |
|
if (isset($rg_user_info_cache[$key])) |
|
525 |
|
return $rg_user_info_cache[$key]; |
|
526 |
|
|
|
527 |
540 |
rg_prof_start("user_info"); |
rg_prof_start("user_info"); |
528 |
|
rg_log("user_info: uid/user/email=$uid/$user/$email..."); |
|
529 |
541 |
|
|
530 |
542 |
$ret = array(); |
$ret = array(); |
531 |
543 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
532 |
544 |
$ret['exists'] = 0; |
$ret['exists'] = 0; |
533 |
545 |
$ret['uid'] = 0; |
$ret['uid'] = 0; |
534 |
546 |
$ret['is_admin'] = 0; |
$ret['is_admin'] = 0; |
|
547 |
|
$ret['rights'] = ""; |
|
548 |
|
|
|
549 |
|
$set_cache = FALSE; |
|
550 |
|
$set_cache_user = FALSE; |
|
551 |
|
$set_cache_email = FALSE; |
|
552 |
|
while (1) { |
|
553 |
|
//rg_log("user_info: uid=$uid user=$user email=$email."); |
|
554 |
|
|
|
555 |
|
if ($uid > 0) { |
|
556 |
|
$c = rg_cache_get("user::" . $uid); |
|
557 |
|
if ($c !== FALSE) { |
|
558 |
|
$ret = unserialize($c); |
|
559 |
|
if ($ret === FALSE) |
|
560 |
|
rg_log("cannot unserialize ($c)"); |
|
561 |
|
break; |
|
562 |
|
} |
535 |
563 |
|
|
536 |
|
// in case we return error |
|
537 |
|
$rg_user_info_cache[$key] = $ret; |
|
|
564 |
|
$params = array($uid); |
|
565 |
|
$sql = "SELECT * FROM users WHERE uid = $1"; |
|
566 |
|
$set_cache = TRUE; |
|
567 |
|
} else if (!empty($user)) { |
|
568 |
|
if (rg_user_ok($user) !== TRUE) |
|
569 |
|
break; |
538 |
570 |
|
|
539 |
|
if ($uid > 0) { |
|
540 |
|
$add = " AND uid = " . sprintf("%u", $uid); |
|
541 |
|
} else if (!empty($user)) { |
|
542 |
|
if (rg_user_ok($user) !== TRUE) |
|
543 |
|
return FALSE; |
|
|
571 |
|
$c = rg_cache_get("username_to_uid::" . $user); |
|
572 |
|
if ($c !== FALSE) { |
|
573 |
|
$uid = $c; |
|
574 |
|
continue; |
|
575 |
|
} |
544 |
576 |
|
|
545 |
|
$e_user = rg_sql_escape($db, $user); |
|
546 |
|
$add = " AND username = '$e_user'"; |
|
547 |
|
} else if (!empty($email)) { |
|
548 |
|
$e_email = rg_sql_escape($db, $email); |
|
549 |
|
$add = " AND email = '$e_email'"; |
|
550 |
|
} else { |
|
551 |
|
return FALSE; |
|
552 |
|
} |
|
|
577 |
|
$params = array($user); |
|
578 |
|
$sql = "SELECT * FROM users WHERE username = $1"; |
|
579 |
|
$set_cache_user = TRUE; |
|
580 |
|
} else if (!empty($email)) { |
|
581 |
|
$c = rg_cache_get("email_to_uid::" . $email); |
|
582 |
|
if ($c != FALSE) { |
|
583 |
|
$uid = $c; |
|
584 |
|
continue; |
|
585 |
|
} |
553 |
586 |
|
|
554 |
|
$sql = "SELECT * FROM users WHERE 1 = 1" . $add; |
|
555 |
|
$res = rg_sql_query($db, $sql); |
|
556 |
|
if ($res === FALSE) { |
|
557 |
|
rg_user_set_error("cannot get info (" . rg_sql_error() . ")"); |
|
558 |
|
return $ret; |
|
559 |
|
} |
|
|
587 |
|
$params = array($email); |
|
588 |
|
$sql = "SELECT * FROM users WHERE email = $1"; |
|
589 |
|
$set_cache_email = TRUE; |
|
590 |
|
} else { |
|
591 |
|
break; |
|
592 |
|
} |
560 |
593 |
|
|
561 |
|
$ret['ok'] = 1; |
|
562 |
|
$rows = rg_sql_num_rows($res); |
|
563 |
|
if ($rows > 0) |
|
564 |
|
$row = rg_sql_fetch_array($res); |
|
565 |
|
rg_sql_free_result($res); |
|
566 |
|
if ($rows == 0) { |
|
567 |
|
rg_user_set_error("user not found"); |
|
568 |
|
return $ret; |
|
569 |
|
} |
|
|
594 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
595 |
|
if ($res === FALSE) { |
|
596 |
|
rg_user_set_error("cannot get info (" . rg_sql_error() . ")"); |
|
597 |
|
break; |
|
598 |
|
} |
570 |
599 |
|
|
571 |
|
$row['ok'] = 1; |
|
572 |
|
$row['exists'] = 1; |
|
573 |
|
rg_log("\tUser found."); |
|
|
600 |
|
$ret['ok'] = 1; |
|
601 |
|
$rows = rg_sql_num_rows($res); |
|
602 |
|
if ($rows > 0) |
|
603 |
|
$row = rg_sql_fetch_array($res); |
|
604 |
|
rg_sql_free_result($res); |
|
605 |
|
if ($rows == 0) { |
|
606 |
|
rg_log("user not found"); |
|
607 |
|
rg_user_set_error("user not found"); |
|
608 |
|
break; |
|
609 |
|
} |
|
610 |
|
|
|
611 |
|
$ret = array_merge($ret, $row); |
|
612 |
|
$ret['exists'] = 1; |
|
613 |
|
break; |
|
614 |
|
}; |
|
615 |
|
|
|
616 |
|
if (($ret['ok'] == 1) && $set_cache) |
|
617 |
|
rg_cache_set("user::" . $ret['uid'], serialize($ret)); |
|
618 |
|
|
|
619 |
|
if ($ret['exists'] == 1) { |
|
620 |
|
if ($set_cache_user) |
|
621 |
|
rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']); |
574 |
622 |
|
|
575 |
|
$rg_user_info_cache[$key] = $row; |
|
|
623 |
|
if ($set_cache_email) |
|
624 |
|
rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']); |
|
625 |
|
} |
576 |
626 |
|
|
577 |
627 |
rg_prof_end("user_info"); |
rg_prof_end("user_info"); |
578 |
|
return $row; |
|
|
628 |
|
return $ret; |
579 |
629 |
} |
} |
580 |
630 |
|
|
581 |
631 |
/* |
/* |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
583 |
633 |
*/ |
*/ |
584 |
634 |
function rg_user_login_by_sid($db, $sid, &$ui) |
function rg_user_login_by_sid($db, $sid, &$ui) |
585 |
635 |
{ |
{ |
|
636 |
|
rg_prof_start("user_login_by_sid"); |
586 |
637 |
rg_log("user_login_by_sid: sid=$sid..."); |
rg_log("user_login_by_sid: sid=$sid..."); |
587 |
638 |
|
|
588 |
639 |
// Make sure it is not passed by client |
// Make sure it is not passed by client |
589 |
640 |
$ui = array(); |
$ui = array(); |
590 |
641 |
$ui['uid'] = 0; |
$ui['uid'] = 0; |
591 |
642 |
$ui['is_admin'] = 0; |
$ui['is_admin'] = 0; |
|
643 |
|
$ui['rights'] = ""; |
592 |
644 |
$ui['username'] = ""; |
$ui['username'] = ""; |
593 |
645 |
|
|
594 |
|
if (empty($sid)) { |
|
595 |
|
rg_log("\tNo sid!"); |
|
596 |
|
return FALSE; |
|
597 |
|
} |
|
|
646 |
|
$ret = FALSE; |
|
647 |
|
do { |
|
648 |
|
if (empty($sid)) { |
|
649 |
|
rg_log("\tNo sid!"); |
|
650 |
|
break; |
|
651 |
|
} |
598 |
652 |
|
|
599 |
|
$uid = rg_sess_valid($db, $sid); |
|
600 |
|
if ($uid == 0) |
|
601 |
|
return FALSE; |
|
|
653 |
|
$sess = rg_sess_valid($db, $sid); |
|
654 |
|
if ($sess == FALSE) { |
|
655 |
|
rg_log("session is not valid"); |
|
656 |
|
break; |
|
657 |
|
} |
602 |
658 |
|
|
603 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
604 |
|
if ($ui['exists'] != 1) { |
|
605 |
|
rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!"); |
|
606 |
|
rg_user_set_error("invalid uid"); |
|
607 |
|
return FALSE; |
|
608 |
|
} |
|
|
659 |
|
$uid = $sess['uid']; |
|
660 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
661 |
|
if ($ui['exists'] != 1) { |
|
662 |
|
rg_log("\tUid $uid does not exists (" . rg_user_error() . ")!"); |
|
663 |
|
rg_user_set_error("invalid uid"); |
|
664 |
|
break; |
|
665 |
|
} |
609 |
666 |
|
|
610 |
|
rg_sess_update($db, $sid); |
|
|
667 |
|
rg_sess_update($db, $sess); |
611 |
668 |
|
|
612 |
|
rg_user_set_last_seen($db, $ui['uid']); |
|
|
669 |
|
rg_user_set_last_seen($db, $ui['uid']); |
613 |
670 |
|
|
614 |
|
return TRUE; |
|
|
671 |
|
$ret = TRUE; |
|
672 |
|
} while (0); |
|
673 |
|
|
|
674 |
|
rg_prof_end("user_login_by_sid"); |
|
675 |
|
return $ret; |
615 |
676 |
} |
} |
616 |
677 |
|
|
617 |
678 |
/* |
/* |
|
... |
... |
function rg_user_pass_valid($db, $uid, $pass) |
645 |
706 |
/* |
/* |
646 |
707 |
* Auto login the user |
* Auto login the user |
647 |
708 |
*/ |
*/ |
648 |
|
function rg_user_auto_login($db, $uid, &$ui) |
|
|
709 |
|
function rg_user_auto_login($db, $uid, $lock_ip, &$ui) |
649 |
710 |
{ |
{ |
650 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
651 |
|
if ($ui['ok'] != 1) |
|
652 |
|
return FALSE; |
|
|
711 |
|
rg_prof_start("user_auto_login"); |
|
712 |
|
rg_log("user_auto_login: uid=$uid lock_ip=$lock_ip"); |
653 |
713 |
|
|
654 |
|
if ($ui['exists'] != 1) |
|
655 |
|
return FALSE; |
|
|
714 |
|
$ret = FALSE; |
|
715 |
|
do { |
|
716 |
|
$ui = rg_user_info($db, $uid, "", ""); |
|
717 |
|
if ($ui['ok'] != 1) |
|
718 |
|
break; |
656 |
719 |
|
|
657 |
|
$secure = FALSE; |
|
658 |
|
if (isset($_SERVER['HTTPS'])) |
|
659 |
|
$secure = TRUE; |
|
|
720 |
|
if ($ui['exists'] != 1) { |
|
721 |
|
rg_log("user does not exists"); |
|
722 |
|
break; |
|
723 |
|
} |
660 |
724 |
|
|
661 |
|
$sid = rg_id(40); |
|
662 |
|
rg_sess_add($db, $uid, $sid, $ui['session_time']); |
|
663 |
|
setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'], |
|
664 |
|
$secure, TRUE /* httponly */); |
|
|
725 |
|
$secure = FALSE; |
|
726 |
|
if (isset($_SERVER['HTTPS'])) |
|
727 |
|
$secure = TRUE; |
665 |
728 |
|
|
666 |
|
return TRUE; |
|
|
729 |
|
$sid = rg_id(40); |
|
730 |
|
rg_sess_add($db, $uid, $sid, $ui['session_time'], $lock_ip); |
|
731 |
|
setcookie("sid", $sid, 0, "/", $_SERVER['SERVER_NAME'], |
|
732 |
|
$secure, TRUE /* httponly */); |
|
733 |
|
|
|
734 |
|
$ret = TRUE; |
|
735 |
|
} while (0); |
|
736 |
|
|
|
737 |
|
rg_prof_end("user_auto_login"); |
|
738 |
|
return $ret; |
667 |
739 |
} |
} |
668 |
740 |
|
|
669 |
741 |
/* |
/* |
670 |
742 |
* Test if login is OK |
* Test if login is OK |
671 |
743 |
*/ |
*/ |
672 |
|
function rg_user_login_by_user_pass($db, $user, $pass, &$ui) |
|
|
744 |
|
function rg_user_login_by_user_pass($db, $user, $pass, $lock_ip, &$ui) |
673 |
745 |
{ |
{ |
674 |
|
rg_log("user_login_by_user_pass: user=$user, pass=$pass..."); |
|
|
746 |
|
rg_log("user_login_by_user_pass: user=$user, pass=$pass lock_ip=$lock_ip"); |
675 |
747 |
|
|
676 |
748 |
$ui = array(); |
$ui = array(); |
677 |
749 |
$ui['uid'] = 0; |
$ui['uid'] = 0; |
678 |
750 |
$ui['is_admin'] = 0; |
$ui['is_admin'] = 0; |
|
751 |
|
$ui['rights'] = ""; |
679 |
752 |
|
|
680 |
753 |
if (empty($user) || empty($pass)) { |
if (empty($user) || empty($pass)) { |
681 |
754 |
rg_user_set_error("invalid user or pass"); |
rg_user_set_error("invalid user or pass"); |
|
755 |
|
rg_log("user or pass are empty"); |
682 |
756 |
return FALSE; |
return FALSE; |
683 |
757 |
} |
} |
684 |
758 |
|
|
685 |
759 |
$ui0 = rg_user_info($db, 0, $user, ""); |
$ui0 = rg_user_info($db, 0, $user, ""); |
686 |
|
if ($ui0['ok'] != 1) { |
|
687 |
|
rg_user_set_error("internal error"); |
|
|
760 |
|
if ($ui0['ok'] != 1) |
688 |
761 |
return FALSE; |
return FALSE; |
689 |
|
} |
|
690 |
762 |
if ($ui0['exists'] != 1) { |
if ($ui0['exists'] != 1) { |
691 |
763 |
rg_user_set_error("invalid user or pass"); |
rg_user_set_error("invalid user or pass"); |
|
764 |
|
rg_log("user doesn't exists"); |
692 |
765 |
return FALSE; |
return FALSE; |
693 |
766 |
} |
} |
694 |
767 |
|
|
695 |
768 |
if ($ui0['suspended'] > 0) { |
if ($ui0['suspended'] > 0) { |
696 |
769 |
rg_user_set_error("invalid user or pass"); |
rg_user_set_error("invalid user or pass"); |
|
770 |
|
rg_log("account is suspended"); |
697 |
771 |
return FALSE; |
return FALSE; |
698 |
772 |
} |
} |
699 |
773 |
|
|
700 |
774 |
if ($ui0['confirmed'] == 0) { |
if ($ui0['confirmed'] == 0) { |
701 |
775 |
rg_user_set_error("invalid user or pass"); |
rg_user_set_error("invalid user or pass"); |
|
776 |
|
rg_log("account is not confirmed"); |
702 |
777 |
return FALSE; |
return FALSE; |
703 |
778 |
} |
} |
704 |
779 |
|
|
705 |
780 |
$sha1pass = rg_user_pass($ui0['salt'], $pass); |
$sha1pass = rg_user_pass($ui0['salt'], $pass); |
706 |
781 |
if (strcmp($sha1pass, $ui0['pass']) != 0) { |
if (strcmp($sha1pass, $ui0['pass']) != 0) { |
707 |
782 |
rg_user_set_error("invalid user or pass"); |
rg_user_set_error("invalid user or pass"); |
|
783 |
|
rg_log("pass mismatch"); |
708 |
784 |
return FALSE; |
return FALSE; |
709 |
785 |
} |
} |
710 |
786 |
|
|
711 |
787 |
$ui = $ui0; |
$ui = $ui0; |
712 |
|
rg_user_auto_login($db, $ui['uid'], $ui); |
|
|
788 |
|
rg_user_auto_login($db, $ui['uid'], $lock_ip, $ui); |
713 |
789 |
|
|
714 |
790 |
rg_user_set_last_seen($db, $ui['uid']); |
rg_user_set_last_seen($db, $ui['uid']); |
715 |
791 |
|
|
|
... |
... |
function rg_user_suspend($db, $uid, $op) |
724 |
800 |
{ |
{ |
725 |
801 |
rg_log("user_suspend: uid=$uid, op=$op"); |
rg_log("user_suspend: uid=$uid, op=$op"); |
726 |
802 |
|
|
|
803 |
|
$login_ui = rg_get_login_ui(); |
|
804 |
|
if (!rg_rights_allow($login_ui['rights'], "S")) |
|
805 |
|
return FALSE; |
|
806 |
|
|
727 |
807 |
$now = time(); |
$now = time(); |
728 |
808 |
|
|
729 |
809 |
if ($op == 1) |
if ($op == 1) |
|
... |
... |
function rg_user_suspend($db, $uid, $op) |
731 |
811 |
else |
else |
732 |
812 |
$v = 0; |
$v = 0; |
733 |
813 |
|
|
734 |
|
$sql = "UPDATE users SET suspended = $v WHERE uid = $uid"; |
|
735 |
|
$res = rg_sql_query($db, $sql); |
|
|
814 |
|
$parmas = array($v, $uid); |
|
815 |
|
$sql = "UPDATE users SET suspended = $1 WHERE uid = $2"; |
|
816 |
|
$res = rg_sql_query_params($db, $sql, $params); |
736 |
817 |
if ($res === FALSE) { |
if ($res === FALSE) { |
737 |
818 |
rg_user_set_error("cannot suspend (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot suspend (" . rg_sql_error() . ")"); |
738 |
819 |
return FALSE; |
return FALSE; |
739 |
820 |
} |
} |
740 |
821 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
741 |
822 |
|
|
|
823 |
|
// Invalidate cache. |
|
824 |
|
rg_cache_unset("user::" . $uid); |
|
825 |
|
|
742 |
826 |
return TRUE; |
return TRUE; |
743 |
827 |
} |
} |
744 |
828 |
|
|
|
... |
... |
function rg_user_suspend($db, $uid, $op) |
749 |
833 |
function rg_user_make_admin($db, $uid, $op) |
function rg_user_make_admin($db, $uid, $op) |
750 |
834 |
{ |
{ |
751 |
835 |
rg_log("user_make_admin: uid=$uid, op=$op"); |
rg_log("user_make_admin: uid=$uid, op=$op"); |
|
836 |
|
rg_prof_start("user_make_admin"); |
752 |
837 |
|
|
753 |
|
$sql = "UPDATE users SET is_admin = $op WHERE uid = $uid"; |
|
754 |
|
$res = rg_sql_query($db, $sql); |
|
755 |
|
if ($res === FALSE) { |
|
756 |
|
rg_user_set_error("cannot make admin (" . rg_sql_error() . ")"); |
|
757 |
|
return FALSE; |
|
758 |
|
} |
|
759 |
|
rg_sql_free_result($res); |
|
|
838 |
|
$ret = FALSE; |
|
839 |
|
do { |
|
840 |
|
$login_ui = rg_get_login_ui(); |
|
841 |
|
if (!rg_rights_allow($login_ui['rights'], "A")) |
|
842 |
|
return FALSE; |
760 |
843 |
|
|
761 |
|
return TRUE; |
|
|
844 |
|
$params = array($op, $uid); |
|
845 |
|
$sql = "UPDATE users SET is_admin = $1 WHERE uid = $2"; |
|
846 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
847 |
|
if ($res === FALSE) { |
|
848 |
|
rg_user_set_error("cannot make admin (" . rg_sql_error() . ")"); |
|
849 |
|
break; |
|
850 |
|
} |
|
851 |
|
rg_sql_free_result($res); |
|
852 |
|
|
|
853 |
|
// Invalidate cache. |
|
854 |
|
rg_cache_unset("user::" . $uid); |
|
855 |
|
$ret = TRUE; |
|
856 |
|
} while (0); |
|
857 |
|
|
|
858 |
|
rg_prof_end("user_make_admin"); |
|
859 |
|
return $ret; |
762 |
860 |
} |
} |
763 |
861 |
|
|
764 |
862 |
/* |
/* |
|
... |
... |
function rg_user_set_last_seen($db, $uid) |
770 |
868 |
|
|
771 |
869 |
$now = time(); |
$now = time(); |
772 |
870 |
|
|
773 |
|
$sql = "UPDATE users SET last_seen = $now WHERE uid = $uid"; |
|
774 |
|
$res = rg_sql_query($db, $sql); |
|
|
871 |
|
$params = array($now, $uid); |
|
872 |
|
$sql = "UPDATE users SET last_seen = $1 WHERE uid = $2"; |
|
873 |
|
$res = rg_sql_query_params($db, $sql, $params); |
775 |
874 |
if ($res === FALSE) { |
if ($res === FALSE) { |
776 |
875 |
rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot update last seen (" . rg_sql_error() . ")"); |
777 |
876 |
return FALSE; |
return FALSE; |
778 |
877 |
} |
} |
779 |
878 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
780 |
879 |
|
|
|
880 |
|
// TODO: check if we need to invalidate cache |
|
881 |
|
|
781 |
882 |
return TRUE; |
return TRUE; |
782 |
883 |
} |
} |
783 |
884 |
|
|
784 |
885 |
/* |
/* |
785 |
886 |
* List users |
* List users |
|
887 |
|
* TODO: switch to templates. |
786 |
888 |
*/ |
*/ |
787 |
|
function rg_user_list($db, $url) |
|
|
889 |
|
function rg_user_list($db) |
788 |
890 |
{ |
{ |
789 |
|
rg_log("user_list, url=$url..."); |
|
|
891 |
|
rg_log("user_list"); |
790 |
892 |
|
|
791 |
893 |
$ret = ""; |
$ret = ""; |
792 |
894 |
|
|
793 |
|
$uid = rg_var_uint("uid"); |
|
794 |
|
|
|
795 |
|
$suspend = rg_var_uint("suspend"); |
|
796 |
|
if ($suspend == 1) { |
|
797 |
|
if (!rg_user_suspend($db, $uid, 1)) |
|
798 |
|
$ret .= "<font color=red>Cannot suspend!</font><br />"; |
|
799 |
|
} |
|
800 |
|
|
|
801 |
|
$unsuspend = rg_var_uint("unsuspend"); |
|
802 |
|
if ($unsuspend == 1) { |
|
803 |
|
if (!rg_user_suspend($db, $uid, 0)) |
|
804 |
|
$ret .= "<font color=red>Cannot unsuspend!</font><br />"; |
|
805 |
|
} |
|
806 |
|
|
|
807 |
|
$make_admin = rg_var_uint("make_admin"); |
|
808 |
|
if ($make_admin == 1) { |
|
809 |
|
if (!rg_user_make_admin($db, $uid, 1)) |
|
810 |
|
$ret .= "<font color=red>Cannot make admin!</font><br />"; |
|
811 |
|
} |
|
812 |
|
|
|
813 |
|
$remove_admin = rg_var_uint("remove_admin"); |
|
814 |
|
if ($remove_admin == 1) { |
|
815 |
|
if (!rg_user_make_admin($db, $uid, 0)) |
|
816 |
|
$ret .= "<font color=red>Cannot remove admin!</font><br />"; |
|
817 |
|
} |
|
818 |
|
|
|
819 |
|
$remove = rg_var_uint("remove"); |
|
820 |
|
if ($remove > 0) { |
|
821 |
|
if (!rg_user_remove($db, $uid)) |
|
822 |
|
$ret .= "<font color=red>Cannot remove!</font><br />"; |
|
823 |
|
} |
|
824 |
|
|
|
825 |
895 |
$sql = "SELECT * FROM users ORDER BY username"; |
$sql = "SELECT * FROM users ORDER BY username"; |
826 |
896 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
827 |
897 |
if ($res === FALSE) { |
if ($res === FALSE) { |
|
... |
... |
function rg_user_list($db, $url) |
836 |
906 |
$ret .= " <th>E-mail</th>\n"; |
$ret .= " <th>E-mail</th>\n"; |
837 |
907 |
$ret .= " <th>Admin?</th>\n"; |
$ret .= " <th>Admin?</th>\n"; |
838 |
908 |
$ret .= " <th>Creation date (UTC)</th>\n"; |
$ret .= " <th>Creation date (UTC)</th>\n"; |
839 |
|
$ret .= " <th>Quota</th>\n"; |
|
|
909 |
|
$ret .= " <th>Plan</th>\n"; |
840 |
910 |
$ret .= " <th>Suspended?</th>\n"; |
$ret .= " <th>Suspended?</th>\n"; |
841 |
911 |
$ret .= " <th>Confirmed?</th>\n"; |
$ret .= " <th>Confirmed?</th>\n"; |
842 |
912 |
$ret .= " <th>Session time</th>\n"; |
$ret .= " <th>Session time</th>\n"; |
|
... |
... |
function rg_user_list($db, $url) |
851 |
921 |
$ret .= " <td>" . $row['email'] . "</td>\n"; |
$ret .= " <td>" . $row['email'] . "</td>\n"; |
852 |
922 |
$ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n"; |
$ret .= " <td>" . ($row['is_admin'] == 1 ? "Yes" : "No") . "</td>\n"; |
853 |
923 |
$ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n"; |
$ret .= " <td>" . gmdate("Y-m-d", $row['itime']) . "</td>\n"; |
854 |
|
if ($row['disk_quota_mb'] > 0) |
|
855 |
|
$_v = rg_1024($row['disk_quota_mb'] * 1024 * 1024); |
|
856 |
|
else |
|
857 |
|
$_v = "unlimited"; |
|
858 |
|
$ret .= " <td>" . $_v . "</td>\n"; |
|
|
924 |
|
|
|
925 |
|
$pi = rg_plan_info($db, $row['plan_id']); |
|
926 |
|
$plan = "Unlimited"; |
|
927 |
|
if ($pi['exists'] == 1) |
|
928 |
|
$plan = $pi['name']; |
|
929 |
|
$ret .= " <td>" . $plan . "</td>\n"; |
859 |
930 |
$ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n"; |
$ret .= " <td>" . ($row['suspended'] == 0 ? "No" : "Yes") . "</th>\n"; |
860 |
931 |
$ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n"; |
$ret .= " <td>" . ($row['confirmed'] == 0 ? "No" : gmdate("Y-m-d", $row['confirmed'])) . "</th>\n"; |
861 |
932 |
$ret .= " <td>" . $row['session_time'] . "s</td>\n"; |
$ret .= " <td>" . $row['session_time'] . "s</td>\n"; |
|
... |
... |
function rg_user_list($db, $url) |
865 |
936 |
$ret .= " <td>" . $v . "</td>\n"; |
$ret .= " <td>" . $v . "</td>\n"; |
866 |
937 |
|
|
867 |
938 |
// operations |
// operations |
868 |
|
$_url = $url . "&uid=" . $row['uid']; |
|
|
939 |
|
$url = "/op/admin/users"; |
|
940 |
|
$url2 = $row['username']; |
869 |
941 |
$ret .= " <td>"; |
$ret .= " <td>"; |
870 |
942 |
|
|
871 |
943 |
// edit |
// edit |
872 |
|
$ret .= "[<a href=\"$_url&subsubop=3\">Edit</a>]"; |
|
|
944 |
|
$ret .= "[<a href=\"$url/edit/$url2\">Edit</a>]"; |
873 |
945 |
|
|
874 |
946 |
// suspend |
// suspend |
875 |
|
$v = "suspend=1"; $t = "Suspend"; |
|
|
947 |
|
$v = "suspend"; $t = "Suspend"; |
876 |
948 |
if ($row['suspended'] > 0) { |
if ($row['suspended'] > 0) { |
877 |
949 |
$t = "Unsuspend"; |
$t = "Unsuspend"; |
878 |
|
$v = "unsuspend=1"; |
|
|
950 |
|
$v = "unsuspend"; |
879 |
951 |
} |
} |
880 |
|
$ret .= "[<a href=\"$_url&subsubop=1&$v\">$t</a>]"; |
|
|
952 |
|
$ret .= "[<a href=\"$url/$v/$url2\">$t</a>]"; |
881 |
953 |
|
|
882 |
954 |
// admin |
// admin |
883 |
|
$v = "make_admin=1"; $t = "Make admin"; |
|
|
955 |
|
$v = "make_admin"; $t = "Make admin"; |
884 |
956 |
if ($row['is_admin'] == 1) { |
if ($row['is_admin'] == 1) { |
885 |
957 |
$t = "Remove admin"; |
$t = "Remove admin"; |
886 |
|
$v = "remove_admin=1"; |
|
|
958 |
|
$v = "remove_admin"; |
887 |
959 |
} |
} |
888 |
|
$ret .= "[<a href=\"$_url&subsubop=1&$v\">$t</a>]"; |
|
|
960 |
|
$ret .= "[<a href=\"$url/$v/$url2\">$t</a>]"; |
889 |
961 |
|
|
890 |
962 |
// remove |
// remove |
891 |
963 |
if ($row['suspended'] > 0) |
if ($row['suspended'] > 0) |
892 |
|
$ret .= "[<a href=\"$_url&subsubop=1&remove=1\">Remove!</a>]"; |
|
|
964 |
|
$ret .= "[<a href=\"$url/remove/$url2\">Remove!</a>]"; |
893 |
965 |
|
|
894 |
966 |
$ret .= " </td>"; |
$ret .= " </td>"; |
895 |
967 |
$ret .= "</tr>\n"; |
$ret .= "</tr>\n"; |
|
... |
... |
function rg_user_forgot_pass_uid($db, $token) |
912 |
984 |
rg_log("user_forgot_pass_uid: token=$token"); |
rg_log("user_forgot_pass_uid: token=$token"); |
913 |
985 |
|
|
914 |
986 |
$now = time(); |
$now = time(); |
915 |
|
$e_token = rg_sql_escape($db, $token); |
|
916 |
987 |
|
|
|
988 |
|
$params = array($token, $now); |
917 |
989 |
$sql = "SELECT uid FROM forgot_pass" |
$sql = "SELECT uid FROM forgot_pass" |
918 |
|
. " WHERE token = '$e_token'" |
|
919 |
|
. " AND expire > $now"; |
|
920 |
|
$res = rg_sql_query($db, $sql); |
|
|
990 |
|
. " WHERE token = $1" |
|
991 |
|
. " AND expire > $2"; |
|
992 |
|
$res = rg_sql_query_params($db, $sql, $params); |
921 |
993 |
if ($res === FALSE) { |
if ($res === FALSE) { |
922 |
994 |
rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot lookup token (" . rg_sql_error() . ")"); |
923 |
995 |
return $ret; |
return $ret; |
|
... |
... |
function rg_user_forgot_pass_mail_prepare($db, $email) |
964 |
1036 |
$uid = $r['uid']; |
$uid = $r['uid']; |
965 |
1037 |
|
|
966 |
1038 |
// store token in database |
// store token in database |
|
1039 |
|
$params = array($token, $uid, $expire); |
967 |
1040 |
$sql = "INSERT INTO forgot_pass (token, uid, expire)" |
$sql = "INSERT INTO forgot_pass (token, uid, expire)" |
968 |
|
. " VALUES ('$token', $uid, $expire)"; |
|
969 |
|
$res = rg_sql_query($db, $sql); |
|
|
1041 |
|
. " VALUES ($1, $2, $3)"; |
|
1042 |
|
$res = rg_sql_query_params($db, $sql, $params); |
970 |
1043 |
if ($res === FALSE) { |
if ($res === FALSE) { |
971 |
1044 |
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
972 |
1045 |
return $ret; |
return $ret; |
|
... |
... |
function rg_user_forgot_pass_mail($db, $email) |
1012 |
1085 |
"Hello!\n\n" |
"Hello!\n\n" |
1013 |
1086 |
. "If you want to reset the password, follow:\n" |
. "If you want to reset the password, follow:\n" |
1014 |
1087 |
. $base_url |
. $base_url |
1015 |
|
. rg_re_url("/op/forgot_link") . "&forgot_token=" . $r['token'] |
|
|
1088 |
|
. rg_re_url("/op/forgot_link") . "/" . $r['token'] |
1016 |
1089 |
. "\n\nRocketGit team", |
. "\n\nRocketGit team", |
1017 |
1090 |
$headers, |
$headers, |
1018 |
1091 |
"-f $rg_admin_email")) { |
"-f $rg_admin_email")) { |
|
... |
... |
function rg_user_forgot_pass_destroy($db, $uid) |
1033 |
1106 |
{ |
{ |
1034 |
1107 |
rg_log("user_forgot_pass_destroy: uid=$uid"); |
rg_log("user_forgot_pass_destroy: uid=$uid"); |
1035 |
1108 |
|
|
1036 |
|
$sql = "DELETE FROM forgot_pass WHERE uid = $uid"; |
|
1037 |
|
$res = rg_sql_query($db, $sql); |
|
|
1109 |
|
$params = array($uid); |
|
1110 |
|
$sql = "DELETE FROM forgot_pass WHERE uid = $1"; |
|
1111 |
|
$res = rg_sql_query_params($db, $sql, $params); |
1038 |
1112 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1039 |
1113 |
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot query (" . rg_sql_error() . ")"); |
1040 |
1114 |
return FALSE; |
return FALSE; |
|
... |
... |
function rg_user_set_pass($db, $uid, $pass) |
1048 |
1122 |
{ |
{ |
1049 |
1123 |
rg_log("user_set_pass: uid=$uid pass=$pass"); |
rg_log("user_set_pass: uid=$uid pass=$pass"); |
1050 |
1124 |
|
|
1051 |
|
$e_salt = rg_id(40); |
|
1052 |
|
$e_sha1pass = rg_user_pass($e_salt, $pass); |
|
|
1125 |
|
$salt = rg_id(40); |
|
1126 |
|
$pass = rg_user_pass($salt, $pass); |
1053 |
1127 |
|
|
|
1128 |
|
$params = array($salt, $pass, $uid); |
1054 |
1129 |
$sql = "UPDATE users SET" |
$sql = "UPDATE users SET" |
1055 |
|
." salt = '$e_salt'" |
|
1056 |
|
. ", pass = '$e_sha1pass'" |
|
1057 |
|
. " WHERE uid = " . $uid; |
|
1058 |
|
$res = rg_sql_query($db, $sql); |
|
|
1130 |
|
." salt = $1" |
|
1131 |
|
. ", pass = $2" |
|
1132 |
|
. " WHERE uid = $3"; |
|
1133 |
|
$res = rg_sql_query_params($db, $sql, $params); |
1059 |
1134 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1060 |
1135 |
rg_user_set_error("cannot update pass (" . rg_sql_error() . ")"); |
rg_user_set_error("cannot update pass (" . rg_sql_error() . ")"); |
1061 |
1136 |
return FALSE; |
return FALSE; |
1062 |
1137 |
} |
} |
1063 |
1138 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1064 |
1139 |
|
|
|
1140 |
|
// Invalidate cache. |
|
1141 |
|
rg_cache_unset("user::" . $uid); |
|
1142 |
|
|
1065 |
1143 |
return TRUE; |
return TRUE; |
1066 |
1144 |
} |
} |
1067 |
1145 |
|
|
1068 |
1146 |
/* |
/* |
1069 |
|
* Confirm account creation (send mail) |
|
|
1147 |
|
* Confirm account creation |
1070 |
1148 |
*/ |
*/ |
1071 |
|
function rg_user_confirm_send($email, $token) |
|
|
1149 |
|
function rg_user_confirm($db, $token) |
1072 |
1150 |
{ |
{ |
1073 |
|
global $rg_admin_name, $rg_admin_email; |
|
|
1151 |
|
rg_prof_start("user_confirm"); |
|
1152 |
|
rg_log("user_confirm: token=$token"); |
1074 |
1153 |
|
|
1075 |
|
rg_log("user_confirm_send: email=$email, token=$token"); |
|
|
1154 |
|
$now = time(); |
|
1155 |
|
$token = preg_replace("/[^A-Za-z0-9]/", "", $token); |
1076 |
1156 |
|
|
1077 |
|
$headers = "From: $rg_admin_name <$rg_admin_email>"; |
|
|
1157 |
|
$ret = FALSE; |
|
1158 |
|
do { |
|
1159 |
|
if (empty($token)) { |
|
1160 |
|
rg_user_set_error("invalid token"); |
|
1161 |
|
break; |
|
1162 |
|
} |
1078 |
1163 |
|
|
1079 |
|
$proto = "http://"; |
|
1080 |
|
if (isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'], "on") == 0)) |
|
1081 |
|
$proto = "https://"; |
|
|
1164 |
|
$params = array($token); |
|
1165 |
|
$sql = "SELECT uid FROM users WHERE confirm_token = $1"; |
|
1166 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
1167 |
|
if ($res === FALSE) { |
|
1168 |
|
rg_user_set_error("cannot search for token (" . rg_sql_error() . ")"); |
|
1169 |
|
break; |
|
1170 |
|
} |
|
1171 |
|
$rows = rg_sql_num_rows($res); |
|
1172 |
|
if ($rows == 1) |
|
1173 |
|
$row = rg_sql_fetch_array($res); |
|
1174 |
|
rg_sql_free_result($res); |
|
1175 |
|
if ($rows != 1) { |
|
1176 |
|
rg_user_set_error("cannot find token"); |
|
1177 |
|
break; |
|
1178 |
|
} |
|
1179 |
|
$uid = $row['uid']; |
|
1180 |
|
|
|
1181 |
|
// "< 2" because we mark with "1" if "no need to confirm" |
|
1182 |
|
$params = array($now, $uid); |
|
1183 |
|
$sql = "UPDATE users SET confirmed = $1" |
|
1184 |
|
. " WHERE uid = $2" |
|
1185 |
|
. " AND confirmed < 2"; |
|
1186 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
1187 |
|
if ($res === FALSE) { |
|
1188 |
|
rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")"); |
|
1189 |
|
break; |
|
1190 |
|
} |
|
1191 |
|
rg_sql_free_result($res); |
1082 |
1192 |
|
|
1083 |
|
if (!mail($email, |
|
1084 |
|
"Account creation confirmation", |
|
1085 |
|
"Hello!\n\n" |
|
1086 |
|
. "Please confirm your account creation following:\n" |
|
1087 |
|
. $proto |
|
1088 |
|
. @$_SERVER['HTTP_HOST'] |
|
1089 |
|
. rg_re_url("/op/confirm") . "&token=" . $token |
|
1090 |
|
. "\n\nRocketGit team", |
|
1091 |
|
$headers, |
|
1092 |
|
"-f $rg_admin_email")) { |
|
1093 |
|
rg_user_set_error("cannot send mail ($php_errormsg)!"); |
|
1094 |
|
return FALSE; |
|
1095 |
|
} |
|
|
1193 |
|
rg_cache_unset("user::" . $uid); |
1096 |
1194 |
|
|
1097 |
|
return TRUE; |
|
|
1195 |
|
$ret = $uid; |
|
1196 |
|
} while (0); |
|
1197 |
|
|
|
1198 |
|
rg_prof_end("user_confirm"); |
|
1199 |
|
return $ret; |
1098 |
1200 |
} |
} |
1099 |
1201 |
|
|
1100 |
1202 |
/* |
/* |
1101 |
|
* Confirm account creation |
|
|
1203 |
|
* Add a suggestion to database |
1102 |
1204 |
*/ |
*/ |
1103 |
|
function rg_user_confirm($db, $token) |
|
|
1205 |
|
function rg_user_suggestion($db, $uid, $email, $suggestion) |
1104 |
1206 |
{ |
{ |
1105 |
|
$now = time(); |
|
1106 |
|
|
|
1107 |
|
$sql = "SELECT uid FROM users WHERE confirm_token = '$token'"; |
|
1108 |
|
$res = rg_sql_query($db, $sql); |
|
|
1207 |
|
$params = array($uid, $email, $suggestion); |
|
1208 |
|
$sql = "INSERT INTO suggestions (uid, email, suggestion)" |
|
1209 |
|
. " VALUES ($1, $2, $3)"; |
|
1210 |
|
$res = rg_sql_query_params($db, $sql, $params); |
1109 |
1211 |
if ($res === FALSE) { |
if ($res === FALSE) { |
1110 |
|
rg_user_set_error("cannot search for token (" . rg_sql_error() . ")"); |
|
|
1212 |
|
rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")"); |
1111 |
1213 |
return FALSE; |
return FALSE; |
1112 |
1214 |
} |
} |
1113 |
|
$rows = rg_sql_num_rows($res); |
|
1114 |
|
if ($rows > 0) |
|
1115 |
|
$row = rg_sql_fetch_array($res); |
|
1116 |
1215 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1117 |
|
if ($rows == 0) { |
|
1118 |
|
rg_user_set_error("cannot find token (" . rg_sql_error() . ")"); |
|
|
1216 |
|
|
|
1217 |
|
return TRUE; |
|
1218 |
|
} |
|
1219 |
|
|
|
1220 |
|
/* |
|
1221 |
|
* Checks if a user is over limit. |
|
1222 |
|
* Returns maximum allowed in @max. |
|
1223 |
|
*/ |
|
1224 |
|
function rg_user_over_limit($db, $ui, &$max) |
|
1225 |
|
{ |
|
1226 |
|
$pi = rg_plan_info($db, $ui['plan_id']); |
|
1227 |
|
if ($pi['exists'] != 1) { |
|
1228 |
|
rg_internal_error("Invalid plan."); |
1119 |
1229 |
return FALSE; |
return FALSE; |
1120 |
1230 |
} |
} |
1121 |
|
$uid = $row['uid']; |
|
1122 |
1231 |
|
|
1123 |
|
$sql = "UPDATE users SET confirmed = $now" |
|
1124 |
|
. " WHERE uid = $uid"; |
|
1125 |
|
$res = rg_sql_query($db, $sql); |
|
1126 |
|
if ($res === FALSE) { |
|
1127 |
|
rg_user_set_error("cannot update confirmed (" . rg_sql_error() . ")"); |
|
|
1232 |
|
$max = $pi['disk_mb']; |
|
1233 |
|
if ($max == 0) |
1128 |
1234 |
return FALSE; |
return FALSE; |
1129 |
|
} |
|
1130 |
|
rg_sql_free_result($res); |
|
1131 |
1235 |
|
|
1132 |
|
return $uid; |
|
|
1236 |
|
if ($ui['disk_used_mb'] >= $max) |
|
1237 |
|
return TRUE; |
|
1238 |
|
|
|
1239 |
|
return FALSE; |
1133 |
1240 |
} |
} |
1134 |
1241 |
|
|
1135 |
1242 |
/* |
/* |
1136 |
|
* Add a suggestion to database |
|
|
1243 |
|
* Returns the login structure of the logged-in user |
1137 |
1244 |
*/ |
*/ |
1138 |
|
function rg_user_suggestion($db, $uid, $email, $suggestion) |
|
|
1245 |
|
function rg_user_get_login_ui() |
1139 |
1246 |
{ |
{ |
1140 |
|
$e_email = rg_sql_escape($db, $email); |
|
1141 |
|
$e_suggestion = rg_sql_escape($db, $suggestion); |
|
|
1247 |
|
global $login_ui; |
1142 |
1248 |
|
|
1143 |
|
$sql = "INSERT INTO suggestions (uid, email, suggestion)" |
|
1144 |
|
. " VALUES ($uid, '$e_email', '$e_suggestion')"; |
|
1145 |
|
$res = rg_sql_query($db, $sql); |
|
1146 |
|
if ($res === FALSE) { |
|
1147 |
|
rg_user_set_error("cannot add suggestion (" . rg_sql_error() . ")"); |
|
1148 |
|
return FALSE; |
|
|
1249 |
|
return $login_ui; |
|
1250 |
|
} |
|
1251 |
|
|
|
1252 |
|
/* |
|
1253 |
|
* Returns the login structure of the target user (admin section) |
|
1254 |
|
*/ |
|
1255 |
|
function rg_user_get_target_ui() |
|
1256 |
|
{ |
|
1257 |
|
global $target_ui; |
|
1258 |
|
|
|
1259 |
|
return $target_ui; |
|
1260 |
|
} |
|
1261 |
|
|
|
1262 |
|
/* |
|
1263 |
|
* Test access of a login_user to an uid |
|
1264 |
|
* TODO: Admin will have access... |
|
1265 |
|
*/ |
|
1266 |
|
function rg_user_allow_access($login_ui, $uid) |
|
1267 |
|
{ |
|
1268 |
|
/* uid 0 does not exists */ |
|
1269 |
|
if ($uid == 0) |
|
1270 |
|
return TRUE; |
|
1271 |
|
|
|
1272 |
|
if ($login_ui['uid'] == $uid) |
|
1273 |
|
return TRUE; |
|
1274 |
|
|
|
1275 |
|
if (rg_rights_allow($login_ui['rights'], "U")) |
|
1276 |
|
return TRUE; |
|
1277 |
|
|
|
1278 |
|
rg_security_violation_no_exit("uid " . $login_ui['uid'] |
|
1279 |
|
. " has no access to uid $uid!"); |
|
1280 |
|
return FALSE; |
|
1281 |
|
} |
|
1282 |
|
|
|
1283 |
|
/* |
|
1284 |
|
* High level functions |
|
1285 |
|
*/ |
|
1286 |
|
|
|
1287 |
|
/* |
|
1288 |
|
* High-level function for editing a user |
|
1289 |
|
*/ |
|
1290 |
|
function rg_user_edit_high_level($db, $sid, $more) |
|
1291 |
|
{ |
|
1292 |
|
rg_log("user_edit_high_level"); |
|
1293 |
|
|
|
1294 |
|
$ret = ""; |
|
1295 |
|
|
|
1296 |
|
$login_ui = rg_user_get_login_ui(); |
|
1297 |
|
$target_ui = rg_user_get_target_ui(); |
|
1298 |
|
$doit = rg_var_uint("doit"); |
|
1299 |
|
|
|
1300 |
|
if (!rg_user_allow_access($login_ui, $target_ui['uid'])) { |
|
1301 |
|
$ret .= rg_template("access_denied.html", $more); |
|
1302 |
|
return $ret; |
1149 |
1303 |
} |
} |
1150 |
|
rg_sql_free_result($res); |
|
1151 |
1304 |
|
|
1152 |
|
return TRUE; |
|
|
1305 |
|
if (($target_ui['uid'] == 0) && ($more['rg_account_allow_creation'] != 1)) { |
|
1306 |
|
$ret .= rg_template("user/create_na.html", $more); |
|
1307 |
|
return $ret; |
|
1308 |
|
} |
|
1309 |
|
|
|
1310 |
|
if ($target_ui['uid'] > 0) |
|
1311 |
|
$more['create_mode'] = 0; |
|
1312 |
|
else |
|
1313 |
|
$more['create_mode'] = 1; |
|
1314 |
|
|
|
1315 |
|
if ($doit == 0) { |
|
1316 |
|
if ($target_ui['uid'] > 0) { |
|
1317 |
|
// TODO: check also access rights? |
|
1318 |
|
$ui = $target_ui; |
|
1319 |
|
} else { |
|
1320 |
|
// Defaults |
|
1321 |
|
$ui = array(); |
|
1322 |
|
$ui['uid'] = 0; |
|
1323 |
|
$ui['username'] = ""; |
|
1324 |
|
$ui['realname'] = ""; |
|
1325 |
|
$ui['email'] = ""; |
|
1326 |
|
$ui['pass'] = ""; |
|
1327 |
|
$ui['pass2'] = ""; |
|
1328 |
|
$ui['is_admin'] = "0"; |
|
1329 |
|
$ui['rights'] = rg_rights_checkboxes("user", "C"); // TODO |
|
1330 |
|
$ui['plan_id'] = 0; |
|
1331 |
|
$ui['session_time'] = 600; |
|
1332 |
|
} |
|
1333 |
|
} |
|
1334 |
|
|
|
1335 |
|
$errmsg = array(); |
|
1336 |
|
$load_form = TRUE; |
|
1337 |
|
do { |
|
1338 |
|
if ($doit != 1) |
|
1339 |
|
break; |
|
1340 |
|
|
|
1341 |
|
$ui = array(); |
|
1342 |
|
$ui['uid'] = $target_ui['uid']; |
|
1343 |
|
$ui['username'] = rg_var_str("username"); |
|
1344 |
|
$ui['realname'] = rg_var_str("realname"); |
|
1345 |
|
$ui['email'] = rg_var_str("email"); |
|
1346 |
|
$ui['pass'] = rg_var_str("pass"); |
|
1347 |
|
$ui['pass2'] = rg_var_str("pass2"); |
|
1348 |
|
$ui['is_admin'] = rg_var_uint("is_admin"); |
|
1349 |
|
$ui['rights'] = "C"; // TODO |
|
1350 |
|
$ui['plan_id'] = rg_var_uint("plan_id"); |
|
1351 |
|
$ui['session_time'] = rg_var_uint("session_time"); |
|
1352 |
|
$ui['confirm_token'] = rg_id(20); |
|
1353 |
|
|
|
1354 |
|
$token = rg_var_str("token"); |
|
1355 |
|
|
|
1356 |
|
if (!rg_token_valid($db, $sid, $token)) { |
|
1357 |
|
$errmsg[] = "invalid token; try again"; |
|
1358 |
|
break; |
|
1359 |
|
} |
|
1360 |
|
|
|
1361 |
|
if ($ui['uid'] == 0) { |
|
1362 |
|
$_ui = rg_user_info($db, 0, $ui['username'], ""); |
|
1363 |
|
if ($_ui['ok'] != 1) { |
|
1364 |
|
$errmsg[] = rg_user_error(); |
|
1365 |
|
break; |
|
1366 |
|
} |
|
1367 |
|
if ($_ui['exists'] == 1) { |
|
1368 |
|
$errmsg[] = "user already exists"; |
|
1369 |
|
break; |
|
1370 |
|
} |
|
1371 |
|
} |
|
1372 |
|
|
|
1373 |
|
// Security warning - a user can pass "pass" var to me avoiding |
|
1374 |
|
// being asked for old pass |
|
1375 |
|
if ($ui['uid'] > 0) { |
|
1376 |
|
if (!empty($ui['pass'])) |
|
1377 |
|
rg_security_violation_no_exit("User tried to" |
|
1378 |
|
. " change pass using 'edit info' page."); |
|
1379 |
|
$ui['pass'] = ""; |
|
1380 |
|
} |
|
1381 |
|
|
|
1382 |
|
$r = rg_user_edit($db, $ui); |
|
1383 |
|
if ($r === FALSE) { |
|
1384 |
|
$errmsg[] = rg_user_error(); |
|
1385 |
|
break; |
|
1386 |
|
} |
|
1387 |
|
|
|
1388 |
|
// TODO: should we just redirect to login page? |
|
1389 |
|
// TODO: or to user page if there is no need to confirm the account? |
|
1390 |
|
if ($ui['uid'] == 0) |
|
1391 |
|
$ret = rg_template("user/create_ok.html", $more); |
|
1392 |
|
else |
|
1393 |
|
$ret = rg_template("user/edit_ok.html", $more); |
|
1394 |
|
$load_form = FALSE; |
|
1395 |
|
} while (0); |
|
1396 |
|
|
|
1397 |
|
if ($load_form) { |
|
1398 |
|
if (rg_rights_allow($login_ui['rights'], "U")) |
|
1399 |
|
$more['admin_mode'] = 1; |
|
1400 |
|
else |
|
1401 |
|
$more['admin_mode'] = 0; |
|
1402 |
|
|
|
1403 |
|
$more = array_merge($more, $ui); |
|
1404 |
|
$more['HTML:select_plan'] = rg_plan_select($db, $ui['plan_id']); |
|
1405 |
|
$more['HTML:checkbox_rights'] = rg_rights_checkboxes("user", $ui['rights']); |
|
1406 |
|
$more['HTML:errmsg'] = rg_template_errmsg($errmsg); |
|
1407 |
|
$more['rg_form_token'] = rg_token_get($db, $sid); |
|
1408 |
|
$ret .= rg_template("user/add_edit.html", $more); |
|
1409 |
|
} |
|
1410 |
|
|
|
1411 |
|
return $ret; |
1153 |
1412 |
} |
} |
1154 |
1413 |
|
|
1155 |
1414 |
?> |
?> |
File inc/util.inc.php changed (mode: 100644) (index 474f101..dbf987f) |
... |
... |
require_once($INC . "/prof.inc.php"); |
3 |
3 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
4 |
4 |
|
|
5 |
5 |
set_error_handler("rg_error_handler"); |
set_error_handler("rg_error_handler"); |
6 |
|
register_shutdown_function("rg_shutdown_error"); |
|
|
6 |
|
register_shutdown_function("rg_error_shutdown"); |
7 |
7 |
|
|
8 |
8 |
$rg_util_error = ""; |
$rg_util_error = ""; |
9 |
9 |
|
|
|
... |
... |
function rg_re_url($area) |
129 |
129 |
if (isset($_REQUEST['rwe'])) |
if (isset($_REQUEST['rwe'])) |
130 |
130 |
return $area; |
return $area; |
131 |
131 |
|
|
132 |
|
return "/?vv=" . $area; |
|
133 |
|
} |
|
134 |
|
|
|
135 |
|
/* |
|
136 |
|
* This is used for forms |
|
137 |
|
*/ |
|
138 |
|
function rg_re_post($op) |
|
139 |
|
{ |
|
140 |
|
if (isset($_REQUEST['rwe'])) |
|
141 |
|
return $op; |
|
|
132 |
|
$add = ""; |
|
133 |
|
if (isset($_SERVER['PHP_SELF'])) |
|
134 |
|
$add = $_SERVER['PHP_SELF']; |
142 |
135 |
|
|
143 |
|
return "/?vv=$op"; |
|
|
136 |
|
return $add . "/?vv=" . $area; |
144 |
137 |
} |
} |
145 |
138 |
|
|
146 |
139 |
function rg_re_userpage($ui) |
function rg_re_userpage($ui) |
|
... |
... |
function rg_re_userpage($ui) |
156 |
149 |
|
|
157 |
150 |
$s = $prefix . "/" . $ui['username']; |
$s = $prefix . "/" . $ui['username']; |
158 |
151 |
|
|
159 |
|
if (isset($_REQUEST['rwe'])) |
|
160 |
|
return $s; |
|
161 |
|
|
|
162 |
|
return $_SERVER['PHP_SELF'] . "?vv=$s"; |
|
|
152 |
|
return rg_re_url($s); |
163 |
153 |
} |
} |
164 |
154 |
|
|
165 |
155 |
function rg_re_repopage($ui, $repo_name) |
function rg_re_repopage($ui, $repo_name) |
|
... |
... |
function rg_re_repopage($ui, $repo_name) |
171 |
161 |
|
|
172 |
162 |
$s = rg_re_userpage($ui) . "/" . $repo_name; |
$s = rg_re_userpage($ui) . "/" . $repo_name; |
173 |
163 |
|
|
174 |
|
if (isset($_REQUEST['rwe'])) |
|
175 |
|
return $s; |
|
176 |
|
|
|
177 |
|
return $_SERVER['PHP_SELF'] . "?vv=$s"; |
|
|
164 |
|
return rg_re_url($s); |
178 |
165 |
} |
} |
179 |
166 |
|
|
180 |
167 |
function rg_re_bugpage($ui, $repo_name, $bug_id) |
function rg_re_bugpage($ui, $repo_name, $bug_id) |
181 |
168 |
{ |
{ |
182 |
|
$s = rg_re_repopage($ui, $repo_name) . "/bug/" . $bug_id; |
|
183 |
|
|
|
184 |
|
if (isset($_REQUEST['rwe'])) |
|
185 |
|
return $s; |
|
186 |
|
|
|
187 |
|
return $_SERVER['PHP_SELF'] . "?vv=$s"; |
|
|
169 |
|
return rg_re_repopage($ui, $repo_name) . "/bug/" . $bug_id; |
188 |
170 |
} |
} |
189 |
171 |
|
|
190 |
172 |
function rg_base_url() |
function rg_base_url() |
191 |
173 |
{ |
{ |
|
174 |
|
if (!isset($_SERVER['REMOTE_ADDR'])) |
|
175 |
|
return "http://SERVER/"; |
|
176 |
|
|
192 |
177 |
$port = ""; |
$port = ""; |
193 |
178 |
if (isset($_SERVER['HTTPS'])) { |
if (isset($_SERVER['HTTPS'])) { |
194 |
179 |
$proto = "https"; |
$proto = "https"; |
|
... |
... |
function rg_chars_allow($name, $allowed_regexp) |
296 |
281 |
*/ |
*/ |
297 |
282 |
function rg_rmdir($dir) |
function rg_rmdir($dir) |
298 |
283 |
{ |
{ |
299 |
|
rg_log("rmdir: $dir"); |
|
300 |
|
|
|
301 |
284 |
if (!is_dir($dir)) { |
if (!is_dir($dir)) { |
302 |
285 |
rg_util_set_error("WARN: asked to remove a non-existing dir ($dir)"); |
rg_util_set_error("WARN: asked to remove a non-existing dir ($dir)"); |
303 |
286 |
return TRUE; |
return TRUE; |
|
... |
... |
function rg_rmdir($dir) |
341 |
324 |
*/ |
*/ |
342 |
325 |
function rg_menu_add(&$menu, $sub, $op) |
function rg_menu_add(&$menu, $sub, $op) |
343 |
326 |
{ |
{ |
344 |
|
//rg_log_ml("DEBUG: rg_menu_add (op=$op): " . print_r($sub, TRUE)); |
|
345 |
|
|
|
346 |
327 |
if (isset($sub[$op])) |
if (isset($sub[$op])) |
347 |
328 |
$sub[$op]['active'] = 1; |
$sub[$op]['active'] = 1; |
348 |
329 |
|
|
|
... |
... |
function rg_menu_add(&$menu, $sub, $op) |
352 |
333 |
} |
} |
353 |
334 |
|
|
354 |
335 |
// search for last active menu |
// search for last active menu |
355 |
|
foreach ($menu as $_op => $_info) { |
|
|
336 |
|
foreach ($menu as $_op => &$_info) { |
356 |
337 |
if (!isset($_info['active'])) |
if (!isset($_info['active'])) |
357 |
338 |
continue; |
continue; |
358 |
339 |
|
|
|
... |
... |
function rg_menu_add(&$menu, $sub, $op) |
363 |
344 |
} |
} |
364 |
345 |
|
|
365 |
346 |
// we are on parent of the correct menu |
// we are on parent of the correct menu |
366 |
|
rg_menu_add($menu[$_op], $sub, $op); |
|
|
347 |
|
rg_menu_add($_info['sub'], $sub, $op); |
367 |
348 |
break; |
break; |
368 |
349 |
} |
} |
369 |
350 |
} |
} |
|
... |
... |
function rg_menu_add(&$menu, $sub, $op) |
373 |
354 |
*/ |
*/ |
374 |
355 |
function rg_menu($a, $url, $ui) |
function rg_menu($a, $url, $ui) |
375 |
356 |
{ |
{ |
376 |
|
rg_log_ml("DEBUG: rg_menu: url=$url a=" . print_r($a, TRUE)); |
|
377 |
|
|
|
378 |
|
$ret = array(); |
|
379 |
|
$submenu = array(); |
|
380 |
|
|
|
381 |
|
$menu = "<div class=\"menu\">\n"; |
|
382 |
|
$menu .= "\t<ul>\n"; |
|
|
357 |
|
$menu = array(); |
|
358 |
|
$submenu = ""; |
383 |
359 |
foreach ($a as $_id => $_info) { |
foreach ($a as $_id => $_info) { |
|
360 |
|
$entry = array(); |
|
361 |
|
|
384 |
362 |
// we ignore fake menus like 'home' |
// we ignore fake menus like 'home' |
385 |
363 |
if (!isset($_info['text'])) |
if (!isset($_info['text'])) |
386 |
364 |
continue; |
continue; |
|
... |
... |
function rg_menu($a, $url, $ui) |
394 |
372 |
if (!isset($_info['uid0']) && ($ui['uid'] == 0)) |
if (!isset($_info['uid0']) && ($ui['uid'] == 0)) |
395 |
373 |
continue; |
continue; |
396 |
374 |
|
|
397 |
|
$_text = $_info['text']; |
|
|
375 |
|
$entry['text'] = $_info['text']; |
398 |
376 |
$prefix = empty($url) ? "" : $url . "/"; |
$prefix = empty($url) ? "" : $url . "/"; |
399 |
|
$_url = $prefix . rg_re_url($_info['op']); |
|
400 |
|
//$menu .= "<!-- op=" . $_info['op'] . " url=$_url." . " -->\n"; |
|
|
377 |
|
$menu_url = $prefix . rg_re_url($_info['op']); |
|
378 |
|
$entry['url'] = $menu_url; |
401 |
379 |
|
|
402 |
|
//rg_log("\tDEBUG: compare with [" . $_info['op'] . "]"); |
|
403 |
|
$add = ""; |
|
|
380 |
|
$entry['selected'] = 0; |
404 |
381 |
if (isset($_info['active'])) |
if (isset($_info['active'])) |
405 |
|
$add = " class=\"selected\"";; |
|
406 |
|
$menu .= "\t\t<li><a href=\"" . $_url . "\"" . $add . ">" |
|
407 |
|
. $_text . "</a></li>\n"; |
|
|
382 |
|
$entry['selected'] = 1; |
|
383 |
|
|
|
384 |
|
$menu[] = $entry; |
408 |
385 |
|
|
409 |
386 |
if (!isset($_info['sub']) || (count($_info['sub']) == 0)) |
if (!isset($_info['sub']) || (count($_info['sub']) == 0)) |
410 |
387 |
continue; |
continue; |
411 |
388 |
|
|
412 |
389 |
// submenu |
// submenu |
413 |
|
$submenu = rg_menu($_info['sub'], $_url, $ui); |
|
|
390 |
|
$submenu = rg_menu($_info['sub'], $menu_url, $ui); |
414 |
391 |
} |
} |
415 |
|
$menu .= "\t</ul>\n"; |
|
416 |
|
$menu .= "\t</div>\n"; |
|
417 |
|
$ret[] = $menu; |
|
418 |
392 |
|
|
419 |
|
if (!empty($submenu)) { |
|
420 |
|
foreach ($submenu as $_index => $_menu) |
|
421 |
|
$ret[] = $_menu; |
|
422 |
|
} |
|
|
393 |
|
// Build menu |
|
394 |
|
$ret = rg_template_table("menu", $menu, array()); |
|
395 |
|
$ret .= $submenu; |
423 |
396 |
|
|
424 |
397 |
return $ret; |
return $ret; |
425 |
398 |
} |
} |
|
... |
... |
function rg_menu($a, $url, $ui) |
430 |
403 |
*/ |
*/ |
431 |
404 |
function rg_image_callback($matches) |
function rg_image_callback($matches) |
432 |
405 |
{ |
{ |
433 |
|
global $rg_scripts; |
|
|
406 |
|
global $rg_theme_dir; |
434 |
407 |
global $rg_theme; |
global $rg_theme; |
435 |
408 |
|
|
436 |
409 |
$n = $matches[1]; |
$n = $matches[1]; |
437 |
410 |
$url = "/themes/" . $rg_theme . "/" . $n; |
$url = "/themes/" . $rg_theme . "/" . $n; |
438 |
|
$xfile = $rg_scripts . "/root" . $url; |
|
|
411 |
|
$xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $n; |
439 |
412 |
if (!is_file($xfile)) |
if (!is_file($xfile)) |
440 |
413 |
$url = "/themes/default/" . $n; |
$url = "/themes/default/" . $n; |
441 |
414 |
|
|
|
... |
... |
function rg_image_callback($matches) |
443 |
416 |
} |
} |
444 |
417 |
|
|
445 |
418 |
/* |
/* |
446 |
|
* Prepare an image taking in consideration the them. It will use rg_img as |
|
447 |
|
* callback. |
|
|
419 |
|
* Prepares the images to point to a correct image. |
448 |
420 |
*/ |
*/ |
449 |
421 |
function rg_prepare_image($line) |
function rg_prepare_image($line) |
450 |
422 |
{ |
{ |
|
... |
... |
function rg_prepare_replace(&$data, &$what, &$values) |
457 |
429 |
if (!is_array($data)) |
if (!is_array($data)) |
458 |
430 |
rg_internal_error("invalid type passed"); |
rg_internal_error("invalid type passed"); |
459 |
431 |
foreach ($data as $k => $v) { |
foreach ($data as $k => $v) { |
460 |
|
if (is_array($v)) { |
|
461 |
|
rg_log_ml("value of key [$k] is array!" |
|
|
432 |
|
if (is_array($v)) |
|
433 |
|
rg_fatal("value of key [$k] is array!" |
462 |
434 |
. " data: " . print_r($data, TRUE)); |
. " data: " . print_r($data, TRUE)); |
463 |
|
exit(1); |
|
464 |
|
} |
|
|
435 |
|
|
465 |
436 |
if (strncmp($k, "HTML:", 5) == 0) { |
if (strncmp($k, "HTML:", 5) == 0) { |
466 |
437 |
$k = substr($k, 5); |
$k = substr($k, 5); |
467 |
438 |
} else { |
} else { |
|
... |
... |
function rg_replace_conditionals_block($block, &$data, &$stack) |
555 |
526 |
return FALSE; |
return FALSE; |
556 |
527 |
} |
} |
557 |
528 |
//rg_log("DEBUG: matches2: " . rg_array2string($matches2)); |
//rg_log("DEBUG: matches2: " . rg_array2string($matches2)); |
|
529 |
|
if (count($matches2) < 3) { |
|
530 |
|
rg_internal_error("Cannot match condition."); |
|
531 |
|
return FALSE; |
|
532 |
|
} |
558 |
533 |
$left = rg_replace_lookup($data, trim($matches2[1])); |
$left = rg_replace_lookup($data, trim($matches2[1])); |
559 |
534 |
$op = trim($matches2[2]); |
$op = trim($matches2[2]); |
560 |
535 |
$right = rg_replace_lookup($data, trim($matches2[3])); |
$right = rg_replace_lookup($data, trim($matches2[3])); |
|
... |
... |
function rg_file_get_contents($f) |
648 |
623 |
*/ |
*/ |
649 |
624 |
function rg_template_table($dir, &$data, $more) |
function rg_template_table($dir, &$data, $more) |
650 |
625 |
{ |
{ |
|
626 |
|
global $rg_theme_dir; |
651 |
627 |
global $rg_theme; |
global $rg_theme; |
652 |
|
global $rg_scripts; |
|
653 |
628 |
|
|
654 |
|
$xdir = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $dir; |
|
|
629 |
|
$xdir = $rg_theme_dir . "/" . $rg_theme . "/" . $dir; |
655 |
630 |
if (!is_dir($xdir)) { |
if (!is_dir($xdir)) { |
656 |
631 |
rg_log("$xdir not found."); |
rg_log("$xdir not found."); |
657 |
|
$xdir = $rg_scripts . "/root/themes/default/" . $dir; |
|
|
632 |
|
$xdir = $rg_theme_dir . "/default/" . $dir; |
658 |
633 |
rg_log("Using [$xdir]"); |
rg_log("Using [$xdir]"); |
659 |
634 |
} |
} |
660 |
635 |
|
|
|
... |
... |
function rg_template_table($dir, &$data, $more) |
695 |
670 |
$body .= $between; |
$body .= $between; |
696 |
671 |
} |
} |
697 |
672 |
|
|
698 |
|
$r = rg_replace_conditionals($line, $more); |
|
|
673 |
|
$more2 = array_merge($more, $info); |
|
674 |
|
$r = rg_replace_conditionals($line, $more2); |
699 |
675 |
$body .= preg_replace($what, $values, $r); |
$body .= preg_replace($what, $values, $r); |
700 |
676 |
} |
} |
701 |
677 |
|
|
|
... |
... |
function rg_template_table($dir, &$data, $more) |
704 |
680 |
|
|
705 |
681 |
function rg_template($file, &$data) |
function rg_template($file, &$data) |
706 |
682 |
{ |
{ |
707 |
|
global $rg_scripts; |
|
|
683 |
|
global $rg_theme_dir; |
708 |
684 |
global $rg_theme; |
global $rg_theme; |
709 |
685 |
|
|
710 |
686 |
rg_log("Loading template from $file..."); |
rg_log("Loading template from $file..."); |
711 |
687 |
|
|
712 |
|
$xfile = $rg_scripts . "/root/themes/" . $rg_theme . "/" . $file; |
|
|
688 |
|
$xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $file; |
713 |
689 |
if (!is_file($xfile)) |
if (!is_file($xfile)) |
714 |
|
$xfile = $rg_scripts . "/root/themes/default/" . $file; |
|
|
690 |
|
$xfile = $rg_theme_dir . "/default/" . $file; |
715 |
691 |
|
|
716 |
692 |
$body = rg_file_get_contents($xfile); |
$body = rg_file_get_contents($xfile); |
717 |
693 |
if (empty($body)) { |
if (empty($body)) { |
|
... |
... |
function rg_exec($cmd) |
890 |
866 |
*/ |
*/ |
891 |
867 |
function rg_redirect($url) |
function rg_redirect($url) |
892 |
868 |
{ |
{ |
|
869 |
|
rg_log("Redirecting to [$url]"); |
893 |
870 |
header("Location: $url"); |
header("Location: $url"); |
894 |
871 |
exit(0); |
exit(0); |
895 |
872 |
} |
} |
|
... |
... |
function rg_array2string($a) |
944 |
921 |
} |
} |
945 |
922 |
|
|
946 |
923 |
/* |
/* |
947 |
|
* Load files from a folder |
|
|
924 |
|
* Load files from a folder using a pattern for match |
948 |
925 |
*/ |
*/ |
949 |
|
function rg_dir_load($dir) |
|
|
926 |
|
function rg_dir_load_pattern($dir, $pattern) |
950 |
927 |
{ |
{ |
951 |
|
$ret = array(); |
|
|
928 |
|
$ret = FALSE; |
952 |
929 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
953 |
|
rg_log("$dir does not exists!"); |
|
|
930 |
|
rg_util_set_error("$dir does not exists"); |
954 |
931 |
return $ret; |
return $ret; |
955 |
932 |
} |
} |
956 |
933 |
|
|
957 |
934 |
$d = @scandir($dir); |
$d = @scandir($dir); |
958 |
935 |
if ($d === FALSE) { |
if ($d === FALSE) { |
959 |
|
rg_log("Cannot scan dir $dir ($php_errormsg)."); |
|
|
936 |
|
rg_util_set_error("cannot scan dir $dir ($php_errormsg)"); |
960 |
937 |
return $ret; |
return $ret; |
961 |
938 |
} |
} |
962 |
939 |
|
|
|
940 |
|
$ret = array(); |
963 |
941 |
foreach ($d as $file) { |
foreach ($d as $file) { |
964 |
942 |
if ((strcmp($file, ".") == 0) || (strcmp($file, "..") == 0)) |
if ((strcmp($file, ".") == 0) || (strcmp($file, "..") == 0)) |
965 |
943 |
continue; |
continue; |
966 |
944 |
|
|
|
945 |
|
if (preg_match("/" . $pattern . "/", $file) !== 1) |
|
946 |
|
continue; |
|
947 |
|
|
967 |
948 |
$ret[] = $file; |
$ret[] = $file; |
968 |
949 |
} |
} |
969 |
950 |
|
|
970 |
951 |
return $ret; |
return $ret; |
971 |
952 |
} |
} |
972 |
953 |
|
|
|
954 |
|
/* |
|
955 |
|
* Load all files from a folder |
|
956 |
|
*/ |
|
957 |
|
function rg_dir_load($dir) |
|
958 |
|
{ |
|
959 |
|
return rg_dir_load_pattern($dir, ".*"); |
|
960 |
|
} |
|
961 |
|
|
973 |
962 |
/* |
/* |
974 |
963 |
* Recursive dir load (used for references) |
* Recursive dir load (used for references) |
975 |
964 |
*/ |
*/ |
|
... |
... |
function rg_copy_tree($src, $dst, $mask) |
1039 |
1028 |
*/ |
*/ |
1040 |
1029 |
function rg_error_handler($no, $str, $file, $line) |
function rg_error_handler($no, $str, $file, $line) |
1041 |
1030 |
{ |
{ |
1042 |
|
global $rg_admin_email; |
|
1043 |
|
|
|
1044 |
1031 |
if ($no == 0) |
if ($no == 0) |
1045 |
1032 |
return; |
return; |
1046 |
1033 |
|
|
1047 |
|
$str = str_replace("\n", "\\n", $str); |
|
1048 |
|
|
|
1049 |
1034 |
$msg = "PHP ERROR: $file:$line: $str (errno=$no)"; |
$msg = "PHP ERROR: $file:$line: $str (errno=$no)"; |
1050 |
|
rg_log($msg); |
|
1051 |
|
|
|
1052 |
|
mail("rg_error@embedromix.ro", "PHP ERROR", |
|
1053 |
|
$msg |
|
1054 |
|
. "\n" . rg_log_buffer(), |
|
1055 |
|
"", "-f $rg_admin_email"); |
|
|
1035 |
|
$key = md5($msg); |
|
1036 |
|
rg_error_core($msg); |
1056 |
1037 |
|
|
1057 |
1038 |
if ($no == E_ERROR) |
if ($no == E_ERROR) |
1058 |
1039 |
die(); |
die(); |
1059 |
1040 |
|
|
|
1041 |
|
$rg_error_seen[$key] = 1; |
|
1042 |
|
|
1060 |
1043 |
return FALSE; |
return FALSE; |
1061 |
1044 |
} |
} |
1062 |
1045 |
|
|
1063 |
1046 |
/* |
/* |
1064 |
|
* shutdown function to call fatal errors |
|
|
1047 |
|
* shutdown function to log fatal errors |
1065 |
1048 |
*/ |
*/ |
1066 |
|
function rg_shutdown_error() |
|
|
1049 |
|
function rg_error_shutdown() |
1067 |
1050 |
{ |
{ |
1068 |
1051 |
$a = error_get_last(); |
$a = error_get_last(); |
1069 |
1052 |
if ($a === NULL) |
if ($a === NULL) |
|
... |
... |
function rg_mail($template, $more) |
1140 |
1123 |
|
|
1141 |
1124 |
/* |
/* |
1142 |
1125 |
* Merges an array (a) into another (src), using a namespace |
* Merges an array (a) into another (src), using a namespace |
|
1126 |
|
* Protects modifiers (HTML: etc.). |
1143 |
1127 |
*/ |
*/ |
1144 |
1128 |
function rg_array_merge($src, $namespace, $a) |
function rg_array_merge($src, $namespace, $a) |
1145 |
1129 |
{ |
{ |
|
... |
... |
function rg_array_merge($src, $namespace, $a) |
1148 |
1132 |
if (empty($a)) |
if (empty($a)) |
1149 |
1133 |
return $ret; |
return $ret; |
1150 |
1134 |
|
|
1151 |
|
foreach ($a as $k => $v) |
|
1152 |
|
$ret[$namespace . "." . $k] = $v; |
|
|
1135 |
|
foreach ($a as $k => $v) { |
|
1136 |
|
$t = explode(":", $k, 2); |
|
1137 |
|
if (count($t) == 1) |
|
1138 |
|
$ret[$namespace . "." . $k] = $v; |
|
1139 |
|
else |
|
1140 |
|
$ret[$t[0] . ":" . $namespace . "." . $t[1]] = $v; |
|
1141 |
|
} |
1153 |
1142 |
|
|
1154 |
1143 |
return $ret; |
return $ret; |
1155 |
1144 |
} |
} |
|
... |
... |
function rg_implode($prefix, $a, $postfix) |
1172 |
1161 |
return implode($postfix, $ret); |
return implode($postfix, $ret); |
1173 |
1162 |
} |
} |
1174 |
1163 |
|
|
|
1164 |
|
/* |
|
1165 |
|
* Here we will cache the connections |
|
1166 |
|
*/ |
|
1167 |
|
$rg_socket_cache = array(); |
|
1168 |
|
|
|
1169 |
|
/* |
|
1170 |
|
* Receives buffers and test if @wait string is present. |
|
1171 |
|
* @timeout - in miliseconds |
|
1172 |
|
*/ |
|
1173 |
|
function rg_socket_recv_wait($socket, $wait, $timeout) |
|
1174 |
|
{ |
|
1175 |
|
$ret = FALSE; |
|
1176 |
|
|
|
1177 |
|
if ($timeout === NULL) { |
|
1178 |
|
$tv_sec = NULL; |
|
1179 |
|
$tv_usec = NULL; |
|
1180 |
|
} else { |
|
1181 |
|
$tv_sec = $timeout / 1000; |
|
1182 |
|
$tv_usec = ($timeout % 1000) * 1000; |
|
1183 |
|
} |
|
1184 |
|
|
|
1185 |
|
$ret_buf = ""; |
|
1186 |
|
do { |
|
1187 |
|
$reads = array($socket); $writes = array(); $ex = array(); |
|
1188 |
|
$r = socket_select($reads, $writes, $ex, $tv_sec, $tv_usec); |
|
1189 |
|
if ($r === FALSE) { |
|
1190 |
|
rg_log("Cannot select(" . socket_strerror(socket_last_error()) . ")!"); |
|
1191 |
|
break; |
|
1192 |
|
} |
|
1193 |
|
|
|
1194 |
|
if ($r === 0) { // timeout |
|
1195 |
|
rg_log("Timeout!"); |
|
1196 |
|
break; |
|
1197 |
|
} |
|
1198 |
|
|
|
1199 |
|
if (!in_array($socket, $reads)) { |
|
1200 |
|
rg_log("Select returned > 0 and my socket is not in reads"); |
|
1201 |
|
break; |
|
1202 |
|
} |
|
1203 |
|
|
|
1204 |
|
$r = socket_recv($socket, $buf, 32 * 4096, 0); |
|
1205 |
|
if ($r === FALSE) { |
|
1206 |
|
rg_log("Cannot receive(" . socket_strerror(socket_last_error()) . ")!"); |
|
1207 |
|
break; |
|
1208 |
|
} |
|
1209 |
|
rg_log("Received [$buf]"); |
|
1210 |
|
$ret_buf .= $buf; |
|
1211 |
|
|
|
1212 |
|
$pos = strpos($buf, $wait); |
|
1213 |
|
if ($pos !== FALSE) { |
|
1214 |
|
$ret = $ret_buf; |
|
1215 |
|
break; |
|
1216 |
|
} |
|
1217 |
|
} while (0); |
|
1218 |
|
|
|
1219 |
|
return $ret; |
|
1220 |
|
} |
|
1221 |
|
|
|
1222 |
|
/* |
|
1223 |
|
* Sends a full buffer |
|
1224 |
|
* TODO: Take timeout in consideration. |
|
1225 |
|
*/ |
|
1226 |
|
function rg_socket_send($socket, $buf) |
|
1227 |
|
{ |
|
1228 |
|
$ret = FALSE; |
|
1229 |
|
$len = strlen($buf); |
|
1230 |
|
$off = 0; |
|
1231 |
|
while (1) { |
|
1232 |
|
$r = socket_send($socket, substr($buf, $off), $len - $off, 0); |
|
1233 |
|
if ($r === FALSE) { |
|
1234 |
|
rg_log("Could not send (" . socket_strerror(socket_last_error()) . ")!"); |
|
1235 |
|
break; |
|
1236 |
|
} |
|
1237 |
|
rg_log("Sent $r bytes (" . substr($buf, $off, $r) . ")."); |
|
1238 |
|
|
|
1239 |
|
$len -= $r; $off += $r; |
|
1240 |
|
if ($len == 0) { |
|
1241 |
|
$ret = TRUE; |
|
1242 |
|
break; |
|
1243 |
|
} |
|
1244 |
|
} |
|
1245 |
|
|
|
1246 |
|
return $ret; |
|
1247 |
|
} |
|
1248 |
|
|
|
1249 |
|
/* |
|
1250 |
|
* Connects to a socket, send @buf and returns the answer. |
|
1251 |
|
* If timeout is 0, we do not wait for an answer. If is NULL, we wait forever. |
|
1252 |
|
* Else, wait the number of miliseconds. |
|
1253 |
|
*/ |
|
1254 |
|
function rg_socket($path, $buf, $timeout) |
|
1255 |
|
{ |
|
1256 |
|
global $rg_socket_cache; |
|
1257 |
|
|
|
1258 |
|
rg_prof_start("socket"); |
|
1259 |
|
|
|
1260 |
|
$ret = FALSE; |
|
1261 |
|
do { |
|
1262 |
|
if (isset($rg_socket_cache[$path])) { |
|
1263 |
|
$socket = $rg_socket_cache[$path]; |
|
1264 |
|
} else { |
|
1265 |
|
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0); |
|
1266 |
|
if ($socket === FALSE) { |
|
1267 |
|
rg_log("Could not create socket (" . socket_strerror(socket_last_error()) . ")!"); |
|
1268 |
|
break; |
|
1269 |
|
} |
|
1270 |
|
|
|
1271 |
|
// try 3 times |
|
1272 |
|
$tries = 3; |
|
1273 |
|
while ($tries > 0) { |
|
1274 |
|
$r = socket_connect($socket, $path); |
|
1275 |
|
if ($r === FALSE) { |
|
1276 |
|
$tries--; |
|
1277 |
|
usleep(200000); |
|
1278 |
|
continue; |
|
1279 |
|
} |
|
1280 |
|
|
|
1281 |
|
break; |
|
1282 |
|
} |
|
1283 |
|
if ($r === FALSE) { |
|
1284 |
|
rg_log("Could not connect the socket (" . socket_strerror(socket_last_error()) . ")!"); |
|
1285 |
|
break; |
|
1286 |
|
} |
|
1287 |
|
|
|
1288 |
|
$rg_socket_cache[$path] = $socket; |
|
1289 |
|
} |
|
1290 |
|
|
|
1291 |
|
$r = rg_socket_send($socket, $buf); |
|
1292 |
|
if ($r !== TRUE) |
|
1293 |
|
break; |
|
1294 |
|
|
|
1295 |
|
if ($timeout == 0) { |
|
1296 |
|
rg_log("We do not have to wait. Exit."); |
|
1297 |
|
$ret = ""; |
|
1298 |
|
break; |
|
1299 |
|
} |
|
1300 |
|
|
|
1301 |
|
$ret = rg_socket_recv_wait($socket, "\n", $timeout); |
|
1302 |
|
} while (0); |
|
1303 |
|
|
|
1304 |
|
rg_prof_end("socket"); |
|
1305 |
|
return $ret; |
|
1306 |
|
} |
|
1307 |
|
|
1175 |
1308 |
?> |
?> |
File scripts/cache.php changed (mode: 100644) (index 9ee3448..c8279d6) |
4 |
4 |
// It will receive signals using a UNIX socket. |
// It will receive signals using a UNIX socket. |
5 |
5 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
6 |
6 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
|
7 |
|
set_time_limit(0); |
7 |
8 |
|
|
8 |
9 |
// Increment this if we need to restart this daemon (protocol changes etc.) |
// Increment this if we need to restart this daemon (protocol changes etc.) |
9 |
|
$rg_cache_version = 1; |
|
|
10 |
|
$rg_cache_version = 35; |
10 |
11 |
|
|
11 |
12 |
$now = time(); |
$now = time(); |
12 |
13 |
$_s = microtime(TRUE); |
$_s = microtime(TRUE); |
|
... |
... |
require_once($INC . "/init.inc.php"); |
18 |
19 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
19 |
20 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
20 |
21 |
require_once($INC . "/struct.inc.php"); |
require_once($INC . "/struct.inc.php"); |
21 |
|
require_once($INC . "/events.inc.php"); |
|
|
22 |
|
require_once($INC . "/cache.inc.php"); |
22 |
23 |
require_once($INC . "/repo.inc.php"); |
require_once($INC . "/repo.inc.php"); |
23 |
24 |
require_once($INC . "/prof.inc.php"); |
require_once($INC . "/prof.inc.php"); |
24 |
25 |
require_once($INC . "/mr.inc.php"); |
require_once($INC . "/mr.inc.php"); |
|
... |
... |
require_once($INC . "/keys.inc.php"); |
26 |
27 |
require_once($INC . "/user.inc.php"); |
require_once($INC . "/user.inc.php"); |
27 |
28 |
require_once($INC . "/bug.inc.php"); |
require_once($INC . "/bug.inc.php"); |
28 |
29 |
require_once($INC . "/fixes.inc.php"); |
require_once($INC . "/fixes.inc.php"); |
|
30 |
|
require_once($INC . "/ver.php"); |
|
31 |
|
|
|
32 |
|
function rg_destroy($k, &$conn_table) |
|
33 |
|
{ |
|
34 |
|
if (isset($conn_table['r'][$k])) |
|
35 |
|
unset($conn_table['r'][$k]); |
|
36 |
|
if (isset($conn_table['w'][$k])) |
|
37 |
|
unset($conn_table['w'][$k]); |
|
38 |
|
// TODO: seems socket is already closed |
|
39 |
|
if (is_resource($conn_table['conns'][$k]['socket'])) |
|
40 |
|
socket_close($conn_table['conns'][$k]['socket']); |
|
41 |
|
unset($conn_table['conns'][$k]); |
|
42 |
|
} |
|
43 |
|
|
|
44 |
|
function rg_handle_command($k, &$conn_table, $cmd) |
|
45 |
|
{ |
|
46 |
|
rg_log("rg_handle_command: k=$k, cmd=$cmd"); |
|
47 |
|
|
|
48 |
|
$s = &$conn_table['conns'][$k]; |
|
49 |
|
|
|
50 |
|
$a = explode(" ", $cmd, 2); |
|
51 |
|
$buf = "WHAT?!\n"; |
|
52 |
|
do { |
|
53 |
|
if (!isset($a[0])) |
|
54 |
|
break; |
|
55 |
|
|
|
56 |
|
$cmd = trim($a[0]); |
|
57 |
|
|
|
58 |
|
/* here, no parameters */ |
|
59 |
|
|
|
60 |
|
/* From, here, at least 1 para */ |
|
61 |
|
if (!isset($a[1])) |
|
62 |
|
break; |
|
63 |
|
$para1 = trim($a[1]); |
|
64 |
|
|
|
65 |
|
if (strcmp($cmd, "SET") == 0) { |
|
66 |
|
$ns_var_value = explode("=", $para1, 2); |
|
67 |
|
if (!isset($ns_var_value[1])) |
|
68 |
|
break; |
|
69 |
|
$ns_var = trim($ns_var_value[0]); |
|
70 |
|
$value = trim($ns_var_value[1]); |
|
71 |
|
rg_cache_server_set("normal::" . $ns_var, $value); |
|
72 |
|
$buf = "OK\n"; |
|
73 |
|
break; |
|
74 |
|
} |
|
75 |
|
|
|
76 |
|
if (strcmp($cmd, "INC") == 0) { |
|
77 |
|
$v = rg_cache_server_inc("normal::" . $para1); |
|
78 |
|
$buf = "OK v=$v\n"; |
|
79 |
|
break; |
|
80 |
|
} |
|
81 |
|
|
|
82 |
|
if (strcmp($cmd, "GET") == 0) { |
|
83 |
|
$ret = rg_cache_server_get("normal::" . $para1); |
|
84 |
|
if ($ret === FALSE) |
|
85 |
|
$buf = "NOT_FOUND\n"; |
|
86 |
|
else |
|
87 |
|
$buf = "OK " . $ret . "\n"; |
|
88 |
|
break; |
|
89 |
|
} |
|
90 |
|
|
|
91 |
|
if (strcmp($cmd, "UNSET") == 0) { |
|
92 |
|
$ret = rg_cache_server_unset("normal::" . $para1); |
|
93 |
|
if ($ret === FALSE) |
|
94 |
|
$buf = "NOT_FOUND\n"; |
|
95 |
|
else |
|
96 |
|
$buf = "OK\n"; |
|
97 |
|
break; |
|
98 |
|
} |
|
99 |
|
|
|
100 |
|
if (strcmp($cmd, "ADUMP") == 0) { |
|
101 |
|
$ret = rg_cache_server_adump("normal::" . $para1); |
|
102 |
|
if ($ret === FALSE) |
|
103 |
|
$buf = "NOT_FOUND\n"; |
|
104 |
|
else |
|
105 |
|
$buf = "OK " . $ret . "\n"; |
|
106 |
|
break; |
|
107 |
|
} |
|
108 |
|
|
|
109 |
|
if (strcmp($cmd, "APUSH") == 0) { |
|
110 |
|
$ns_var_value = explode("=", $para1, 2); |
|
111 |
|
if (!isset($ns_var_value[1])) |
|
112 |
|
break; |
|
113 |
|
$ns_var = trim($ns_var_value[0]); |
|
114 |
|
$value = trim($ns_var_value[1]); |
|
115 |
|
rg_cache_server_apush("normal::" . $ns_var, $value); |
|
116 |
|
$buf = "OK\n"; |
|
117 |
|
break; |
|
118 |
|
} |
|
119 |
|
|
|
120 |
|
if (strcmp($cmd, "APOP") == 0) { |
|
121 |
|
$ret = rg_cache_server_apop("normal::" . $para1); |
|
122 |
|
if ($ret === FALSE) |
|
123 |
|
$buf = "NOT_FOUND\n"; |
|
124 |
|
else |
|
125 |
|
$buf = "OK " . $ret . "\n"; |
|
126 |
|
break; |
|
127 |
|
} |
|
128 |
|
|
|
129 |
|
if (strcmp($cmd, "ASHIFT") == 0) { |
|
130 |
|
$ret = rg_cache_server_ashift("normal::" . $para1); |
|
131 |
|
if ($ret === FALSE) |
|
132 |
|
$buf = "NOT_FOUND\n"; |
|
133 |
|
else |
|
134 |
|
$buf = "OK " . $ret . "\n"; |
|
135 |
|
break; |
|
136 |
|
} |
|
137 |
|
} while (0); |
|
138 |
|
|
|
139 |
|
$s['send'] .= $buf; |
|
140 |
|
$conn_table['w'][$k] = $s['socket']; |
|
141 |
|
} |
|
142 |
|
|
|
143 |
|
function rg_handle_recv($k, &$conn_table) |
|
144 |
|
{ |
|
145 |
|
$s = &$conn_table['conns'][$k]; |
|
146 |
|
|
|
147 |
|
$ret = @socket_recv($s['socket'], $buf, 32 * 4096, 0); |
|
148 |
|
if ($ret === FALSE) { |
|
149 |
|
rg_log("Error in recv (" . socket_strerror(socket_last_error()) . ")"); |
|
150 |
|
rg_destroy($k, $conn_table); |
|
151 |
|
return; |
|
152 |
|
} |
|
153 |
|
if ($ret === 0) { |
|
154 |
|
//rg_log("Remote closed the connection."); |
|
155 |
|
rg_destroy($k, $conn_table); |
|
156 |
|
return; |
|
157 |
|
} |
|
158 |
|
|
|
159 |
|
rg_log("Received data on key $k [$buf]..."); |
|
160 |
|
|
|
161 |
|
$s['recv'] .= $buf; |
|
162 |
|
$s['close_at'] = time() + 300; |
|
163 |
|
|
|
164 |
|
while (1) { |
|
165 |
|
$pos = strpos($s['recv'], "\n"); |
|
166 |
|
if ($pos === FALSE) |
|
167 |
|
return; |
|
168 |
|
|
|
169 |
|
$cmd = substr($s['recv'], 0, $pos); |
|
170 |
|
$s['recv'] = substr($s['recv'], $pos + 1); |
|
171 |
|
|
|
172 |
|
rg_handle_command($k, $conn_table, $cmd); |
|
173 |
|
}; |
|
174 |
|
} |
|
175 |
|
|
|
176 |
|
function rg_handle_send($k, &$conn_table) |
|
177 |
|
{ |
|
178 |
|
$s = &$conn_table['conns'][$k]; |
|
179 |
|
|
|
180 |
|
rg_log("Sending on key $k [" . $s['send'] . "]..."); |
|
181 |
|
$ret = @socket_send($s['socket'], $s['send'], strlen($s['send']), 0); |
|
182 |
|
if ($ret === FALSE) { |
|
183 |
|
rg_log("Cannot send (" . socket_strerror(socket_last_error()) . ")"); |
|
184 |
|
rg_destroy($k, $conn_table); |
|
185 |
|
return; |
|
186 |
|
} |
|
187 |
|
|
|
188 |
|
$s['send'] = substr($s['send'], $ret); |
|
189 |
|
if (empty($s['send'])) |
|
190 |
|
unset($conn_table['w'][$k]); |
|
191 |
|
} |
|
192 |
|
|
|
193 |
|
function rg_handle_new($client, &$conn_table) |
|
194 |
|
{ |
|
195 |
|
socket_set_nonblock($client); |
|
196 |
|
|
|
197 |
|
$key = intval($client); |
|
198 |
|
$conn_table['conns'][$key] = array( |
|
199 |
|
"socket" => $client, |
|
200 |
|
"recv" => "", |
|
201 |
|
"send" => "", |
|
202 |
|
"close_at" => time() + 300 |
|
203 |
|
); |
|
204 |
|
$conn_table['r'][$key] = $client; |
|
205 |
|
rg_log("Added client with key $key."); |
|
206 |
|
} |
|
207 |
|
|
|
208 |
|
function rg_handle_idle(&$conn_table) |
|
209 |
|
{ |
|
210 |
|
$now = time(); |
|
211 |
|
|
|
212 |
|
foreach ($conn_table['conns'] as $key => $info) { |
|
213 |
|
if (strcmp($key, "master") == 0) |
|
214 |
|
continue; |
|
215 |
|
|
|
216 |
|
if ($info['close_at'] < $now) { |
|
217 |
|
rg_log("Destroy $key because was too much time idle."); |
|
218 |
|
rg_destroy($key, $conn_table); |
|
219 |
|
} |
|
220 |
|
} |
|
221 |
|
} |
|
222 |
|
|
29 |
223 |
|
|
30 |
224 |
rg_prof_start("MAIN"); |
rg_prof_start("MAIN"); |
31 |
225 |
|
|
32 |
226 |
rg_log_set_file($rg_log_dir . "/cache.log"); |
rg_log_set_file($rg_log_dir . "/cache.log"); |
33 |
227 |
rg_log_set_sid("000000"); // to spread the logs |
rg_log_set_sid("000000"); // to spread the logs |
34 |
228 |
|
|
35 |
|
rg_log("Start..."); |
|
36 |
|
|
|
37 |
|
// TODO: really needed db connection? |
|
38 |
|
$db = rg_sql_open($rg_sql); |
|
39 |
|
if ($db === FALSE) { |
|
40 |
|
rg_internal_error("Cannot connect to database!"); |
|
41 |
|
exit(1); |
|
42 |
|
} |
|
|
229 |
|
rg_log("Start (ver=$rocketgit_version)..."); |
43 |
230 |
|
|
44 |
231 |
// Remove the socket, else we will get error |
// Remove the socket, else we will get error |
45 |
232 |
if (file_exists($rg_cache_socket)) |
if (file_exists($rg_cache_socket)) |
46 |
233 |
unlink($rg_cache_socket); |
unlink($rg_cache_socket); |
47 |
234 |
|
|
48 |
|
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0); |
|
49 |
|
if ($socket === FALSE) { |
|
|
235 |
|
$master = socket_create(AF_UNIX, SOCK_STREAM, 0); |
|
236 |
|
if ($master === FALSE) { |
50 |
237 |
rg_internal_error("Cannot create events socket!"); |
rg_internal_error("Cannot create events socket!"); |
51 |
238 |
exit(1); |
exit(1); |
52 |
239 |
} |
} |
53 |
240 |
|
|
54 |
|
$r = socket_bind($socket, $rg_cache_socket); |
|
|
241 |
|
$r = socket_bind($master, $rg_cache_socket); |
55 |
242 |
if ($r === FALSE) { |
if ($r === FALSE) { |
56 |
243 |
rg_internal_error("Cannot bind socket!"); |
rg_internal_error("Cannot bind socket!"); |
57 |
244 |
exit(1); |
exit(1); |
58 |
245 |
} |
} |
59 |
246 |
|
|
60 |
|
$r = socket_listen($socket, 128); |
|
|
247 |
|
$r = socket_listen($master, 128); |
61 |
248 |
if ($r === FALSE) { |
if ($r === FALSE) { |
62 |
249 |
rg_internal_error("Cannot set queue length on socket!"); |
rg_internal_error("Cannot set queue length on socket!"); |
63 |
250 |
exit(1); |
exit(1); |
64 |
251 |
} |
} |
65 |
252 |
|
|
|
253 |
|
socket_set_nonblock($master); |
|
254 |
|
|
66 |
255 |
// Allow apache (at least) to connect to socket |
// Allow apache (at least) to connect to socket |
67 |
256 |
// TODO: this is a security hole. Take care. Hm. How?! |
// TODO: this is a security hole. Take care. Hm. How?! |
68 |
257 |
$r = chmod($rg_cache_socket, 0666); |
$r = chmod($rg_cache_socket, 0666); |
|
... |
... |
if ($r === FALSE) { |
71 |
260 |
exit(1); |
exit(1); |
72 |
261 |
} |
} |
73 |
262 |
|
|
74 |
|
$notify_list = array(); |
|
75 |
|
$r = array(); $w = array(); |
|
76 |
|
$r['master'] = $socket; |
|
|
263 |
|
$conn_table = array("r" => array(), "w" => array(), "conns" => array()); |
|
264 |
|
$conn_table['r']['master'] = $master; |
77 |
265 |
do { |
do { |
78 |
266 |
$new_ver = file_get_contents(__FILE__); |
$new_ver = file_get_contents(__FILE__); |
79 |
267 |
$new_ver = preg_match("/rg_cache_version = (.*);/", $new_ver, $matches); |
$new_ver = preg_match("/rg_cache_version = (.*);/", $new_ver, $matches); |
|
... |
... |
do { |
85 |
273 |
|
|
86 |
274 |
rg_log_buffer_clear(); |
rg_log_buffer_clear(); |
87 |
275 |
|
|
88 |
|
$r2 = $r; $w2 = $w; $ex = array(); |
|
|
276 |
|
$r2 = $conn_table['r']; $w2 = $conn_table['w']; $ex = array(); |
89 |
277 |
$r = socket_select($r2, $w2, $ex, 5); |
$r = socket_select($r2, $w2, $ex, 5); |
90 |
278 |
if ($r === FALSE) |
if ($r === FALSE) |
91 |
279 |
rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); |
rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); |
92 |
280 |
|
|
93 |
|
rg_log("select returned $r."); |
|
|
281 |
|
//rg_log_ml("conn_table: " . print_r($conn_table, TRUE)); |
94 |
282 |
|
|
95 |
|
print_r($r); exit(0); |
|
96 |
|
foreach ($r as $k) { |
|
97 |
|
} |
|
|
283 |
|
foreach ($r2 as $key => $socket) { |
|
284 |
|
if (strcmp($key, "master") == 0) { |
|
285 |
|
$client = socket_accept($socket); |
|
286 |
|
if ($client === FALSE) { |
|
287 |
|
rg_log("Connection seems broken!"); |
|
288 |
|
continue; |
|
289 |
|
} |
98 |
290 |
|
|
99 |
|
$client = socket_accept($socket); |
|
100 |
|
if ($client === FALSE) { |
|
101 |
|
rg_log("Connection seems broken!"); |
|
102 |
|
continue; |
|
103 |
|
} |
|
104 |
|
|
|
105 |
|
// TODO: this will be used with select |
|
106 |
|
//socket_set_nonblock($client); |
|
107 |
|
|
|
108 |
|
$close = 1; |
|
109 |
|
$r = socket_recv($client, $buf, 1024, 0); |
|
110 |
|
if ($r === 0) { // remote close the connection |
|
111 |
|
rg_log("Remote closed the connection."); |
|
112 |
|
} else if ($r === FALSE) { |
|
113 |
|
$errno = socket_last_error($client); |
|
114 |
|
rg_log("Error in receive (" . socket_strerror($errno) . ")."); |
|
115 |
|
} else { |
|
116 |
|
rg_log("Received $r byte(s): [$buf]."); |
|
117 |
|
if (strncmp($buf, "NOTIFY ", 7) == 0) { |
|
118 |
|
$ev_id = trim(substr($buf, 7)); |
|
119 |
|
$notify_list[$ev_id][] = array("fd" => $client, "itime" => time()); |
|
120 |
|
$close = 0; |
|
121 |
|
|
|
122 |
|
// It is possible that we already executed the task |
|
123 |
|
rg_event_notify($notify_list, $ev_id, ""); |
|
124 |
|
} else if (strncmp($buf, "SET ", 4) == 0) { |
|
125 |
|
$_t = explode("=", substr($buf, 4), 2); |
|
126 |
|
$ns_var = trim($_t[0]); |
|
127 |
|
$value = trim($_t[1]); |
|
128 |
|
$_t = explode("::", $ns_var, 2); |
|
129 |
|
$ns = trim($_t[0]); |
|
130 |
|
$var = trim($_t[1]); |
|
131 |
|
rg_event_set($ns, $var, $value); |
|
132 |
|
rg_event_notify($notify_list, $ns . "::" . $var, $value); |
|
133 |
|
} else if (strncmp($buf, "GET ", 4) == 0) { |
|
134 |
|
$_t = explode("::", substr($buf, 4), 2); |
|
135 |
|
$ns = trim($_t[0]); |
|
136 |
|
$var = trim($_t[1]); |
|
137 |
|
$out = rg_event_get($ns, $var); |
|
138 |
|
if ($out === FALSE) |
|
139 |
|
$out = "NOT_FOUND"; |
|
140 |
|
$r = socket_send($client, $out, strlen($out), 0); |
|
141 |
|
} else if (strncmp($buf, "UNSET ", 6) == 0) { |
|
142 |
|
$_t = explode("::", substr($buf, 6), 2); |
|
143 |
|
$ns = trim($_t[0]); |
|
144 |
|
$var = trim($_t[1]); |
|
145 |
|
rg_event_unset($ns, $var); |
|
146 |
|
$r = socket_send($client, $out, strlen($out), 0); |
|
147 |
|
rg_event_notify($notify_list, $ns . "::" . $var, ""); // TODO: need to signal FALSE |
|
|
291 |
|
rg_handle_new($client, $conn_table); |
|
292 |
|
continue; |
148 |
293 |
} |
} |
|
294 |
|
|
|
295 |
|
rg_handle_recv($key, $conn_table); |
149 |
296 |
} |
} |
150 |
297 |
|
|
151 |
|
if ($close == 1) |
|
152 |
|
socket_close($client); |
|
|
298 |
|
foreach ($w2 as $key => $sock) |
|
299 |
|
rg_handle_send($key, $conn_table); |
153 |
300 |
|
|
154 |
|
// clean up notify_list |
|
155 |
|
rg_event_notify_clean($notify_list); |
|
|
301 |
|
rg_handle_idle($conn_table); |
156 |
302 |
} while (1); |
} while (1); |
157 |
303 |
|
|
158 |
|
socket_close($socket); |
|
|
304 |
|
socket_close($master); |
159 |
305 |
|
|
160 |
306 |
rg_log("Exiting..."); |
rg_log("Exiting..."); |
161 |
307 |
|
|