Skip to content

Commit c7ab2fe

Browse files
committed
feat: implements allow_new_users setting
Refs: #1484 #1566 #1629 Closes: #1429
1 parent 391addb commit c7ab2fe

9 files changed

Lines changed: 103 additions & 2 deletions

File tree

docs/src/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ The following configuration options are available.
106106
| <span id="SYNC_TOKENSERVER__STATSD_LABEL"></span>SYNC_TOKENSERVER__STATSD_LABEL | syncstorage.tokenserver | StatsD metrics label prefix |
107107
| <span id="SYNC_TOKENSERVER__TOKEN_DURATION"></span>SYNC_TOKENSERVER__TOKEN_DURATION | 3600 | Token TTL (1 hour) |
108108
| <span id="SYNC_TOKENSERVER__FXA_WEBHOOK_ENABLED"></span>SYNC_TOKENSERVER__FXA_WEBHOOK_ENABLED | false | Enable the FxA webhook endpoint. When disabled, the route is not registered. |
109+
| <span id="SYNC_TOKENSERVER__ALLOW_NEW_USERS"></span>SYNC_TOKENSERVER__ALLOW_NEW_USERS | true | Whether new users may be created. When disabled, only previously registered users can use the tokenserver service. |
109110

110111
### Tokenserver+FxA Integration
111112

syncserver/src/tokenserver/extractors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ impl FromRequest for TokenserverRequest {
249249
client_state: auth_data.client_state.clone(),
250250
keys_changed_at: auth_data.keys_changed_at,
251251
capacity_release_rate: state.node_capacity_release_rate,
252+
allow_new_users: state.allow_new_users,
252253
})
253254
.await?;
254255
log_items_mutator.insert("first_seen_at".to_owned(), user.first_seen_at.to_string());
@@ -1345,6 +1346,7 @@ mod tests {
13451346
token_duration: TOKEN_DURATION,
13461347
set_verifiers: Vec::new(),
13471348
fxa_webhook_enabled: false,
1349+
allow_new_users: true,
13481350
}
13491351
}
13501352

@@ -1367,6 +1369,7 @@ mod tests {
13671369
token_duration: TOKEN_DURATION,
13681370
set_verifiers,
13691371
fxa_webhook_enabled: true,
1372+
allow_new_users: true,
13701373
}
13711374
}
13721375

syncserver/src/tokenserver/handlers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ mod tests {
444444
token_duration: 3600,
445445
set_verifiers,
446446
fxa_webhook_enabled: true,
447+
allow_new_users: true,
447448
}
448449
}
449450

syncserver/src/tokenserver/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct ServerState {
3434
pub token_duration: u64,
3535
pub set_verifiers: Vec<SETVerifierImpl>,
3636
pub fxa_webhook_enabled: bool,
37+
pub allow_new_users: bool,
3738
}
3839

3940
impl ServerState {
@@ -115,6 +116,7 @@ impl ServerState {
115116
token_duration: settings.token_duration,
116117
set_verifiers,
117118
fxa_webhook_enabled: settings.fxa_webhook_enabled,
119+
allow_new_users: settings.allow_new_users,
118120
})
119121
}
120122

tokenserver-db-common/src/error.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ pub struct DbError {
1818
}
1919

2020
impl DbError {
21+
pub fn user_not_found(user: String) -> Self {
22+
DbErrorKind::UserNotFound(user).into()
23+
}
24+
2125
pub fn internal(msg: String) -> Self {
2226
DbErrorKind::Internal(msg).into()
2327
}
@@ -26,6 +30,10 @@ impl DbError {
2630
DbErrorKind::PoolTimeout(timeout_type).into()
2731
}
2832

33+
pub fn is_user_not_found(&self) -> bool {
34+
matches!(&self.kind, DbErrorKind::UserNotFound(_))
35+
}
36+
2937
#[cfg(debug_assertions)]
3038
pub fn is_diesel_not_found(&self) -> bool {
3139
matches!(&self.kind, DbErrorKind::Sql(e) if e.is_diesel_not_found())
@@ -59,6 +67,9 @@ impl ReportableError for DbError {
5967

6068
#[derive(Debug, Error)]
6169
enum DbErrorKind {
70+
#[error("Specified user does not exist: {}", _0)]
71+
UserNotFound(String),
72+
6273
#[error("{}", _0)]
6374
Sql(SqlError),
6475

@@ -72,6 +83,11 @@ enum DbErrorKind {
7283
impl From<DbErrorKind> for DbError {
7384
fn from(kind: DbErrorKind) -> Self {
7485
match kind {
86+
DbErrorKind::UserNotFound(_) => Self {
87+
kind,
88+
status: StatusCode::NOT_FOUND,
89+
backtrace: Box::new(Backtrace::new_unresolved()),
90+
},
7591
DbErrorKind::Sql(ref sqle) => Self {
7692
status: sqle.status,
7793
backtrace: Box::new(sqle.backtrace.clone()),

tokenserver-db-common/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub trait Db {
113113
fn metrics(&self) -> &Metrics;
114114

115115
/// Gets the user with the given email and service ID.
116-
/// If one doesn't exist, allocates a new user.
116+
/// If one doesn't exist, and when configuration allows it, allocates a new user.
117117
async fn get_or_create_user(
118118
&mut self,
119119
params: params::GetOrCreateUser,
@@ -127,7 +127,12 @@ pub trait Db {
127127

128128
if raw_users.is_empty() {
129129
// There are no users in the database with the given email and service ID, so
130-
// allocate a new one.
130+
// allocate a new one if allowed by configuration.
131+
if !params.allow_new_users {
132+
warn!("New users registration is disabled by configuration"; "email" => &params.email);
133+
return Err(DbError::user_not_found(params.email.clone()));
134+
}
135+
131136
let allocate_user_result = self
132137
.allocate_user(params.clone() as params::AllocateUser)
133138
.await?;
@@ -193,6 +198,7 @@ pub trait Db {
193198
client_state: raw_user.client_state.clone(),
194199
keys_changed_at: raw_user.keys_changed_at,
195200
capacity_release_rate: params.capacity_release_rate,
201+
allow_new_users: params.allow_new_users,
196202
})
197203
.await?
198204
};

tokenserver-db-common/src/params.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct GetOrCreateUser {
3535
pub client_state: String,
3636
pub keys_changed_at: Option<i64>,
3737
pub capacity_release_rate: Option<f32>,
38+
pub allow_new_users: bool,
3839
}
3940

4041
pub type AllocateUser = GetOrCreateUser;

tokenserver-db/src/tests.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ async fn test_node_allocation() -> DbResult<()> {
556556
client_state: "aaaa".to_owned(),
557557
keys_changed_at: Some(1234),
558558
capacity_release_rate: None,
559+
allow_new_users: true,
559560
})
560561
.await?;
561562
assert_eq!(user.node, "https://node1");
@@ -609,6 +610,7 @@ async fn test_allocation_to_least_loaded_node() -> DbResult<()> {
609610
client_state: "aaaa".to_owned(),
610611
keys_changed_at: Some(1234),
611612
capacity_release_rate: None,
613+
allow_new_users: true,
612614
})
613615
.await?;
614616

@@ -620,6 +622,7 @@ async fn test_allocation_to_least_loaded_node() -> DbResult<()> {
620622
client_state: "aaaa".to_owned(),
621623
keys_changed_at: Some(1234),
622624
capacity_release_rate: None,
625+
allow_new_users: true,
623626
})
624627
.await?;
625628

@@ -663,6 +666,7 @@ async fn test_allocation_is_not_allowed_to_downed_nodes() -> DbResult<()> {
663666
client_state: "aaaa".to_owned(),
664667
keys_changed_at: Some(1234),
665668
capacity_release_rate: None,
669+
allow_new_users: true,
666670
})
667671
.await;
668672
let error = result.unwrap_err();
@@ -704,6 +708,7 @@ async fn test_allocation_is_not_allowed_to_backoff_nodes() -> DbResult<()> {
704708
client_state: "aaaa".to_owned(),
705709
keys_changed_at: Some(1234),
706710
capacity_release_rate: None,
711+
allow_new_users: true,
707712
})
708713
.await;
709714
let error = result.unwrap_err();
@@ -744,6 +749,7 @@ async fn test_node_reassignment_when_records_are_replaced() -> DbResult<()> {
744749
client_state: "aaaa".to_owned(),
745750
keys_changed_at: Some(1234),
746751
capacity_release_rate: None,
752+
allow_new_users: true,
747753
})
748754
.await?;
749755
let user1 = db
@@ -768,6 +774,7 @@ async fn test_node_reassignment_when_records_are_replaced() -> DbResult<()> {
768774
client_state: "bbbb".to_owned(),
769775
keys_changed_at: Some(1235),
770776
capacity_release_rate: None,
777+
allow_new_users: true,
771778
})
772779
.await?;
773780

@@ -816,6 +823,7 @@ async fn test_node_reassignment_not_done_for_retired_users() -> DbResult<()> {
816823
client_state: "aaaa".to_owned(),
817824
keys_changed_at: Some(1234),
818825
capacity_release_rate: None,
826+
allow_new_users: true,
819827
})
820828
.await?;
821829

@@ -827,6 +835,7 @@ async fn test_node_reassignment_not_done_for_retired_users() -> DbResult<()> {
827835
client_state: "aaaa".to_owned(),
828836
keys_changed_at: Some(1234),
829837
capacity_release_rate: None,
838+
allow_new_users: true,
830839
})
831840
.await?;
832841

@@ -884,6 +893,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
884893
client_state: "aaaa".to_owned(),
885894
keys_changed_at: Some(1234),
886895
capacity_release_rate: None,
896+
allow_new_users: true,
887897
})
888898
.await?;
889899

@@ -895,6 +905,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
895905
client_state: "aaaa".to_owned(),
896906
keys_changed_at: Some(1234),
897907
capacity_release_rate: None,
908+
allow_new_users: true,
898909
})
899910
.await?;
900911

@@ -906,6 +917,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
906917
client_state: "aaaa".to_owned(),
907918
keys_changed_at: Some(1234),
908919
capacity_release_rate: None,
920+
allow_new_users: true,
909921
})
910922
.await?;
911923

@@ -917,6 +929,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
917929
client_state: "aaaa".to_owned(),
918930
keys_changed_at: Some(1234),
919931
capacity_release_rate: None,
932+
allow_new_users: true,
920933
})
921934
.await?;
922935

@@ -949,6 +962,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
949962
client_state: user.client_state.clone(),
950963
keys_changed_at: user.keys_changed_at,
951964
capacity_release_rate: None,
965+
allow_new_users: true,
952966
})
953967
.await?;
954968

@@ -978,6 +992,7 @@ async fn test_node_reassignment_and_removal() -> DbResult<()> {
978992
client_state: user.client_state.clone(),
979993
keys_changed_at: user.keys_changed_at,
980994
capacity_release_rate: None,
995+
allow_new_users: true,
981996
})
982997
.await?;
983998

@@ -1034,6 +1049,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
10341049
client_state: "aaaa".to_owned(),
10351050
keys_changed_at: Some(1234),
10361051
capacity_release_rate: None,
1052+
allow_new_users: true,
10371053
})
10381054
.await?;
10391055

@@ -1051,6 +1067,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
10511067
client_state: "aaaa".to_owned(),
10521068
keys_changed_at: Some(1234),
10531069
capacity_release_rate: None,
1070+
allow_new_users: true,
10541071
})
10551072
.await?;
10561073

@@ -1070,6 +1087,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
10701087
client_state: "aaaa".to_owned(),
10711088
keys_changed_at: Some(1234),
10721089
capacity_release_rate: None,
1090+
allow_new_users: true,
10731091
})
10741092
.await?;
10751093

@@ -1087,6 +1105,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
10871105
client_state: "aaaa".to_owned(),
10881106
keys_changed_at: Some(1234),
10891107
capacity_release_rate: None,
1108+
allow_new_users: true,
10901109
})
10911110
.await?;
10921111

@@ -1105,6 +1124,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
11051124
client_state: "aaaa".to_owned(),
11061125
keys_changed_at: Some(1234),
11071126
capacity_release_rate: None,
1127+
allow_new_users: true,
11081128
})
11091129
.await?;
11101130

@@ -1122,6 +1142,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
11221142
client_state: "aaaa".to_owned(),
11231143
keys_changed_at: Some(1234),
11241144
capacity_release_rate: None,
1145+
allow_new_users: true,
11251146
})
11261147
.await?;
11271148

@@ -1140,6 +1161,7 @@ async fn test_gradual_release_of_node_capacity() -> DbResult<()> {
11401161
client_state: "aaaa".to_owned(),
11411162
keys_changed_at: Some(1234),
11421163
capacity_release_rate: None,
1164+
allow_new_users: true,
11431165
})
11441166
.await;
11451167

@@ -1185,6 +1207,7 @@ async fn test_correct_created_at_used_during_node_reassignment() -> DbResult<()>
11851207
client_state: "aaaa".to_owned(),
11861208
keys_changed_at: Some(1234),
11871209
capacity_release_rate: None,
1210+
allow_new_users: true,
11881211
})
11891212
.await?;
11901213

@@ -1204,6 +1227,7 @@ async fn test_correct_created_at_used_during_node_reassignment() -> DbResult<()>
12041227
client_state: "aaaa".to_owned(),
12051228
keys_changed_at: Some(1234),
12061229
capacity_release_rate: None,
1230+
allow_new_users: true,
12071231
})
12081232
.await?;
12091233

@@ -1245,6 +1269,7 @@ async fn test_correct_created_at_used_during_user_retrieval() -> DbResult<()> {
12451269
client_state: "aaaa".to_owned(),
12461270
keys_changed_at: Some(1234),
12471271
capacity_release_rate: None,
1272+
allow_new_users: true,
12481273
})
12491274
.await?;
12501275

@@ -1261,6 +1286,7 @@ async fn test_correct_created_at_used_during_user_retrieval() -> DbResult<()> {
12611286
client_state: "aaaa".to_owned(),
12621287
keys_changed_at: Some(1234),
12631288
capacity_release_rate: None,
1289+
allow_new_users: true,
12641290
})
12651291
.await?;
12661292

@@ -1270,6 +1296,47 @@ async fn test_correct_created_at_used_during_user_retrieval() -> DbResult<()> {
12701296
Ok(())
12711297
}
12721298

1299+
#[tokio::test]
1300+
async fn test_no_new_user_allocation() -> DbResult<()> {
1301+
let pool = db_pool().await?;
1302+
let mut db = pool.get().await?;
1303+
1304+
let service_id = db
1305+
.get_service_id(params::GetServiceId {
1306+
service: "sync-1.5".to_owned(),
1307+
})
1308+
.await?
1309+
.id;
1310+
1311+
// Add a downed node
1312+
db.post_node(params::PostNode {
1313+
service_id,
1314+
node: "https://node1".to_owned(),
1315+
current_load: 0,
1316+
capacity: 100,
1317+
available: 100,
1318+
downed: 1,
1319+
..Default::default()
1320+
})
1321+
.await?;
1322+
1323+
// User allocation fails because users allocation is disabled
1324+
let result = db
1325+
.allocate_user(params::AllocateUser {
1326+
service_id,
1327+
generation: 1234,
1328+
email: "test@test.com".to_owned(),
1329+
client_state: "aaaa".to_owned(),
1330+
keys_changed_at: Some(1234),
1331+
capacity_release_rate: None,
1332+
allow_new_users: false,
1333+
})
1334+
.await;
1335+
assert!(result.unwrap_err().is_user_not_found());
1336+
1337+
Ok(())
1338+
}
1339+
12731340
#[tokio::test]
12741341
async fn test_latest_created_at() -> DbResult<()> {
12751342
let pool = db_pool().await?;

0 commit comments

Comments
 (0)