Skip to content

Commit

Permalink
Disable local auth (#834)
Browse files Browse the repository at this point in the history
* fix(backend): handle edge case

* docs: add info about new users config

* feat(config): new config param

Also change the descriptions of old ones.

* feat(backend): core details for disabling local auth

* feat(frontend): respect new config param

* fix(frontend): do not display collections group if none

* fix(backend): get manga and anime specifics correct

* fix(backend): calculate manga specifics correctly

* fix(backend): calculate anime specifics correctly

* build(backend): bump version
  • Loading branch information
IgnisDa committed May 14, 2024
1 parent 56ce050 commit b30f912
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 123 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ryot"
version = "5.3.3"
version = "5.3.4"
edition = "2021"
repository = "https://github.com/IgnisDa/ryot"
license = "GPL-3.0"
Expand Down
16 changes: 9 additions & 7 deletions apps/backend/src/miscellaneous/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ struct CoreDetails {
page_limit: i32,
timezone: String,
token_valid_for_days: i64,
local_auth_disabled: bool,
oidc_enabled: bool,
}

Expand Down Expand Up @@ -1464,12 +1465,13 @@ impl MiscellaneousService {
async fn core_details(&self) -> Result<CoreDetails> {
Ok(CoreDetails {
timezone: self.timezone.to_string(),
author_name: AUTHOR.to_owned(),
docs_link: "https://docs.ryot.io".to_owned(),
repository_link: "https://github.com/ignisda/ryot".to_owned(),
page_limit: self.config.frontend.page_size,
token_valid_for_days: self.config.users.token_valid_for_days,
author_name: AUTHOR.to_owned(),
oidc_enabled: self.oidc_client.is_some(),
repository_link: "https://github.com/ignisda/ryot".to_owned(),
local_auth_disabled: self.config.users.disable_local_auth,
token_valid_for_days: self.config.users.token_valid_for_days,
})
}

Expand Down Expand Up @@ -4761,19 +4763,19 @@ impl MiscellaneousService {
ls.media.movies.runtime += r;
units_consumed = Some(r);
}
} else if let Some(item) = meta.anime_specifics {
} else if let Some(_item) = meta.anime_specifics {
ls.unique_items.anime.insert(meta.id);
if let Some(s) = seen.anime_extra_information.to_owned() {
if let (Some(_), Some(episode)) = (item.episodes, s.episode) {
if let Some(episode) = s.episode {
ls.unique_items.anime_episodes.insert((meta.id, episode));
units_consumed = Some(1);
}
}
} else if let Some(item) = meta.manga_specifics {
} else if let Some(_item) = meta.manga_specifics {
ls.unique_items.manga.insert(meta.id);
if let Some(s) = seen.manga_extra_information.to_owned() {
units_consumed = Some(1);
if let (Some(_), Some(chapter)) = (item.chapters, s.chapter) {
if let Some(chapter) = s.chapter {
ls.unique_items.manga_chapters.insert((meta.id, chapter));
}
if let Some(volume) = s.volume {
Expand Down
32 changes: 17 additions & 15 deletions apps/backend/src/providers/anilist/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,24 +594,26 @@ async fn media_details(client: &Client, id: &str, prefer_english: bool) -> Resul
}),
);
let people = people.into_iter().unique().collect_vec();
let lot = match details.type_.unwrap() {
media_details_query::MediaType::ANIME => MediaLot::Anime,
media_details_query::MediaType::MANGA => MediaLot::Manga,
let (lot, anime_specifics, manga_specifics) = match details.type_.unwrap() {
media_details_query::MediaType::ANIME => (
MediaLot::Anime,
Some(AnimeSpecifics {
episodes: details.episodes.and_then(|c| c.try_into().ok()),
}),
None,
),
media_details_query::MediaType::MANGA => (
MediaLot::Manga,
None,
Some(MangaSpecifics {
chapters: details.chapters.and_then(|c| c.try_into().ok()),
volumes: details.volumes.and_then(|v| v.try_into().ok()),
url: None,
}),
),
media_details_query::MediaType::Other(_) => unreachable!(),
};

let anime_specifics = details.episodes.map(|c| AnimeSpecifics {
episodes: c.try_into().ok(),
});
let manga_specifics = details
.chapters
.zip(details.volumes)
.map(|(c, v)| MangaSpecifics {
chapters: c.try_into().ok(),
volumes: v.try_into().ok(),
url: None,
});

let year = details
.start_date
.and_then(|b| b.year.map(|y| y.try_into().unwrap()));
Expand Down
5 changes: 4 additions & 1 deletion apps/backend/src/providers/igdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,10 @@ where id = {id};
.map_err(|e| anyhow!(e))?;
let mut details: Vec<IgdbInvolvedCompany> =
rsp.body_json().await.map_err(|e| anyhow!(e))?;
let detail = details.pop().map(|ic| ic.company).unwrap();
let detail = details
.pop()
.map(|ic| ic.company)
.ok_or_else(|| anyhow!("No data"))?;
let mut related = detail
.published
.unwrap_or_default()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,22 @@ export default function Page() {
{loaderData.metadataGroupDetails.details.parts} media items
</Text>
</Flex>
<Group>
{loaderData.userMetadataGroupDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.metadataGroupId.toString()}
entityLot={EntityLot.MediaGroup}
/>
))}
{loaderData.metadataGroupDetails.details.isPartial ? (
<MediaIsPartial mediaType="group" />
) : null}
</Group>
{loaderData.userMetadataGroupDetails.collections.length > 0 ? (
<Group>
{loaderData.userMetadataGroupDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.metadataGroupId.toString()}
entityLot={EntityLot.MediaGroup}
/>
))}
</Group>
) : null}
{loaderData.metadataGroupDetails.details.isPartial ? (
<MediaIsPartial mediaType="group" />
) : null}
<Tabs variant="outline" defaultValue={loaderData.query.defaultTab}>
<Tabs.List mb="xs">
<Tabs.Tab value="media" leftSection={<IconDeviceTv size={16} />}>
Expand Down
34 changes: 18 additions & 16 deletions apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -553,23 +553,25 @@ export default function Page() {
<Title id="media-title">{loaderData.mediaMainDetails.title}</Title>
</Box>
<UserMetadataDetailsSuspenseLoader>
{(userMetadataDetails) => (
<Group>
{userMetadataDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.metadataId.toString()}
entityLot={EntityLot.Media}
/>
))}
{loaderData.mediaMainDetails.isPartial ? (
<MediaIsPartial mediaType="media" />
) : null}
</Group>
)}
{(userMetadataDetails) =>
userMetadataDetails.collections.length > 0 ? (
<Group>
{userMetadataDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.metadataId.toString()}
entityLot={EntityLot.Media}
/>
))}
</Group>
) : null
}
</UserMetadataDetailsSuspenseLoader>
{loaderData.mediaMainDetails.isPartial ? (
<MediaIsPartial mediaType="media" />
) : null}
<MediaAdditionalDetailsSuspenseLoader>
{(mediaAdditionalDetails) => (
<Text c="dimmed" fz={{ base: "sm", lg: "md" }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,20 +195,22 @@ export default function Page() {
</>
) : null}
</Text>
<Group>
{loaderData.userPersonDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.personId.toString()}
entityLot={EntityLot.Person}
/>
))}
{loaderData.personDetails.details.isPartial ? (
<MediaIsPartial mediaType="person" />
) : null}
</Group>
{loaderData.userPersonDetails.collections.length > 0 ? (
<Group>
{loaderData.userPersonDetails.collections.map((col) => (
<DisplayCollection
key={col.id}
col={col}
userId={col.userId}
entityId={loaderData.personId.toString()}
entityLot={EntityLot.Person}
/>
))}
</Group>
) : null}
{loaderData.personDetails.details.isPartial ? (
<MediaIsPartial mediaType="person" />
) : null}
<Tabs variant="outline" defaultValue={loaderData.query.defaultTab}>
<Tabs.List mb="xs">
<Tabs.Tab value="media" leftSection={<IconDeviceTv size={16} />}>
Expand Down
83 changes: 43 additions & 40 deletions apps/frontend/app/routes/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
return json({
defaultForm: query.defaultForm || "login",
oidcEnabled: coreDetails.oidcEnabled,
localAuthDisabled: coreDetails.localAuthDisabled,
tokenValidForDays: coreDetails.tokenValidForDays,
signupAllowed: enabledFeatures.signupAllowed,
});
Expand Down Expand Up @@ -206,54 +207,56 @@ export default function Page() {
m="auto"
w={{ base: "80%", sm: "60%", md: "50%", lg: "40%", xl: "30%" }}
>
<Form
method="post"
action={withQuery(".", { intent })}
{...getFormProps(form)}
ref={parent}
>
<input
type="hidden"
name="tokenValidForDays"
defaultValue={loaderData.tokenValidForDays}
/>
{redirectValue ? (
{!loaderData.localAuthDisabled ? (
<Form
method="post"
action={withQuery(".", { intent })}
{...getFormProps(form)}
ref={parent}
>
<input
type="hidden"
name={redirectToQueryParam}
defaultValue={redirectValue}
name="tokenValidForDays"
defaultValue={loaderData.tokenValidForDays}
/>
{redirectValue ? (
<input
type="hidden"
name={redirectToQueryParam}
defaultValue={redirectValue}
/>
) : null}
<TextInput
{...getInputProps(fields.username, { type: "text" })}
label="Username"
autoFocus
required
error={fields.username.errors?.[0]}
/>
) : null}
<TextInput
{...getInputProps(fields.username, { type: "text" })}
label="Username"
autoFocus
required
error={fields.username.errors?.[0]}
/>
<PasswordInput
label="Password"
{...getInputProps(fields.password, { type: "password" })}
mt="md"
required
error={fields.password.errors?.[0]}
/>
{intent === "register" ? (
<PasswordInput
label="Confirm password"
label="Password"
{...getInputProps(fields.password, { type: "password" })}
mt="md"
{...getInputProps(fields.confirm, { type: "password" })}
required
error={fields.confirm.errors?.[0]}
error={fields.password.errors?.[0]}
/>
) : null}
<Button id="submit-button" mt="md" type="submit" w="100%">
{startCase(intent)}
</Button>
</Form>
{intent === "register" ? (
<PasswordInput
label="Confirm password"
mt="md"
{...getInputProps(fields.confirm, { type: "password" })}
required
error={fields.confirm.errors?.[0]}
/>
) : null}
<Button id="submit-button" mt="md" type="submit" w="100%">
{startCase(intent)}
</Button>
</Form>
) : null}
{loaderData.oidcEnabled ? (
<>
<Divider label="OR" />
{!loaderData.localAuthDisabled ? <Divider label="OR" /> : null}
<Form method="post" action="?intent=getOauthRedirectUrl" replace>
<Button
variant="outline"
Expand All @@ -267,7 +270,7 @@ export default function Page() {
</Form>
</>
) : null}
{loaderData.signupAllowed ? (
{loaderData.signupAllowed && !loaderData.localAuthDisabled ? (
<Anchor
ta="right"
component={Link}
Expand Down
3 changes: 3 additions & 0 deletions docs/content/guides/openid.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ username set to their email address. This can be changed later in the profile se
!!! warning

A user can authenticate using only one provider at a time.

You can set `USERS_DISABLE_LOCAL_AUTH=true` to disable local authentication and only allow
users to authenticate using OIDC.
8 changes: 4 additions & 4 deletions docs/includes/backend-config-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@ users:
# @envvar USERS_ALLOW_REGISTRATION
allow_registration: true

# The number of days till login auth token is valid.
# The number of days till login authentication token is valid.
# @envvar USERS_TOKEN_VALID_FOR_DAYS
token_valid_for_days: 90

# Whether to validate the password for users. Should be set to false only for testing.
# @envvar USERS_VALIDATE_PASSWORD
validate_password: true
# Whether to disable local user authentication completely.
# @envvar USERS_DISABLE_LOCAL_AUTH
disable_local_auth: false

# Settings related to video games.
video_games:
Expand Down
9 changes: 6 additions & 3 deletions libs/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,14 @@ pub struct UsersConfig {
/// Whether new users will be allowed to sign up to this instance.
#[setting(default = true)]
pub allow_registration: bool,
/// The number of days till login auth token is valid.
/// The number of days till login authentication token is valid.
#[setting(default = 90)]
pub token_valid_for_days: i64,
/// Whether to validate the password for users. Should be set to false only for testing.
#[setting(default = true)]
/// Whether to disable local user authentication completely.
#[setting(default = false)]
pub disable_local_auth: bool,
/// Whether to validate password for users.
#[setting(default = true, skip)]
pub validate_password: bool,
}

Expand Down

0 comments on commit b30f912

Please sign in to comment.