Move user ID localpart classification into a public function
This commit is contained in:
parent
76a5a487d2
commit
93f75353a7
@ -27,6 +27,9 @@ Improvements:
|
||||
* Add support for historical uppercase MXIDs
|
||||
* Made all dependencies optional
|
||||
* `serde` is the only one that is enabled by default
|
||||
* The `user_id` module is now public and contains `fn localpart_is_fully_conforming`
|
||||
* This function can be used to determine whether a user name (the localpart of a user ID) is valid
|
||||
without actually constructing a full user ID first
|
||||
|
||||
# 0.14.1
|
||||
|
||||
|
@ -20,10 +20,9 @@ use std::num::NonZeroU8;
|
||||
use serde::de::{self, Deserialize as _, Deserializer, Unexpected};
|
||||
|
||||
#[doc(inline)]
|
||||
pub use crate::device_id::DeviceId;
|
||||
pub use crate::{
|
||||
error::Error, event_id::EventId, room_alias_id::RoomAliasId, room_id::RoomId,
|
||||
room_id_or_room_alias_id::RoomIdOrAliasId, room_version_id::RoomVersionId,
|
||||
device_id::DeviceId, error::Error, event_id::EventId, room_alias_id::RoomAliasId,
|
||||
room_id::RoomId, room_id_or_room_alias_id::RoomIdOrAliasId, room_version_id::RoomVersionId,
|
||||
server_name::is_valid_server_name, user_id::UserId,
|
||||
};
|
||||
|
||||
@ -40,7 +39,7 @@ mod room_id;
|
||||
mod room_id_or_room_alias_id;
|
||||
mod room_version_id;
|
||||
mod server_name;
|
||||
mod user_id;
|
||||
pub mod user_id;
|
||||
|
||||
/// All identifiers must be 255 bytes or less.
|
||||
const MAX_BYTES: usize = 255;
|
||||
|
@ -84,29 +84,43 @@ impl TryFrom<Cow<'_, str>> for UserId {
|
||||
let colon_idx = parse_id(&user_id, &['@'])?;
|
||||
let localpart = &user_id[1..colon_idx.get() as usize];
|
||||
|
||||
// See https://matrix.org/docs/spec/appendices#user-identifiers
|
||||
let is_fully_conforming = localpart.bytes().all(|b| match b {
|
||||
b'0'..=b'9' | b'a'..=b'z' | b'-' | b'.' | b'=' | b'_' | b'/' => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
// If it's not fully conforming, check if it contains characters that are also disallowed
|
||||
// for historical user IDs. If there are, return an error.
|
||||
// See https://matrix.org/docs/spec/appendices#historical-user-ids
|
||||
if !is_fully_conforming && localpart.bytes().any(|b| b < 0x21 || b == b':' || b > 0x7E) {
|
||||
return Err(Error::InvalidCharacters);
|
||||
}
|
||||
let is_historical = localpart_is_fully_comforming(localpart)?;
|
||||
|
||||
Ok(Self {
|
||||
full_id: user_id.into_owned(),
|
||||
colon_idx,
|
||||
is_historical: !is_fully_conforming,
|
||||
is_historical: !is_historical,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
common_impls!(UserId, "a Matrix user ID");
|
||||
|
||||
/// Check whether the given user id localpart is valid and fully conforming
|
||||
///
|
||||
/// Returns an `Err` for invalid user ID localparts, `Ok(false)` for historical user ID localparts
|
||||
/// and `Ok(true)` for fully conforming user ID localparts.
|
||||
pub fn localpart_is_fully_comforming(localpart: &str) -> Result<bool, Error> {
|
||||
if localpart.is_empty() {
|
||||
return Err(Error::InvalidLocalPart);
|
||||
}
|
||||
|
||||
// See https://matrix.org/docs/spec/appendices#user-identifiers
|
||||
let is_fully_conforming = localpart.bytes().all(|b| match b {
|
||||
b'0'..=b'9' | b'a'..=b'z' | b'-' | b'.' | b'=' | b'_' | b'/' => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
// If it's not fully conforming, check if it contains characters that are also disallowed
|
||||
// for historical user IDs. If there are, return an error.
|
||||
// See https://matrix.org/docs/spec/appendices#historical-user-ids
|
||||
if !is_fully_conforming && localpart.bytes().any(|b| b < 0x21 || b == b':' || b > 0x7E) {
|
||||
Err(Error::InvalidCharacters)
|
||||
} else {
|
||||
Ok(is_fully_conforming)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::convert::TryFrom;
|
||||
|
Loading…
x
Reference in New Issue
Block a user