| File TODO changed (mode: 100644) (index c713968..f4cc376) | 
	| 1 | 
	1 | 
	== Where I stopped last time == | 
	== Where I stopped last time == | 
	| 2 | 
	 | 
	[ ] admin_delete_rights::delete, was not protected against csrf/ua! | 
	 | 
	| 3 | 
	 | 
		Other places? Use a unit test for this stuff? | 
	 | 
	| 4 | 
	 | 
	[ ] Seems I do not insert a history item on repo creation! | 
	 | 
	| 5 | 
	 | 
	[ ] Bugs caching page is not working anymore (after NO_WAIT changes) | 
	 | 
	| 6 | 
	 | 
		Seems I regenerate the CSRF tokens! | 
	 | 
	| 7 | 
	 | 
	[ ] tests are failing! | 
	 | 
	| 8 | 
	2 | 
	[ ]  | 
	[ ]  | 
	| 9 | 
	3 | 
	 | 
	 | 
	 | 
	4 | 
	 | 
	 | 
	| 10 | 
	5 | 
	== CSRF logic == | 
	== CSRF logic == | 
	| 11 | 
	6 | 
	- Generate a token for a specific form (call rg_token_get with an $op) | 
	- Generate a token for a specific form (call rg_token_get with an $op) | 
	| 12 | 
	7 | 
	Why I do not use a key per user not a master key?! Maybe because I have | 
	Why I do not use a key per user not a master key?! Maybe because I have | 
|   | 
	| ... | 
	... | 
	to store it in db. Why not? Because of caching of the pages... | 
	| 21 | 
	16 | 
		 | 
		 | 
	| 22 | 
	17 | 
	 | 
	 | 
	| 23 | 
	18 | 
	== BEFORE NEXT RELEASE == | 
	== BEFORE NEXT RELEASE == | 
	 | 
	19 | 
	 | 
	[ ] Prefetch of varibles from cache | 
	 | 
	20 | 
	 | 
		Take care of non-existing vars in cache. | 
	 | 
	21 | 
	 | 
		First candidate: first_install. | 
	 | 
	22 | 
	 | 
	[ ] Seems I do not insert a history item on repo creation! | 
	 | 
	23 | 
	 | 
	[ ] admin_delete_rights::delete, was not protected against csrf/ua! | 
	 | 
	24 | 
	 | 
		Other places? Use a unit test for this stuff? | 
	 | 
	25 | 
	 | 
	[ ] When building VM, automatically add a snapshot, so user can go back. | 
	| 24 | 
	26 | 
	[ ] Some rg_cache_unset may trigger an error. Case by case we have to | 
	[ ] Some rg_cache_unset may trigger an error. Case by case we have to | 
	| 25 | 
	27 | 
		analyze the impact. We may want to give an error to the user. | 
		analyze the impact. We may want to give an error to the user. | 
	| 26 | 
	28 | 
		I am thinking at tokens. Maybe we do ot want to mark it as used in | 
		I am thinking at tokens. Maybe we do ot want to mark it as used in | 
| File inc/cache.inc.php changed (mode: 100644) (index 2fece33..5702ab5) | 
	| ... | 
	... | 
	function rg_cache_core_merge($ns_var, $list) | 
	| 82 | 
	82 | 
		$t = explode("::", $ns_var); | 
		$t = explode("::", $ns_var); | 
	| 83 | 
	83 | 
		foreach ($t as $token) { | 
		foreach ($t as $token) { | 
	| 84 | 
	84 | 
			if (!isset($tree[$token])) | 
			if (!isset($tree[$token])) | 
	| 85 | 
	 | 
				$tree[$token] = array(); | 
	 | 
	 | 
	85 | 
	 | 
				return FALSE; | 
	| 86 | 
	86 | 
	 | 
	 | 
	| 87 | 
	87 | 
			$tree = &$tree[$token]; | 
			$tree = &$tree[$token]; | 
	| 88 | 
	88 | 
		} | 
		} | 
	| 89 | 
	89 | 
	 | 
	 | 
	| 90 | 
	90 | 
		foreach ($list as $k => $v) | 
		foreach ($list as $k => $v) | 
	| 91 | 
	91 | 
			$tree[$k] = $v; | 
			$tree[$k] = $v; | 
	 | 
	92 | 
	 | 
	 | 
	 | 
	93 | 
	 | 
		return TRUE; | 
	| 92 | 
	94 | 
	} | 
	} | 
	| 93 | 
	95 | 
	 | 
	 | 
	| 94 | 
	96 | 
	/* | 
	/* | 
|   | 
	| ... | 
	... | 
	function rg_cache_unset($ns_var, $flags) | 
	| 498 | 
	500 | 
	/* | 
	/* | 
	| 499 | 
	501 | 
	 * Merge some k=v pairs into an existing cache | 
	 * Merge some k=v pairs into an existing cache | 
	| 500 | 
	502 | 
	 */ | 
	 */ | 
	| 501 | 
	 | 
	function rg_cache_merge($ns_var, $list) | 
	 | 
	 | 
	503 | 
	 | 
	function rg_cache_merge($ns_var, $list, $flags) | 
	| 502 | 
	504 | 
	{ | 
	{ | 
	| 503 | 
	505 | 
		global $rg_cache_socket; | 
		global $rg_cache_socket; | 
	| 504 | 
	506 | 
		global $rg_cache_timeout; | 
		global $rg_cache_timeout; | 
|   | 
	| ... | 
	... | 
	function rg_cache_merge($ns_var, $list) | 
	| 507 | 
	509 | 
	 | 
	 | 
	| 508 | 
	510 | 
		rg_prof_start("cache_merge"); | 
		rg_prof_start("cache_merge"); | 
	| 509 | 
	511 | 
		if ($rg_cache_debug) | 
		if ($rg_cache_debug) | 
	| 510 | 
	 | 
			rg_log_ml_enter("cache_merge: $ns_var = " . print_r($list, TRUE)); | 
	 | 
	 | 
	512 | 
	 | 
			rg_log_ml_enter("cache_merge: flags=$flags" | 
	 | 
	513 | 
	 | 
				. " $ns_var = " . print_r($list, TRUE)); | 
	| 511 | 
	514 | 
	 | 
	 | 
	| 512 | 
	515 | 
		$ret = FALSE; | 
		$ret = FALSE; | 
	| 513 | 
	516 | 
		while (1) { | 
		while (1) { | 
|   | 
	| ... | 
	... | 
	function rg_cache_merge($ns_var, $list) | 
	| 516 | 
	519 | 
			if ($rg_cache_enable === FALSE) | 
			if ($rg_cache_enable === FALSE) | 
	| 517 | 
	520 | 
				break; | 
				break; | 
	| 518 | 
	521 | 
	 | 
	 | 
	| 519 | 
	 | 
			$c = rg_socket($rg_cache_socket, "MERGE F= " . $ns_var . "=" | 
	 | 
	| 520 | 
	 | 
				. rg_cache_prepare($list) . "\n", $rg_cache_timeout, 1, 0); | 
	 | 
	 | 
	522 | 
	 | 
			$f = ''; | 
	 | 
	523 | 
	 | 
			if ($flags & RG_SOCKET_NO_WAIT) | 
	 | 
	524 | 
	 | 
				$f .= 'W'; | 
	 | 
	525 | 
	 | 
	 | 
	 | 
	526 | 
	 | 
			$c = rg_socket($rg_cache_socket, "MERGE F=$f " . $ns_var . "=" | 
	 | 
	527 | 
	 | 
				. rg_cache_prepare($list) . "\n", $rg_cache_timeout, | 
	 | 
	528 | 
	 | 
				1, $flags); | 
	| 521 | 
	529 | 
			if ($c === FALSE) | 
			if ($c === FALSE) | 
	| 522 | 
	530 | 
				break; | 
				break; | 
	| 523 | 
	531 | 
	 | 
	 | 
	 | 
	532 | 
	 | 
			if ($flags & RG_SOCKET_NO_WAIT) { | 
	 | 
	533 | 
	 | 
				$ret = TRUE; | 
	 | 
	534 | 
	 | 
				break; | 
	 | 
	535 | 
	 | 
			} | 
	 | 
	536 | 
	 | 
	 | 
	| 524 | 
	537 | 
			if (strncmp($c, "OK", 2) != 0) | 
			if (strncmp($c, "OK", 2) != 0) | 
	| 525 | 
	538 | 
				break; | 
				break; | 
	| 526 | 
	539 | 
	 | 
	 | 
| File inc/user.inc.php changed (mode: 100644) (index 921d99d..351bbf7) | 
	| ... | 
	... | 
	function rg_user_edit($db, $d) | 
	| 442 | 
	442 | 
				} | 
				} | 
	| 443 | 
	443 | 
			} | 
			} | 
	| 444 | 
	444 | 
	 | 
	 | 
	| 445 | 
	 | 
			$now = time(); | 
	 | 
	 | 
	445 | 
	 | 
			$d['itime'] = time(); | 
	| 446 | 
	446 | 
			$d['salt'] = rg_id(40); | 
			$d['salt'] = rg_id(40); | 
	| 447 | 
	447 | 
			$d['pass_crypted'] = rg_user_pass($d['salt'], $d['pass']); | 
			$d['pass_crypted'] = rg_user_pass($d['salt'], $d['pass']); | 
	| 448 | 
	448 | 
	 | 
	 | 
	| 449 | 
	 | 
			$params = array("username" => $d['username'], | 
	 | 
	| 450 | 
	 | 
				"realname" => $d['realname'], | 
	 | 
	| 451 | 
	 | 
				"salt" => $d['salt'], | 
	 | 
	| 452 | 
	 | 
				"pass_crypted" => $d['pass_crypted'], | 
	 | 
	| 453 | 
	 | 
				"email" => $d['email'], | 
	 | 
	| 454 | 
	 | 
				"now" => $now, | 
	 | 
	| 455 | 
	 | 
				"is_admin" => $d['is_admin'], | 
	 | 
	| 456 | 
	 | 
				"rights" => $d['rights'], | 
	 | 
	| 457 | 
	 | 
				"session_time" => $d['session_time'], | 
	 | 
	| 458 | 
	 | 
				"confirmed" => $confirmed, | 
	 | 
	| 459 | 
	 | 
				"confirm_token" => $d['confirm_token'], | 
	 | 
	| 460 | 
	 | 
				"plan_id" => $d['plan_id'], | 
	 | 
	| 461 | 
	 | 
				"uid" => $d['uid']); | 
	 | 
	| 462 | 
	 | 
	 | 
	 | 
	| 463 | 
	449 | 
			if ($d['uid'] == 0) { // add | 
			if ($d['uid'] == 0) { // add | 
	| 464 | 
	450 | 
				if (rg_user_pass_ok($d['pass']) !== TRUE) | 
				if (rg_user_pass_ok($d['pass']) !== TRUE) | 
	| 465 | 
	451 | 
					break; | 
					break; | 
|   | 
	| ... | 
	... | 
	function rg_user_edit($db, $d) | 
	| 469 | 
	455 | 
					. ", is_admin, rights, session_time" | 
					. ", is_admin, rights, session_time" | 
	| 470 | 
	456 | 
					. ", confirmed, confirm_token, plan_id)" | 
					. ", confirmed, confirm_token, plan_id)" | 
	| 471 | 
	457 | 
					. " VALUES (@@username@@, @@realname@@, @@salt@@" | 
					. " VALUES (@@username@@, @@realname@@, @@salt@@" | 
	| 472 | 
	 | 
					. ", @@pass_crypted@@, @@email@@, @@now@@" | 
	 | 
	 | 
	458 | 
	 | 
					. ", @@pass_crypted@@, @@email@@, @@itime@@" | 
	| 473 | 
	459 | 
					. ", @@is_admin@@, @@rights@@, @@session_time@@" | 
					. ", @@is_admin@@, @@rights@@, @@session_time@@" | 
	| 474 | 
	460 | 
					. ", @@confirmed@@, @@confirm_token@@, @@plan_id@@)" | 
					. ", @@confirmed@@, @@confirm_token@@, @@plan_id@@)" | 
	| 475 | 
	461 | 
					. " RETURNING uid"; | 
					. " RETURNING uid"; | 
	| 476 | 
	462 | 
			} else { // edit | 
			} else { // edit | 
	| 477 | 
	463 | 
				$salt_pass_add = ""; | 
				$salt_pass_add = ""; | 
	| 478 | 
	464 | 
				if (!empty($d['pass'])) { | 
				if (!empty($d['pass'])) { | 
	| 479 | 
	 | 
					$params['pass_crtypted'] = $d['pass_crypted']; | 
	 | 
	| 480 | 
	 | 
					$params['salt'] = $d['salt']; | 
	 | 
	| 481 | 
	465 | 
					$salt_pass_add = ", pass = @@pass_crypted@@" | 
					$salt_pass_add = ", pass = @@pass_crypted@@" | 
	| 482 | 
	466 | 
						. ", salt = @@salt@@"; | 
						. ", salt = @@salt@@"; | 
	| 483 | 
	467 | 
				} | 
				} | 
|   | 
	| ... | 
	... | 
	function rg_user_edit($db, $d) | 
	| 495 | 
	479 | 
					. " RETURNING uid"; | 
					. " RETURNING uid"; | 
	| 496 | 
	480 | 
			} | 
			} | 
	| 497 | 
	481 | 
	 | 
	 | 
	| 498 | 
	 | 
			$res = rg_sql_query_params($db, $sql, $params); | 
	 | 
	 | 
	482 | 
	 | 
			$res = rg_sql_query_params($db, $sql, $d); | 
	| 499 | 
	483 | 
			if ($res === FALSE) { | 
			if ($res === FALSE) { | 
	| 500 | 
	484 | 
				rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); | 
				rg_user_set_error("cannot insert/update user (" . rg_sql_error() . ")"); | 
	| 501 | 
	485 | 
				break; | 
				break; | 
|   | 
	| ... | 
	... | 
	function rg_user_edit($db, $d) | 
	| 503 | 
	487 | 
			$row = rg_sql_fetch_array($res); | 
			$row = rg_sql_fetch_array($res); | 
	| 504 | 
	488 | 
			rg_sql_free_result($res); | 
			rg_sql_free_result($res); | 
	| 505 | 
	489 | 
	 | 
	 | 
	| 506 | 
	 | 
			// invalidate cache (because we may not have the password) | 
	 | 
	| 507 | 
	 | 
			// TODO: but, we can do a merge! | 
	 | 
	| 508 | 
	 | 
			if ($d['uid'] > 0) | 
	 | 
	| 509 | 
	 | 
				rg_cache_unset('user::' . $d['uid'], RG_SOCKET_NO_WAIT); | 
	 | 
	| 510 | 
	 | 
	 | 
	 | 
	| 511 | 
	490 | 
			if ($d['uid'] == 0) { // add | 
			if ($d['uid'] == 0) { // add | 
	 | 
	491 | 
	 | 
				rg_cache_set('user::' . $d['uid'], $d, RG_SOCKET_NO_WAIT); | 
	 | 
	492 | 
	 | 
	 | 
	| 512 | 
	493 | 
				$event = array('category' => 2000, 'prio' => 50, | 
				$event = array('category' => 2000, 'prio' => 50, | 
	| 513 | 
	494 | 
					'ui' => array( | 
					'ui' => array( | 
	| 514 | 
	495 | 
						'uid' => $row['uid'], | 
						'uid' => $row['uid'], | 
|   | 
	| ... | 
	... | 
	function rg_user_edit($db, $d) | 
	| 525 | 
	506 | 
					break; | 
					break; | 
	| 526 | 
	507 | 
				} | 
				} | 
	| 527 | 
	508 | 
				rg_event_signal_daemon("", 0); | 
				rg_event_signal_daemon("", 0); | 
	 | 
	509 | 
	 | 
			} else { // edit | 
	 | 
	510 | 
	 | 
				rg_cache_merge('user::' . $d['uid'], $d, RG_SOCKET_NO_WAIT); | 
	| 528 | 
	511 | 
			} | 
			} | 
	| 529 | 
	512 | 
	 | 
	 | 
	| 530 | 
	513 | 
			// TODO: should we cache here the user_by_uid and user_by_name | 
			// TODO: should we cache here the user_by_uid and user_by_name | 
|   | 
	| ... | 
	... | 
	function rg_user_set_last_seen($db, $uid) | 
	| 691 | 
	674 | 
			} | 
			} | 
	| 692 | 
	675 | 
			rg_sql_free_result($res); | 
			rg_sql_free_result($res); | 
	| 693 | 
	676 | 
	 | 
	 | 
	| 694 | 
	 | 
			rg_cache_merge("user::" . $uid, $params); | 
	 | 
	 | 
	677 | 
	 | 
			rg_cache_merge("user::" . $uid, $params, RG_SOCKET_NO_WAIT); | 
	| 695 | 
	678 | 
	 | 
	 | 
	| 696 | 
	679 | 
			$ret = TRUE; | 
			$ret = TRUE; | 
	| 697 | 
	680 | 
			break; | 
			break; | 
|   | 
	| ... | 
	... | 
	function rg_user_set_pass($db, $uid, $pass) | 
	| 1281 | 
	1264 | 
			} | 
			} | 
	| 1282 | 
	1265 | 
			rg_sql_free_result($res); | 
			rg_sql_free_result($res); | 
	| 1283 | 
	1266 | 
	 | 
	 | 
	| 1284 | 
	 | 
			// Because we may not have info about the user in cache, | 
	 | 
	| 1285 | 
	 | 
			// we cannot do a merge. | 
	 | 
	| 1286 | 
	 | 
			rg_cache_unset('user::' . $uid, RG_SOCKET_NO_WAIT); | 
	 | 
	 | 
	1267 | 
	 | 
			rg_cache_merge('user::' . $uid, $params, RG_SOCKET_NO_WAIT); | 
	| 1287 | 
	1268 | 
	 | 
	 | 
	| 1288 | 
	1269 | 
			$ret = TRUE; | 
			$ret = TRUE; | 
	| 1289 | 
	1270 | 
			break; | 
			break; | 
|   | 
	| ... | 
	... | 
	function rg_user_confirm($db, $token) | 
	| 1330 | 
	1311 | 
			$uid = $row['uid']; | 
			$uid = $row['uid']; | 
	| 1331 | 
	1312 | 
	 | 
	 | 
	| 1332 | 
	1313 | 
			// "< 2" because we mark with "1" if "no need to confirm" | 
			// "< 2" because we mark with "1" if "no need to confirm" | 
	| 1333 | 
	 | 
			$params = array("now" => $now, "uid" => $uid); | 
	 | 
	| 1334 | 
	 | 
			$sql = "UPDATE users SET confirmed = @@now@@" | 
	 | 
	 | 
	1314 | 
	 | 
			$params = array("confirmed" => $now, "uid" => $uid); | 
	 | 
	1315 | 
	 | 
			$sql = "UPDATE users SET confirmed = @@confirmed@@" | 
	| 1335 | 
	1316 | 
				. " WHERE uid = @@uid@@" | 
				. " WHERE uid = @@uid@@" | 
	| 1336 | 
	1317 | 
				. " AND confirmed < 2"; | 
				. " AND confirmed < 2"; | 
	| 1337 | 
	1318 | 
			$res = rg_sql_query_params($db, $sql, $params); | 
			$res = rg_sql_query_params($db, $sql, $params); | 
|   | 
	| ... | 
	... | 
	function rg_user_confirm($db, $token) | 
	| 1341 | 
	1322 | 
			} | 
			} | 
	| 1342 | 
	1323 | 
			rg_sql_free_result($res); | 
			rg_sql_free_result($res); | 
	| 1343 | 
	1324 | 
	 | 
	 | 
	| 1344 | 
	 | 
			rg_cache_unset('user::' . $uid, RG_SOCKET_NO_WAIT); | 
	 | 
	 | 
	1325 | 
	 | 
			rg_cache_merge('user::' . $uid, $params, RG_SOCKET_NO_WAIT); | 
	| 1345 | 
	1326 | 
	 | 
	 | 
	| 1346 | 
	1327 | 
			$ret = $uid; | 
			$ret = $uid; | 
	| 1347 | 
	1328 | 
			break; | 
			break; | 
| File inc/user/repo-page.php changed (mode: 100644) (index 90ae5c1..1382e1c) | 
	| ... | 
	... | 
	if (strcmp($_subop, "history") == 0) { | 
	| 177 | 
	177 | 
				// find treeish of dir | 
				// find treeish of dir | 
	| 178 | 
	178 | 
				$_path = implode("/", $paras); | 
				$_path = implode("/", $paras); | 
	| 179 | 
	179 | 
				$rg['path'] = "/" . $_path; | 
				$rg['path'] = "/" . $_path; | 
	| 180 | 
	 | 
				$_tree = rg_git_ls_tree($ref, $_path); | 
	 | 
	 | 
	180 | 
	 | 
				$_tree = rg_git_ls_tree($repo_path, $ref, $_path); | 
	| 181 | 
	181 | 
				if ($_tree === FALSE) { | 
				if ($_tree === FALSE) { | 
	| 182 | 
	182 | 
					$_repo_body .= "Invalid path!"; | 
					$_repo_body .= "Invalid path!"; | 
	| 183 | 
	183 | 
				} else { | 
				} else { | 
	| 184 | 
	184 | 
					$_hash = $_tree[0]['ref']; | 
					$_hash = $_tree[0]['ref']; | 
	| 185 | 
	 | 
					$_tree = rg_git_ls_tree($_hash, ""); | 
	 | 
	 | 
	185 | 
	 | 
					$_tree = rg_git_ls_tree($repo_path, $_hash, ""); | 
	| 186 | 
	186 | 
					$_repo_body .= rg_template_table("repo/tree", | 
					$_repo_body .= rg_template_table("repo/tree", | 
	| 187 | 
	187 | 
						$_tree, $rg); | 
						$_tree, $rg); | 
	| 188 | 
	188 | 
				} | 
				} | 
	| 189 | 
	189 | 
			} else { // default is to show root tree | 
			} else { // default is to show root tree | 
	| 190 | 
	190 | 
				$rg['path'] = ""; | 
				$rg['path'] = ""; | 
	| 191 | 
	 | 
				$_tree = rg_git_ls_tree($ref, ""); | 
	 | 
	 | 
	191 | 
	 | 
				$_tree = rg_git_ls_tree($repo_path, $ref, ""); | 
	| 192 | 
	192 | 
				$_repo_body .= rg_template_table("repo/tree", $_tree, | 
				$_repo_body .= rg_template_table("repo/tree", $_tree, | 
	| 193 | 
	193 | 
					$rg); | 
					$rg); | 
	| 194 | 
	194 | 
			} | 
			} | 
	| 195 | 
	195 | 
		} else { // show the log | 
		} else { // show the log | 
	 | 
	196 | 
	 | 
			// TODO: improve the error report (error or empty?) | 
	| 196 | 
	197 | 
			$log = rg_git_log($repo_path, 10, "", $ref, FALSE); | 
			$log = rg_git_log($repo_path, 10, "", $ref, FALSE); | 
	| 197 | 
	198 | 
			if ($log === FALSE) { | 
			if ($log === FALSE) { | 
	| 198 | 
	 | 
				$_repo_body .= rg_template("repo/not_init.html", $rg, TRUE /* xss */); | 
	 | 
	 | 
	199 | 
	 | 
				$_repo_body .= rg_template("repo/not_init.html", $rg, | 
	 | 
	200 | 
	 | 
					TRUE /*xss*/); | 
	| 199 | 
	201 | 
			} else { | 
			} else { | 
	| 200 | 
	202 | 
				//rg_log_ml("DEBUG: log: " . print_r($log, TRUE)); | 
				//rg_log_ml("DEBUG: log: " . print_r($log, TRUE)); | 
	| 201 | 
	203 | 
				$_repo_body .= rg_git_log_template($log, "repo/log", $rg); | 
				$_repo_body .= rg_git_log_template($log, "repo/log", $rg); |