#[non_exhaustive]pub struct ServerConfig {Show 25 fields
pub app_id: String,
pub master_key: String,
pub master_key_ips: IpAllowlist,
pub maintenance_key: Option<String>,
pub maintenance_key_ips: IpAllowlist,
pub javascript_key: Option<String>,
pub rest_api_key: Option<String>,
pub client_key: Option<String>,
pub dot_net_key: Option<String>,
pub mount_path: String,
pub enable_sanitized_error_response: bool,
pub has_push_support: bool,
pub has_push_scheduled_support: bool,
pub security_check_enabled: bool,
pub features: FeatureSupport,
pub session: SessionConfig,
pub protected_fields: ProtectedFieldsConfig,
pub protected_fields_owner_exempt: bool,
pub protected_fields_save_response_exempt: bool,
pub allow_custom_object_id: bool,
pub allow_client_class_creation: bool,
pub allow_origin: Vec<String>,
pub allow_headers: Vec<String>,
pub batch_request_limit: i64,
pub create_index_role_name: bool,
}Expand description
The keys and identity a request is checked against.
#[non_exhaustive], decided at 0.2.1 rather than inherited. This release adds two public
fields, which already breaks any ServerConfig { .. } literal outside this crate, and cargo
resolves 0.2.1 as compatible with 0.2.0 and will upgrade into it unasked. Marking it here means
the break happens once, in the release that was going to cause it anyway, instead of again
every time an option is added. Construction is ServerConfig::new followed by field
assignment, which is what every call site in this repository already does and what the
attribute still permits.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.app_id: String§master_key: String§master_key_ips: IpAllowlistmasterKeyIps, default ['127.0.0.1', '::1'] (Options/Definitions.js:396-399), enforced
at middlewares.js:452.
The default is a control and 0.2.0 shipped without it, so the master key was honoured
from any source address on a server nobody had configured. A master key presented from an
address outside this list is refused outright rather than downgraded to a client request:
upstream throws a bare 403 (middlewares.js:453-462) instead of falling through.
maintenance_key: Option<String>maintenanceKey. Grants the same ACL treatment as the master key and is not the same
authority: validateClientClassCreation exempts both on a write and master alone on a read
(RestWrite.js:200-202, RestQuery.js:486-489).
Reachable only from Rust, deliberately. The binary exposes no variable for it, and the
reason changed in 0.2.1: it used to be that parse-rust had no IP filter, and now it has one.
What remains is that master and maintenance are one AclScope internally, so every decision
other than the one corrected above treats them alike. Shipping the key through the CLI would
advertise an authority this server only partly distinguishes.
Not to be confused with the read-only master key, which is a third credential, sets
isMaster upstream (Auth.js:63), and is not modeled at all.
maintenance_key_ips: IpAllowlistmaintenanceKeyIps, same default and same enforcement (Options/Definitions.js:385-388,
middlewares.js:438).
Carried alongside master_key_ips rather than deferred. The two options are one mechanism
with two call sites, and filtering one key while leaving the other unfiltered would close a
hole and leave its twin open one header away. The exposure is narrower, because a
maintenance key has no default value and only exists once an operator sets one.
javascript_key: Option<String>§rest_api_key: Option<String>§client_key: Option<String>§dot_net_key: Option<String>§mount_path: StringWhere the API is mounted, e.g. /parse. A builder input, never inferred from the
request path: axum’s nest and Express’s app.use differ here, and every generated
file URL is built from this value.
enable_sanitized_error_response: boolenableSanitizedErrorResponse, default true (Options/Definitions.js:253-258).
When true, every denial upstream routes through createSanitizedError or
createSanitizedHttpError (Error.js:13-43) says Permission denied instead of naming
the rule that refused. That is the configuration an unmodified deployment runs, so it is
what every SDK sees by default. Read it as ServerConfig::error_detail rather than as a
bare bool at a call site.
has_push_support: bool§has_push_scheduled_support: bool§security_check_enabled: bool§features: FeatureSupportWhat /serverInfo advertises. Defaults to the truth: nothing unimplemented.
session: SessionConfigsessionLength and expireInactiveSessions, which together decide _Session.expiresAt.
Defaults are upstream’s (Options/Definitions.js:629-634, :269-274).
protected_fields: ProtectedFieldsConfigprotectedFields. See default_protected_fields for the merge rule.
protected_fields_owner_exempt: boolprotectedFieldsOwnerExempt, default true (Options/Definitions.js:501-506). When true a
user reading their own _User row sees every field regardless of protectedFields.
protected_fields_save_response_exempt: boolprotectedFieldsSaveResponseExempt, default true (Options/Definitions.js:507-512).
When true, a create or update response carries protected fields the write touched. When false they are stripped from the response as they are from a query result. parse-rust only ever echoes back the keys whose request value was an operation, so this narrows that echo rather than a whole object.
allow_custom_object_id: boolallowCustomObjectId, default false (Options/Definitions.js:73-78).
Two effects, and the second is easy to forget because it is in a different file. It gates
whether a create may carry its own objectId (RestWrite.js:50-65, enforced by
enforce_object_id_policy), and it widens the objectId grammar a CLP entity key is
matched against, from ^[a-zA-Z0-9]{1,}$ to ^.{1,}$ (SchemaController.js:726-731).
The two are one option because a CLP naming a user by id has to be able to name a user whose id the client chose.
allow_client_class_creation: boolallowClientClassCreation, default false (Options/Definitions.js:67-72).
Gates whether a write may bring a class into existence. Enforced by
validateClientClassCreation in the write pipeline, which exempts master, maintenance and
the classes Parse defines itself.
The default matters more than the option. Left unimplemented, a server behaves as though
this were true, which lets a caller holding only the app id and client key create classes
without limit on a database parse-server nodes also read, each with a default-open CLP.
allow_origin: Vec<String>allowOrigin, default ["*"] (middlewares.js:407-408).
A list rather than one value, because upstream accepts either and echoes back whichever
entry matches the request’s Origin. An unmatched origin gets the first entry, so a
single-element list is an allowlist of one rather than a wildcard.
allow_headers: Vec<String>allowHeaders. Appended to DEFAULT_ALLOWED_HEADERS rather than replacing it
(middlewares.js:402-405), so a deployment adding one custom header does not have to
restate the twelve a Parse SDK needs.
batch_request_limit: i64requestComplexity.batchRequestLimit, default -1, which disables it
(Options/Definitions.js:733-738). Master and maintenance bypass it (batch.js:73).
create_index_role_name: booldatabaseOptions.createIndexRoleName, default true (Options/Definitions.js:1318-1323),
created at DatabaseController.js:2033-2038.
Not cosmetic. Without the index two _Role rows can carry the same name, and an ACL
entry of role:X then grants every member of both, which is a privilege-escalation path
rather than a duplicate-data annoyance. Upstream tests !== false, so anything other than
an explicit false creates it.
Implementations§
Source§impl ServerConfig
impl ServerConfig
pub fn new(app_id: impl Into<String>, master_key: impl Into<String>) -> Self
Sourcepub fn error_detail(&self) -> ErrorDetail
pub fn error_detail(&self) -> ErrorDetail
Whether a denial tells the client why.
The one place enable_sanitized_error_response becomes an ErrorDetail, so no call site
has to remember which way round the bool runs.
Sourcepub fn object_id_form(&self) -> ObjectIdForm
pub fn object_id_form(&self) -> ObjectIdForm
How a CLP entity key that looks like an objectId is matched.
Sourcepub fn clp_validation(&self) -> ClpValidation
pub fn clp_validation(&self) -> ClpValidation
What CLP validation accepts.
Unenforceable::Accept, because the read and write pipelines enforce all three of the
features the toggle guards: per-operation pointerFields, the class-wide readUserFields
and writeUserFields arrays (ClassLevelPermissions::applicable_pointer_fields), and
userField: protected-field entries (ProtectedFieldPlan::user_field_rules). Refusing
them would reject a CLP this server honors.
Sourcepub fn permission_options(&self) -> PermissionOptions
pub fn permission_options(&self) -> PermissionOptions
The permission options the read and write pipelines take.
pub fn javascript_key(self, k: impl Into<String>) -> Self
pub fn rest_api_key(self, k: impl Into<String>) -> Self
pub fn mount_path(self, p: impl Into<String>) -> Self
Sourcepub fn requires_client_key(&self) -> bool
pub fn requires_client_key(&self) -> bool
True when any client key is configured. Upstream’s rule is all-or-nothing: if any of
these is set, a non-master request must present one that matches
(middlewares.js:255-265). If none is configured, none is required.
Trait Implementations§
Source§impl Clone for ServerConfig
impl Clone for ServerConfig
Source§fn clone(&self) -> ServerConfig
fn clone(&self) -> ServerConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ServerConfig
impl RefUnwindSafe for ServerConfig
impl Send for ServerConfig
impl Sync for ServerConfig
impl Unpin for ServerConfig
impl UnsafeUnpin for ServerConfig
impl UnwindSafe for ServerConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.