1use crate::{
10 cipher_suite::CipherSuite,
11 client::Client,
12 client_config::ClientConfig,
13 extension::ExtensionType,
14 group::{
15 mls_rules::{DefaultMlsRules, MlsRules},
16 proposal::ProposalType,
17 },
18 identity::CredentialType,
19 identity::SigningIdentity,
20 protocol_version::ProtocolVersion,
21 psk::{ExternalPskId, PreSharedKey},
22 storage_provider::in_memory::{
23 InMemoryGroupStateStorage, InMemoryKeyPackageStorage, InMemoryPreSharedKeyStorage,
24 },
25 time::MlsTime,
26 tree_kem::{Capabilities, Lifetime},
27 Sealed,
28};
29
30use alloc::vec::Vec;
31use core::time::Duration;
32
33#[cfg(feature = "sqlite")]
34use mls_rs_provider_sqlite::{
35 SqLiteDataStorageEngine, SqLiteDataStorageError,
36 {
37 connection_strategy::ConnectionStrategy,
38 storage::{SqLiteGroupStateStorage, SqLiteKeyPackageStorage, SqLitePreSharedKeyStorage},
39 },
40};
41
42#[cfg(feature = "private_message")]
43pub use crate::group::padding::PaddingMode;
44
45pub type BaseConfig = Config<
47 InMemoryKeyPackageStorage,
48 InMemoryPreSharedKeyStorage,
49 InMemoryGroupStateStorage,
50 Missing,
51 DefaultMlsRules,
52 Missing,
53>;
54
55pub type BaseInMemoryConfig = Config<
57 InMemoryKeyPackageStorage,
58 InMemoryPreSharedKeyStorage,
59 InMemoryGroupStateStorage,
60 Missing,
61 Missing,
62 Missing,
63>;
64
65pub type EmptyConfig = Config<Missing, Missing, Missing, Missing, Missing, Missing>;
66
67#[cfg(feature = "sqlite")]
69pub type BaseSqlConfig = Config<
70 SqLiteKeyPackageStorage,
71 SqLitePreSharedKeyStorage,
72 SqLiteGroupStateStorage,
73 Missing,
74 DefaultMlsRules,
75 Missing,
76>;
77
78#[derive(Debug)]
177pub struct ClientBuilder<C>(C);
178
179impl Default for ClientBuilder<BaseConfig> {
180 fn default() -> Self {
181 Self::new()
182 }
183}
184
185impl<C> ClientBuilder<C> {
186 pub(crate) fn from_config(c: C) -> Self {
187 Self(c)
188 }
189}
190
191impl ClientBuilder<BaseConfig> {
192 pub fn new() -> Self {
194 Self(Config(ConfigInner {
195 settings: Default::default(),
196 key_package_repo: Default::default(),
197 psk_store: Default::default(),
198 group_state_storage: Default::default(),
199 identity_provider: Missing,
200 mls_rules: DefaultMlsRules::new(),
201 crypto_provider: Missing,
202 signer: Default::default(),
203 signing_identity: Default::default(),
204 version: ProtocolVersion::MLS_10,
205 }))
206 }
207}
208
209impl ClientBuilder<EmptyConfig> {
210 pub fn new_empty() -> Self {
211 Self(Config(ConfigInner {
212 settings: Default::default(),
213 key_package_repo: Missing,
214 psk_store: Missing,
215 group_state_storage: Missing,
216 identity_provider: Missing,
217 mls_rules: Missing,
218 crypto_provider: Missing,
219 signer: Default::default(),
220 signing_identity: Default::default(),
221 version: ProtocolVersion::MLS_10,
222 }))
223 }
224}
225
226#[cfg(feature = "sqlite")]
227impl ClientBuilder<BaseSqlConfig> {
228 pub fn new_sqlite<CS: ConnectionStrategy>(
230 storage: SqLiteDataStorageEngine<CS>,
231 ) -> Result<Self, SqLiteDataStorageError> {
232 Ok(Self(Config(ConfigInner {
233 settings: Default::default(),
234 key_package_repo: storage.key_package_storage()?,
235 psk_store: storage.pre_shared_key_storage()?,
236 group_state_storage: storage.group_state_storage()?,
237 identity_provider: Missing,
238 mls_rules: DefaultMlsRules::new(),
239 crypto_provider: Missing,
240 signer: Default::default(),
241 signing_identity: Default::default(),
242 version: ProtocolVersion::MLS_10,
243 })))
244 }
245}
246
247impl<C: IntoConfig> ClientBuilder<C> {
248 pub fn extension_type(self, type_: ExtensionType) -> ClientBuilder<IntoConfigOutput<C>> {
250 self.extension_types(Some(type_))
251 }
252
253 pub fn extension_types<I>(self, types: I) -> ClientBuilder<IntoConfigOutput<C>>
255 where
256 I: IntoIterator<Item = ExtensionType>,
257 {
258 let mut c = self.0.into_config();
259 c.0.settings.extension_types.extend(types);
260 ClientBuilder(c)
261 }
262
263 pub fn custom_proposal_type(self, type_: ProposalType) -> ClientBuilder<IntoConfigOutput<C>> {
265 self.custom_proposal_types(Some(type_))
266 }
267
268 pub fn custom_proposal_types<I>(self, types: I) -> ClientBuilder<IntoConfigOutput<C>>
270 where
271 I: IntoIterator<Item = ProposalType>,
272 {
273 let mut c = self.0.into_config();
274 c.0.settings.custom_proposal_types.extend(types);
275 ClientBuilder(c)
276 }
277
278 pub fn protocol_version(self, version: ProtocolVersion) -> ClientBuilder<IntoConfigOutput<C>> {
283 self.protocol_versions(Some(version))
284 }
285
286 pub fn protocol_versions<I>(self, versions: I) -> ClientBuilder<IntoConfigOutput<C>>
291 where
292 I: IntoIterator<Item = ProtocolVersion>,
293 {
294 let mut c = self.0.into_config();
295 c.0.settings.protocol_versions.extend(versions);
296 ClientBuilder(c)
297 }
298
299 pub fn key_package_lifetime(self, lifetime: Duration) -> ClientBuilder<IntoConfigOutput<C>> {
301 let mut c = self.0.into_config();
302 c.0.settings.lifetime = lifetime;
303 ClientBuilder(c)
304 }
305
306 pub fn key_package_repo<K>(self, key_package_repo: K) -> ClientBuilder<WithKeyPackageRepo<K, C>>
310 where
311 K: KeyPackageStorage,
312 {
313 let Config(c) = self.0.into_config();
314
315 ClientBuilder(Config(ConfigInner {
316 settings: c.settings,
317 key_package_repo,
318 psk_store: c.psk_store,
319 group_state_storage: c.group_state_storage,
320 identity_provider: c.identity_provider,
321 mls_rules: c.mls_rules,
322 crypto_provider: c.crypto_provider,
323 signer: c.signer,
324 signing_identity: c.signing_identity,
325 version: c.version,
326 }))
327 }
328
329 pub fn psk_store<P>(self, psk_store: P) -> ClientBuilder<WithPskStore<P, C>>
333 where
334 P: PreSharedKeyStorage,
335 {
336 let Config(c) = self.0.into_config();
337
338 ClientBuilder(Config(ConfigInner {
339 settings: c.settings,
340 key_package_repo: c.key_package_repo,
341 psk_store,
342 group_state_storage: c.group_state_storage,
343 identity_provider: c.identity_provider,
344 mls_rules: c.mls_rules,
345 crypto_provider: c.crypto_provider,
346 signer: c.signer,
347 signing_identity: c.signing_identity,
348 version: c.version,
349 }))
350 }
351
352 pub fn group_state_storage<G>(
356 self,
357 group_state_storage: G,
358 ) -> ClientBuilder<WithGroupStateStorage<G, C>>
359 where
360 G: GroupStateStorage,
361 {
362 let Config(c) = self.0.into_config();
363
364 ClientBuilder(Config(ConfigInner {
365 settings: c.settings,
366 key_package_repo: c.key_package_repo,
367 psk_store: c.psk_store,
368 group_state_storage,
369 identity_provider: c.identity_provider,
370 crypto_provider: c.crypto_provider,
371 mls_rules: c.mls_rules,
372 signer: c.signer,
373 signing_identity: c.signing_identity,
374 version: c.version,
375 }))
376 }
377
378 pub fn identity_provider<I>(
380 self,
381 identity_provider: I,
382 ) -> ClientBuilder<WithIdentityProvider<I, C>>
383 where
384 I: IdentityProvider,
385 {
386 let Config(c) = self.0.into_config();
387
388 ClientBuilder(Config(ConfigInner {
389 settings: c.settings,
390 key_package_repo: c.key_package_repo,
391 psk_store: c.psk_store,
392 group_state_storage: c.group_state_storage,
393 identity_provider,
394 mls_rules: c.mls_rules,
395 crypto_provider: c.crypto_provider,
396 signer: c.signer,
397 signing_identity: c.signing_identity,
398 version: c.version,
399 }))
400 }
401
402 pub fn crypto_provider<Cp>(
404 self,
405 crypto_provider: Cp,
406 ) -> ClientBuilder<WithCryptoProvider<Cp, C>>
407 where
408 Cp: CryptoProvider,
409 {
410 let Config(c) = self.0.into_config();
411
412 ClientBuilder(Config(ConfigInner {
413 settings: c.settings,
414 key_package_repo: c.key_package_repo,
415 psk_store: c.psk_store,
416 group_state_storage: c.group_state_storage,
417 identity_provider: c.identity_provider,
418 mls_rules: c.mls_rules,
419 crypto_provider,
420 signer: c.signer,
421 signing_identity: c.signing_identity,
422 version: c.version,
423 }))
424 }
425
426 pub fn mls_rules<Pr>(self, mls_rules: Pr) -> ClientBuilder<WithMlsRules<Pr, C>>
434 where
435 Pr: MlsRules,
436 {
437 let Config(c) = self.0.into_config();
438
439 ClientBuilder(Config(ConfigInner {
440 settings: c.settings,
441 key_package_repo: c.key_package_repo,
442 psk_store: c.psk_store,
443 group_state_storage: c.group_state_storage,
444 identity_provider: c.identity_provider,
445 mls_rules,
446 crypto_provider: c.crypto_provider,
447 signer: c.signer,
448 signing_identity: c.signing_identity,
449 version: c.version,
450 }))
451 }
452
453 pub fn used_protocol_version(
455 self,
456 version: ProtocolVersion,
457 ) -> ClientBuilder<IntoConfigOutput<C>> {
458 let mut c = self.0.into_config();
459 c.0.version = version;
460 ClientBuilder(c)
461 }
462
463 pub fn signing_identity(
466 self,
467 signing_identity: SigningIdentity,
468 signer: SignatureSecretKey,
469 cipher_suite: CipherSuite,
470 ) -> ClientBuilder<IntoConfigOutput<C>> {
471 let mut c = self.0.into_config();
472 c.0.signer = Some(signer);
473 c.0.signing_identity = Some((signing_identity, cipher_suite));
474 ClientBuilder(c)
475 }
476
477 pub fn signer(self, signer: SignatureSecretKey) -> ClientBuilder<IntoConfigOutput<C>> {
479 let mut c = self.0.into_config();
480 c.0.signer = Some(signer);
481 ClientBuilder(c)
482 }
483
484 #[cfg(any(test, feature = "test_util"))]
485 pub(crate) fn key_package_not_before(
486 self,
487 key_package_not_before: MlsTime,
488 ) -> ClientBuilder<IntoConfigOutput<C>> {
489 let mut c = self.0.into_config();
490 c.0.settings.key_package_not_before = Some(key_package_not_before);
491 ClientBuilder(c)
492 }
493}
494
495impl<C: IntoConfig> ClientBuilder<C>
496where
497 C::KeyPackageRepository: KeyPackageStorage + Clone,
498 C::PskStore: PreSharedKeyStorage + Clone,
499 C::GroupStateStorage: GroupStateStorage + Clone,
500 C::IdentityProvider: IdentityProvider + Clone,
501 C::MlsRules: MlsRules + Clone,
502 C::CryptoProvider: CryptoProvider + Clone,
503{
504 pub(crate) fn build_config(self) -> IntoConfigOutput<C> {
505 let mut c = self.0.into_config();
506
507 if c.0.settings.protocol_versions.is_empty() {
508 c.0.settings.protocol_versions = ProtocolVersion::all().collect();
509 }
510
511 c
512 }
513
514 pub fn build(self) -> Client<IntoConfigOutput<C>> {
519 let mut c = self.build_config();
520 let version = c.0.version;
521 let signer = c.0.signer.take();
522 let signing_identity = c.0.signing_identity.take();
523
524 Client::new(c, signer, signing_identity, version)
525 }
526}
527
528impl<C: IntoConfig<PskStore = InMemoryPreSharedKeyStorage>> ClientBuilder<C> {
529 pub fn psk(
531 self,
532 psk_id: ExternalPskId,
533 psk: PreSharedKey,
534 ) -> ClientBuilder<IntoConfigOutput<C>> {
535 let mut c = self.0.into_config();
536 c.0.psk_store.insert(psk_id, psk);
537 ClientBuilder(c)
538 }
539}
540
541#[derive(Debug)]
543pub struct Missing;
544
545pub type WithKeyPackageRepo<K, C> = Config<
549 K,
550 <C as IntoConfig>::PskStore,
551 <C as IntoConfig>::GroupStateStorage,
552 <C as IntoConfig>::IdentityProvider,
553 <C as IntoConfig>::MlsRules,
554 <C as IntoConfig>::CryptoProvider,
555>;
556
557pub type WithPskStore<P, C> = Config<
561 <C as IntoConfig>::KeyPackageRepository,
562 P,
563 <C as IntoConfig>::GroupStateStorage,
564 <C as IntoConfig>::IdentityProvider,
565 <C as IntoConfig>::MlsRules,
566 <C as IntoConfig>::CryptoProvider,
567>;
568
569pub type WithGroupStateStorage<G, C> = Config<
573 <C as IntoConfig>::KeyPackageRepository,
574 <C as IntoConfig>::PskStore,
575 G,
576 <C as IntoConfig>::IdentityProvider,
577 <C as IntoConfig>::MlsRules,
578 <C as IntoConfig>::CryptoProvider,
579>;
580
581pub type WithIdentityProvider<I, C> = Config<
585 <C as IntoConfig>::KeyPackageRepository,
586 <C as IntoConfig>::PskStore,
587 <C as IntoConfig>::GroupStateStorage,
588 I,
589 <C as IntoConfig>::MlsRules,
590 <C as IntoConfig>::CryptoProvider,
591>;
592
593pub type WithMlsRules<Pr, C> = Config<
597 <C as IntoConfig>::KeyPackageRepository,
598 <C as IntoConfig>::PskStore,
599 <C as IntoConfig>::GroupStateStorage,
600 <C as IntoConfig>::IdentityProvider,
601 Pr,
602 <C as IntoConfig>::CryptoProvider,
603>;
604
605pub type WithCryptoProvider<Cp, C> = Config<
609 <C as IntoConfig>::KeyPackageRepository,
610 <C as IntoConfig>::PskStore,
611 <C as IntoConfig>::GroupStateStorage,
612 <C as IntoConfig>::IdentityProvider,
613 <C as IntoConfig>::MlsRules,
614 Cp,
615>;
616
617pub type IntoConfigOutput<C> = Config<
619 <C as IntoConfig>::KeyPackageRepository,
620 <C as IntoConfig>::PskStore,
621 <C as IntoConfig>::GroupStateStorage,
622 <C as IntoConfig>::IdentityProvider,
623 <C as IntoConfig>::MlsRules,
624 <C as IntoConfig>::CryptoProvider,
625>;
626
627pub type MakeConfig<C> = Config<
629 <C as ClientConfig>::KeyPackageRepository,
630 <C as ClientConfig>::PskStore,
631 <C as ClientConfig>::GroupStateStorage,
632 <C as ClientConfig>::IdentityProvider,
633 <C as ClientConfig>::MlsRules,
634 <C as ClientConfig>::CryptoProvider,
635>;
636
637impl<Kpr, Ps, Gss, Ip, Pr, Cp> ClientConfig for ConfigInner<Kpr, Ps, Gss, Ip, Pr, Cp>
638where
639 Kpr: KeyPackageStorage + Clone,
640 Ps: PreSharedKeyStorage + Clone,
641 Gss: GroupStateStorage + Clone,
642 Ip: IdentityProvider + Clone,
643 Pr: MlsRules + Clone,
644 Cp: CryptoProvider + Clone,
645{
646 type KeyPackageRepository = Kpr;
647 type PskStore = Ps;
648 type GroupStateStorage = Gss;
649 type IdentityProvider = Ip;
650 type MlsRules = Pr;
651 type CryptoProvider = Cp;
652
653 fn supported_extensions(&self) -> Vec<ExtensionType> {
654 self.settings.extension_types.clone()
655 }
656
657 fn supported_protocol_versions(&self) -> Vec<ProtocolVersion> {
658 self.settings.protocol_versions.clone()
659 }
660
661 fn key_package_repo(&self) -> Self::KeyPackageRepository {
662 self.key_package_repo.clone()
663 }
664
665 fn mls_rules(&self) -> Self::MlsRules {
666 self.mls_rules.clone()
667 }
668
669 fn secret_store(&self) -> Self::PskStore {
670 self.psk_store.clone()
671 }
672
673 fn group_state_storage(&self) -> Self::GroupStateStorage {
674 self.group_state_storage.clone()
675 }
676
677 fn identity_provider(&self) -> Self::IdentityProvider {
678 self.identity_provider.clone()
679 }
680
681 fn crypto_provider(&self) -> Self::CryptoProvider {
682 self.crypto_provider.clone()
683 }
684
685 fn lifetime(&self, timestamp: Option<MlsTime>) -> Lifetime {
686 #[cfg(feature = "std")]
687 let now_timestamp = MlsTime::now();
688
689 #[cfg(not(feature = "std"))]
690 let now_timestamp = MlsTime::from(0);
691
692 let now_timestamp = if let Some(now_time) = timestamp {
693 now_time
694 } else {
695 now_timestamp
696 };
697
698 #[cfg(test)]
699 let now_timestamp = self
700 .settings
701 .key_package_not_before
702 .unwrap_or(now_timestamp);
703
704 Lifetime {
705 not_before: now_timestamp,
706 not_after: now_timestamp + self.settings.lifetime,
707 }
708 }
709
710 fn supported_custom_proposals(&self) -> Vec<crate::group::proposal::ProposalType> {
711 self.settings.custom_proposal_types.clone()
712 }
713}
714
715impl<Kpr, Ps, Gss, Ip, Pr, Cp> Sealed for Config<Kpr, Ps, Gss, Ip, Pr, Cp> {}
716
717impl<Kpr, Ps, Gss, Ip, Pr, Cp> MlsConfig for Config<Kpr, Ps, Gss, Ip, Pr, Cp>
718where
719 Kpr: KeyPackageStorage + Clone,
720
721 Ps: PreSharedKeyStorage + Clone,
722 Gss: GroupStateStorage + Clone,
723 Ip: IdentityProvider + Clone,
724 Pr: MlsRules + Clone,
725 Cp: CryptoProvider + Clone,
726{
727 type Output = ConfigInner<Kpr, Ps, Gss, Ip, Pr, Cp>;
728
729 fn get(&self) -> &Self::Output {
730 &self.0
731 }
732}
733
734pub trait MlsConfig: Clone + Send + Sync + Sealed {
738 #[doc(hidden)]
739 type Output: ClientConfig;
740
741 #[doc(hidden)]
742 fn get(&self) -> &Self::Output;
743}
744
745impl<T: MlsConfig> ClientConfig for T {
747 type KeyPackageRepository = <T::Output as ClientConfig>::KeyPackageRepository;
748 type PskStore = <T::Output as ClientConfig>::PskStore;
749 type GroupStateStorage = <T::Output as ClientConfig>::GroupStateStorage;
750 type IdentityProvider = <T::Output as ClientConfig>::IdentityProvider;
751 type MlsRules = <T::Output as ClientConfig>::MlsRules;
752 type CryptoProvider = <T::Output as ClientConfig>::CryptoProvider;
753
754 fn supported_extensions(&self) -> Vec<ExtensionType> {
755 self.get().supported_extensions()
756 }
757
758 fn supported_custom_proposals(&self) -> Vec<ProposalType> {
759 self.get().supported_custom_proposals()
760 }
761
762 fn supported_protocol_versions(&self) -> Vec<ProtocolVersion> {
763 self.get().supported_protocol_versions()
764 }
765
766 fn key_package_repo(&self) -> Self::KeyPackageRepository {
767 self.get().key_package_repo()
768 }
769
770 fn mls_rules(&self) -> Self::MlsRules {
771 self.get().mls_rules()
772 }
773
774 fn secret_store(&self) -> Self::PskStore {
775 self.get().secret_store()
776 }
777
778 fn group_state_storage(&self) -> Self::GroupStateStorage {
779 self.get().group_state_storage()
780 }
781
782 fn identity_provider(&self) -> Self::IdentityProvider {
783 self.get().identity_provider()
784 }
785
786 fn crypto_provider(&self) -> Self::CryptoProvider {
787 self.get().crypto_provider()
788 }
789
790 fn lifetime(&self, timestamp: Option<MlsTime>) -> Lifetime {
791 self.get().lifetime(timestamp)
792 }
793
794 fn capabilities(&self) -> Capabilities {
795 self.get().capabilities()
796 }
797
798 fn version_supported(&self, version: ProtocolVersion) -> bool {
799 self.get().version_supported(version)
800 }
801
802 fn supported_credential_types(&self) -> Vec<CredentialType> {
803 self.get().supported_credential_types()
804 }
805}
806
807#[derive(Clone, Debug)]
808pub(crate) struct Settings {
809 pub(crate) extension_types: Vec<ExtensionType>,
810 pub(crate) protocol_versions: Vec<ProtocolVersion>,
811 pub(crate) custom_proposal_types: Vec<ProposalType>,
812 pub(crate) lifetime: Duration,
813 #[cfg(any(test, feature = "test_util"))]
814 pub(crate) key_package_not_before: Option<MlsTime>,
815}
816
817impl Default for Settings {
818 fn default() -> Self {
819 Self {
820 extension_types: Default::default(),
821 protocol_versions: Default::default(),
822 lifetime: 365 * 24 * Duration::from_secs(3600),
823 custom_proposal_types: Default::default(),
824 #[cfg(any(test, feature = "test_util"))]
825 key_package_not_before: None,
826 }
827 }
828}
829
830pub(crate) fn recreate_config<T: ClientConfig>(
831 c: T,
832 signer: Option<SignatureSecretKey>,
833 signing_identity: Option<(SigningIdentity, CipherSuite)>,
834 version: ProtocolVersion,
835 timestamp: Option<MlsTime>,
836) -> MakeConfig<T> {
837 Config(ConfigInner {
838 settings: Settings {
839 extension_types: c.supported_extensions(),
840 protocol_versions: c.supported_protocol_versions(),
841 custom_proposal_types: c.supported_custom_proposals(),
842 lifetime: {
843 let l = c.lifetime(timestamp);
844 l.not_after - l.not_before
845 },
846 #[cfg(any(test, feature = "test_util"))]
847 key_package_not_before: None,
848 },
849 key_package_repo: c.key_package_repo(),
850 psk_store: c.secret_store(),
851 group_state_storage: c.group_state_storage(),
852 identity_provider: c.identity_provider(),
853 mls_rules: c.mls_rules(),
854 crypto_provider: c.crypto_provider(),
855 signer,
856 signing_identity,
857 version,
858 })
859}
860
861mod private {
864 use mls_rs_core::{
865 crypto::{CipherSuite, SignatureSecretKey},
866 identity::SigningIdentity,
867 protocol_version::ProtocolVersion,
868 };
869
870 use crate::client_builder::{IntoConfigOutput, Settings};
871
872 #[derive(Clone, Debug)]
873 pub struct Config<Kpr, Ps, Gss, Ip, Pr, Cp>(pub(crate) ConfigInner<Kpr, Ps, Gss, Ip, Pr, Cp>);
874
875 #[derive(Clone, Debug)]
876 pub struct ConfigInner<Kpr, Ps, Gss, Ip, Pr, Cp> {
877 pub(crate) settings: Settings,
878 pub(crate) key_package_repo: Kpr,
879 pub(crate) psk_store: Ps,
880 pub(crate) group_state_storage: Gss,
881 pub(crate) identity_provider: Ip,
882 pub(crate) mls_rules: Pr,
883 pub(crate) crypto_provider: Cp,
884 pub(crate) signer: Option<SignatureSecretKey>,
885 pub(crate) signing_identity: Option<(SigningIdentity, CipherSuite)>,
886 pub(crate) version: ProtocolVersion,
887 }
888
889 pub trait IntoConfig {
890 type KeyPackageRepository;
891 type PskStore;
892 type GroupStateStorage;
893 type IdentityProvider;
894 type MlsRules;
895 type CryptoProvider;
896
897 fn into_config(self) -> IntoConfigOutput<Self>;
898 }
899
900 impl<Kpr, Ps, Gss, Ip, Pr, Cp> IntoConfig for Config<Kpr, Ps, Gss, Ip, Pr, Cp> {
901 type KeyPackageRepository = Kpr;
902 type PskStore = Ps;
903 type GroupStateStorage = Gss;
904 type IdentityProvider = Ip;
905 type MlsRules = Pr;
906 type CryptoProvider = Cp;
907
908 fn into_config(self) -> Self {
909 self
910 }
911 }
912}
913
914use mls_rs_core::{
915 crypto::{CryptoProvider, SignatureSecretKey},
916 group::GroupStateStorage,
917 identity::IdentityProvider,
918 key_package::KeyPackageStorage,
919 psk::PreSharedKeyStorage,
920};
921use private::{Config, ConfigInner, IntoConfig};
922
923#[cfg(test)]
924pub(crate) mod test_utils {
925 use crate::{
926 client_builder::{BaseConfig, ClientBuilder, WithIdentityProvider},
927 crypto::test_utils::TestCryptoProvider,
928 identity::{
929 basic::BasicIdentityProvider,
930 test_utils::{get_test_signing_identity, BasicWithCustomProvider},
931 },
932 CipherSuite,
933 };
934
935 use super::WithCryptoProvider;
936
937 pub type TestClientConfig = WithIdentityProvider<
938 BasicWithCustomProvider,
939 WithCryptoProvider<TestCryptoProvider, BaseConfig>,
940 >;
941
942 pub type TestClientBuilder = ClientBuilder<TestClientConfig>;
943
944 impl TestClientBuilder {
945 pub fn new_for_test() -> Self {
946 ClientBuilder::new()
947 .crypto_provider(TestCryptoProvider::new())
948 .identity_provider(BasicWithCustomProvider::new(BasicIdentityProvider::new()))
949 }
950
951 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
952 pub async fn with_random_signing_identity(
953 self,
954 identity: &str,
955 cipher_suite: CipherSuite,
956 ) -> Self {
957 let (signing_identity, signer) =
958 get_test_signing_identity(cipher_suite, identity.as_bytes()).await;
959 self.signing_identity(signing_identity, signer, cipher_suite)
960 }
961 }
962}