forked from cory/tildefriends
		
	A brave new world where admin users can use the server identity.
This commit is contained in:
		
							
								
								
									
										21
									
								
								src/ssb.db.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/ssb.db.c
									
									
									
									
									
								
							| @@ -1946,3 +1946,24 @@ bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id) | |||||||
| 	} | 	} | ||||||
| 	return verified; | 	return verified; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, const char* id, const char* permission) | ||||||
|  | { | ||||||
|  | 	bool has_permission = false; | ||||||
|  | 	sqlite3* db = tf_ssb_acquire_db_reader(ssb); | ||||||
|  | 	sqlite3_stmt* statement = NULL; | ||||||
|  | 	if (sqlite3_prepare(db, | ||||||
|  | 			"SELECT COUNT(*) FROM properties, json_each(properties.value -> 'permissions' -> ?) AS permission WHERE properties.id = 'core' AND properties.key = 'settings' AND " | ||||||
|  | 			"permission.value = ?", | ||||||
|  | 			-1, &statement, NULL) == SQLITE_OK) | ||||||
|  | 	{ | ||||||
|  | 		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, permission, -1, NULL) == SQLITE_OK && | ||||||
|  | 			sqlite3_step(statement) == SQLITE_ROW) | ||||||
|  | 		{ | ||||||
|  | 			has_permission = sqlite3_column_int64(statement, 0) > 0; | ||||||
|  | 		} | ||||||
|  | 		sqlite3_finalize(statement); | ||||||
|  | 	} | ||||||
|  | 	tf_ssb_release_db_reader(ssb, db); | ||||||
|  | 	return has_permission; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -416,6 +416,15 @@ void tf_ssb_db_resolve_index_async(tf_ssb_t* ssb, const char* host, void (*callb | |||||||
| */ | */ | ||||||
| bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id); | bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  | ** Check if a user has a specific permission. | ||||||
|  | ** @param ssb The SSB instance. | ||||||
|  | ** @param id The user ID. | ||||||
|  | ** @param permission The name of the permission. | ||||||
|  | ** @return true If the user has the requested permission. | ||||||
|  | */ | ||||||
|  | bool tf_ssb_db_user_has_permission(tf_ssb_t* ssb, const char* id, const char* permission); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| ** An SQLite authorizer callback.  See https://www.sqlite.org/c3ref/set_authorizer.html for use. | ** An SQLite authorizer callback.  See https://www.sqlite.org/c3ref/set_authorizer.html for use. | ||||||
| ** @param user_data User data registered with the authorizer. | ** @param user_data User data registered with the authorizer. | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								src/ssb.js.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/ssb.js.c
									
									
									
									
									
								
							| @@ -381,6 +381,14 @@ static void _tf_ssb_getIdentities_visit(const char* identity, void* user_data) | |||||||
| static void _tf_ssb_get_identities_work(tf_ssb_t* ssb, void* user_data) | static void _tf_ssb_get_identities_work(tf_ssb_t* ssb, void* user_data) | ||||||
| { | { | ||||||
| 	identities_visit_t* work = user_data; | 	identities_visit_t* work = user_data; | ||||||
|  | 	if (tf_ssb_db_user_has_permission(ssb, work->user, "administration")) | ||||||
|  | 	{ | ||||||
|  | 		char id[k_id_base64_len] = ""; | ||||||
|  | 		if (tf_ssb_whoami(ssb, id, sizeof(id))) | ||||||
|  | 		{ | ||||||
|  | 			_tf_ssb_getIdentities_visit(*id == '@' ? id + 1 : id, work); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	tf_ssb_db_identity_visit(ssb, work->user, _tf_ssb_getIdentities_visit, user_data); | 	tf_ssb_db_identity_visit(ssb, work->user, _tf_ssb_getIdentities_visit, user_data); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -445,6 +453,10 @@ static void _tf_ssb_get_private_key_work(tf_ssb_t* ssb, void* user_data) | |||||||
| { | { | ||||||
| 	get_private_key_t* work = user_data; | 	get_private_key_t* work = user_data; | ||||||
| 	work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, work->user, work->id, work->private_key, sizeof(work->private_key)); | 	work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, work->user, work->id, work->private_key, sizeof(work->private_key)); | ||||||
|  | 	if (!work->got_private_key && tf_ssb_db_user_has_permission(ssb, work->user, "administration")) | ||||||
|  | 	{ | ||||||
|  | 		work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, ":admin", work->id, work->private_key, sizeof(work->private_key)); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static void _tf_ssb_get_private_key_after_work(tf_ssb_t* ssb, int status, void* user_data) | static void _tf_ssb_get_private_key_after_work(tf_ssb_t* ssb, int status, void* user_data) | ||||||
| @@ -625,6 +637,14 @@ static void _tf_ssb_getIdentityInfo_visit(const char* identity, void* data) | |||||||
| static void _tf_ssb_getIdentityInfo_work(tf_ssb_t* ssb, void* user_data) | static void _tf_ssb_getIdentityInfo_work(tf_ssb_t* ssb, void* user_data) | ||||||
| { | { | ||||||
| 	identity_info_work_t* request = user_data; | 	identity_info_work_t* request = user_data; | ||||||
|  | 	if (tf_ssb_db_user_has_permission(ssb, request->name, "administration")) | ||||||
|  | 	{ | ||||||
|  | 		char id[k_id_base64_len] = ""; | ||||||
|  | 		if (tf_ssb_whoami(ssb, id, sizeof(id))) | ||||||
|  | 		{ | ||||||
|  | 			_tf_ssb_getIdentityInfo_visit(*id == '@' ? id + 1 : id, request); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	tf_ssb_db_identity_visit(ssb, request->name, _tf_ssb_getIdentityInfo_visit, request); | 	tf_ssb_db_identity_visit(ssb, request->name, _tf_ssb_getIdentityInfo_visit, request); | ||||||
|  |  | ||||||
| 	sqlite3* db = tf_ssb_acquire_db_reader(ssb); | 	sqlite3* db = tf_ssb_acquire_db_reader(ssb); | ||||||
| @@ -777,6 +797,10 @@ static void _tf_ssb_append_message_with_identity_get_key_work(tf_ssb_t* ssb, voi | |||||||
| { | { | ||||||
| 	append_message_t* work = user_data; | 	append_message_t* work = user_data; | ||||||
| 	work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, work->user, work->id, work->private_key, sizeof(work->private_key)); | 	work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, work->user, work->id, work->private_key, sizeof(work->private_key)); | ||||||
|  | 	if (!work->got_private_key && tf_ssb_db_user_has_permission(ssb, work->user, "administration")) | ||||||
|  | 	{ | ||||||
|  | 		work->got_private_key = tf_ssb_db_identity_get_private_key(ssb, ":admin", work->id, work->private_key, sizeof(work->private_key)); | ||||||
|  | 	} | ||||||
| 	tf_ssb_db_get_latest_message_by_author(ssb, work->id, &work->previous_sequence, work->previous_id, sizeof(work->previous_id)); | 	tf_ssb_db_get_latest_message_by_author(ssb, work->id, &work->previous_sequence, work->previous_id, sizeof(work->previous_id)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,6 +25,30 @@ try: | |||||||
| 	#options.add_argument('--headless') | 	#options.add_argument('--headless') | ||||||
| 	driver = webdriver.Firefox(options = options, service = service) | 	driver = webdriver.Firefox(options = options, service = service) | ||||||
| 	wait = WebDriverWait(driver, 10) | 	wait = WebDriverWait(driver, 10) | ||||||
|  |  | ||||||
|  | 	driver.get('http://localhost:8888') | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click() | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click() | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('adminuser') | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('admin_password') | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('admin_password') | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click() | ||||||
|  | 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))) | ||||||
|  | 	driver.switch_to.frame(driver.find_element(By.ID, 'document')) | ||||||
|  | 	wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'identity'))) | ||||||
|  | 	driver.switch_to.default_content() | ||||||
|  |  | ||||||
|  | 	driver.get('http://localhost:8888/~core/admin/') | ||||||
|  | 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))) | ||||||
|  | 	driver.switch_to.frame(driver.find_element(By.ID, 'document')) | ||||||
|  | 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'gs_room_name'))).send_keys('test room') | ||||||
|  | 	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//*[@id="gs_room_name"]/following-sibling::button'))).click() | ||||||
|  | 	driver.switch_to.alert.accept() | ||||||
|  | 	driver.switch_to.default_content() | ||||||
|  |  | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'identity').click() | ||||||
|  | 	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.ID, 'logout').click() | ||||||
|  |  | ||||||
| 	driver.get('http://localhost:8888') | 	driver.get('http://localhost:8888') | ||||||
| 	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click() | 	driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click() | ||||||
| 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click() | 	driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click() | ||||||
| @@ -82,13 +106,6 @@ try: | |||||||
| 	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))) | 	driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))) | ||||||
| 	id1 = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'li'))).text.split(' ')[-1] | 	id1 = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'li'))).text.split(' ')[-1] | ||||||
|  |  | ||||||
| 	driver.get('http://localhost:8888/~core/admin/') |  | ||||||
| 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))) |  | ||||||
| 	driver.switch_to.frame(driver.find_element(By.ID, 'document')) |  | ||||||
| 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'gs_room_name'))).send_keys('test room') |  | ||||||
| 	wait.until(expected_conditions.presence_of_element_located((By.XPATH, '//*[@id="gs_room_name"]/following-sibling::button'))).click() |  | ||||||
| 	driver.switch_to.alert.accept() |  | ||||||
|  |  | ||||||
| 	driver.get('http://localhost:8888') | 	driver.get('http://localhost:8888') | ||||||
| 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))) | 	wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))) | ||||||
| 	driver.switch_to.frame(driver.find_element(By.ID, 'document')) | 	driver.switch_to.frame(driver.find_element(By.ID, 'document')) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user