mirror of
				https://github.com/scottlamb/moonfire-nvr.git
				synced 2025-10-30 00:05:03 -04:00 
			
		
		
		
	support username properly in POST /api/users/:id
I mistakenly left this out. Also, fix the behavior if something is forgotten. Before, it'd silently ignore it. Now, it correctly returns Unimplemented, in both POST /api/users/:id and PUT /api/users.
This commit is contained in:
		
							parent
							
								
									6c90077ff1
								
							
						
					
					
						commit
						163eaa4cf9
					
				| @ -516,14 +516,16 @@ pub struct ToplevelUser { | |||||||
| 
 | 
 | ||||||
| #[derive(Debug, Deserialize)] | #[derive(Debug, Deserialize)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
|  | #[serde(deny_unknown_fields)] | ||||||
| pub struct PostUser<'a> { | pub struct PostUser<'a> { | ||||||
|     pub csrf: Option<&'a str>, |     pub csrf: Option<&'a str>, | ||||||
|     pub update: Option<UserSubset<'a>>, |     pub update: Option<UserSubset<'a>>, | ||||||
|     pub precondition: Option<UserSubset<'a>>, |     pub precondition: Option<UserSubset<'a>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Deserialize, Serialize)] | #[derive(Debug, Default, Deserialize, Serialize, PartialEq, Eq)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
|  | #[serde(deny_unknown_fields)] | ||||||
| pub struct UserSubset<'a> { | pub struct UserSubset<'a> { | ||||||
|     #[serde(borrow)] |     #[serde(borrow)] | ||||||
|     pub username: Option<&'a str>, |     pub username: Option<&'a str>, | ||||||
| @ -551,7 +553,7 @@ where | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// API/config analog of `Permissions` defined in `db/proto/schema.proto`.
 | /// API/config analog of `Permissions` defined in `db/proto/schema.proto`.
 | ||||||
| #[derive(Debug, Default, Deserialize, Serialize)] | #[derive(Debug, Default, Deserialize, Serialize, PartialEq, Eq)] | ||||||
| #[serde(deny_unknown_fields)] | #[serde(deny_unknown_fields)] | ||||||
| pub struct Permissions { | pub struct Permissions { | ||||||
|     #[serde(default)] |     #[serde(default)] | ||||||
|  | |||||||
| @ -44,20 +44,25 @@ impl Service { | |||||||
|             bail_t!(Unauthenticated, "must have admin_users permission"); |             bail_t!(Unauthenticated, "must have admin_users permission"); | ||||||
|         } |         } | ||||||
|         let r = extract_json_body(&mut req).await?; |         let r = extract_json_body(&mut req).await?; | ||||||
|         let r: json::UserSubset = serde_json::from_slice(&r).map_err(|e| bad_req(e.to_string()))?; |         let mut r: json::UserSubset = | ||||||
|  |             serde_json::from_slice(&r).map_err(|e| bad_req(e.to_string()))?; | ||||||
|         let username = r |         let username = r | ||||||
|             .username |             .username | ||||||
|  |             .take() | ||||||
|             .ok_or_else(|| format_err_t!(InvalidArgument, "username must be specified"))?; |             .ok_or_else(|| format_err_t!(InvalidArgument, "username must be specified"))?; | ||||||
|         let mut change = db::UserChange::add_user(username.to_owned()); |         let mut change = db::UserChange::add_user(username.to_owned()); | ||||||
|         if let Some(Some(pwd)) = r.password { |         if let Some(Some(pwd)) = r.password.take() { | ||||||
|             change.set_password(pwd.to_owned()); |             change.set_password(pwd.to_owned()); | ||||||
|         } |         } | ||||||
|         if let Some(preferences) = r.preferences { |         if let Some(preferences) = r.preferences.take() { | ||||||
|             change.config.preferences = preferences; |             change.config.preferences = preferences; | ||||||
|         } |         } | ||||||
|         if let Some(ref permissions) = r.permissions { |         if let Some(ref permissions) = r.permissions.take() { | ||||||
|             change.permissions = permissions.into(); |             change.permissions = permissions.into(); | ||||||
|         } |         } | ||||||
|  |         if r != Default::default() { | ||||||
|  |             bail_t!(Unimplemented, "unsupported user fields: {:#?}", r); | ||||||
|  |         } | ||||||
|         let mut l = self.db.lock(); |         let mut l = self.db.lock(); | ||||||
|         let user = l.apply_user_change(change)?; |         let user = l.apply_user_change(change)?; | ||||||
|         serve_json(&req, &PutUsersResponse { id: user.id }) |         serve_json(&req, &PutUsersResponse { id: user.id }) | ||||||
| @ -145,33 +150,54 @@ impl Service { | |||||||
|             } |             } | ||||||
|             (_, _) => {} |             (_, _) => {} | ||||||
|         } |         } | ||||||
|         if let Some(ref precondition) = r.precondition { |         if let Some(mut precondition) = r.precondition { | ||||||
|             if matches!(precondition.preferences, Some(ref p) if p != &user.config.preferences) { |             if matches!(precondition.username.take(), Some(n) if n != &user.username) { | ||||||
|  |                 bail_t!(FailedPrecondition, "username mismatch"); | ||||||
|  |             } | ||||||
|  |             if matches!(precondition.preferences.take(), Some(ref p) if p != &user.config.preferences) | ||||||
|  |             { | ||||||
|                 bail_t!(FailedPrecondition, "preferences mismatch"); |                 bail_t!(FailedPrecondition, "preferences mismatch"); | ||||||
|             } |             } | ||||||
|             if let Some(p) = precondition.password { |             if let Some(p) = precondition.password.take() { | ||||||
|                 if !user.check_password(p)? { |                 if !user.check_password(p)? { | ||||||
|                     bail_t!(FailedPrecondition, "password mismatch"); // or Unauthenticated?
 |                     bail_t!(FailedPrecondition, "password mismatch"); // or Unauthenticated?
 | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if let Some(ref p) = precondition.permissions { |             if let Some(p) = precondition.permissions.take() { | ||||||
|                 if user.permissions != db::Permissions::from(p) { |                 if user.permissions != db::Permissions::from(&p) { | ||||||
|                     bail_t!(FailedPrecondition, "permissions mismatch"); |                     bail_t!(FailedPrecondition, "permissions mismatch"); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             // Safety valve in case something is added to UserSubset and forgotten here.
 | ||||||
|  |             if precondition != Default::default() { | ||||||
|  |                 bail_t!( | ||||||
|  |                     Unimplemented, | ||||||
|  |                     "preconditions not supported: {:#?}", | ||||||
|  |                     &precondition | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         if let Some(update) = r.update { |         } | ||||||
|  |         if let Some(mut update) = r.update { | ||||||
|             let mut change = user.change(); |             let mut change = user.change(); | ||||||
|             if let Some(preferences) = update.preferences { |             if let Some(n) = update.username.take() { | ||||||
|  |                 change.username = n.to_string(); | ||||||
|  |             } | ||||||
|  |             if let Some(preferences) = update.preferences.take() { | ||||||
|                 change.config.preferences = preferences; |                 change.config.preferences = preferences; | ||||||
|             } |             } | ||||||
|             match update.password { |             match update.password.take() { | ||||||
|                 None => {} |                 None => {} | ||||||
|                 Some(None) => change.clear_password(), |                 Some(None) => change.clear_password(), | ||||||
|                 Some(Some(p)) => change.set_password(p.to_owned()), |                 Some(Some(p)) => change.set_password(p.to_owned()), | ||||||
|             } |             } | ||||||
|             if let Some(ref permissions) = update.permissions { |             if let Some(permissions) = update.permissions.take() { | ||||||
|                 change.permissions = permissions.into(); |                 change.permissions = (&permissions).into(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Safety valve in case something is added to UserSubset and forgotten here.
 | ||||||
|  |             if update != Default::default() { | ||||||
|  |                 bail_t!(Unimplemented, "updates not supported: {:#?}", &update); | ||||||
|             } |             } | ||||||
|             db.apply_user_change(change)?; |             db.apply_user_change(change)?; | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user