parent
8e0773688e
commit
df0ff3f095
3 changed files with 48 additions and 24 deletions
|
@ -61,7 +61,7 @@ in {
|
||||||
commands =
|
commands =
|
||||||
concatStringsSep "\n"
|
concatStringsSep "\n"
|
||||||
(map
|
(map
|
||||||
(x: "cp -s \"${pkgs.writeText x.file (toXml x.name x.content)}\" \"/var/lib/jellyfin/config/${x.file}\"")
|
(x: "test ! -e \"/var/lib/jellyfin/config/${x.file}\" && cp -s \"${pkgs.writeText x.file (toXml x.name x.content)}\" \"/var/lib/jellyfin/config/${x.file}\"")
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name = "NetworkConfiguration";
|
name = "NetworkConfiguration";
|
||||||
|
@ -92,8 +92,6 @@ in {
|
||||||
sq = "${pkgs.sqlite}/bin/sqlite3 \"${path}/${dbname}\" --";
|
sq = "${pkgs.sqlite}/bin/sqlite3 \"${path}/${dbname}\" --";
|
||||||
path = "/var/lib/jellyfin/data";
|
path = "/var/lib/jellyfin/data";
|
||||||
|
|
||||||
# ${sq} "INSERT INTO Users (Id, AudioLanguagePreference, AuthenticationProviderId, DisplayCollectionsView, DisplayMissingEpisodes, EnableAutoLogin, EnableLocalPassword, EnableNextEpisodeAutoPlay, EnableUserPreferenceAccess, HidePlayedInLatest, InternalId, LoginAttemptsBeforeLockout, MaxActiveSessions, MaxParentalAgeRating, Password, HashedPasswordFile, PasswordResetProviderId, PlayDefaultAudioTrack, RememberAudioSelections, RememberSubtitleSelections, RemoteClientBitrateLimit, SubtitleLanguagePreference, SubtitleMode, SyncPlayAccess, Username, CastReceiverId) \
|
|
||||||
# VALUES(${user.})"
|
|
||||||
genUser = index: user: let
|
genUser = index: user: let
|
||||||
values =
|
values =
|
||||||
builtins.mapAttrs
|
builtins.mapAttrs
|
||||||
|
@ -103,21 +101,23 @@ in {
|
||||||
if value
|
if value
|
||||||
then "1"
|
then "1"
|
||||||
else "0"
|
else "0"
|
||||||
|
else if (isNull value)
|
||||||
|
then "NULL"
|
||||||
else value)
|
else value)
|
||||||
(cfg.Users
|
(user
|
||||||
// {
|
// {
|
||||||
Id =
|
Id =
|
||||||
if (builtins.hasAttr "Id" cfg.Users)
|
if !(isNull user.Id)
|
||||||
then cfg.Users.Id
|
then user.Id
|
||||||
else "$(${pkgs.libuuid}/bin/uuidgen | ${pkgs.coreutils}/bin/tr '[:lower:]' '[:upper:]')";
|
else "$(${pkgs.libuuid}/bin/uuidgen | ${pkgs.coreutils}/bin/tr '[:lower:]' '[:upper:]')";
|
||||||
InternalId =
|
InternalId =
|
||||||
if (builtins.hasAttr "InternalId" cfg.Users)
|
if !(isNull user.InternalId)
|
||||||
then cfg.Users.InternalId
|
then user.InternalId
|
||||||
else "$(($maxIndex+${index + 1}))";
|
else "$(($maxIndex+${toString (index + 1)}))";
|
||||||
Password =
|
Password =
|
||||||
if (hasAttr "HashedPasswordFile" cfg.Users)
|
if !(isNull user.HashedPasswordFile)
|
||||||
then "$(${pkgs.coreutils}/bin/cat \"${cfg.Users.HashedPasswordFile}\")"
|
then "$(${pkgs.coreutils}/bin/cat \"${user.HashedPasswordFile}\")"
|
||||||
else "$(${self.packages.${pkgs.system}.genhash}/bin/genhash -k \"${cfg.Users.Password}\" -i 210000 -l 128 -u)";
|
else "$(${self.packages.${pkgs.system}.genhash}/bin/genhash -k \"${user.Password}\" -i 210000 -l 128 -u)";
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
/*
|
/*
|
||||||
|
@ -130,9 +130,9 @@ in {
|
||||||
(
|
(
|
||||||
builtins.filter (x: x != "HashedPasswordFile")
|
builtins.filter (x: x != "HashedPasswordFile")
|
||||||
(lib.attrsets.mapAttrsToList (name: value: "${name}")
|
(lib.attrsets.mapAttrsToList (name: value: "${name}")
|
||||||
options.services.declarative-jellyfin.Users.options)
|
((import ./options/users.nix {inherit lib;}).options.services.declarative-jellyfin.Users.type.getSubOptions []))
|
||||||
)}) \\
|
)}) \\
|
||||||
VALUES(${builtins.attrValues values})"
|
VALUES(${concatStringsSep "," (map toString (builtins.attrValues values))})"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
|
@ -144,6 +144,7 @@ in {
|
||||||
# Make sure there is a database
|
# Make sure there is a database
|
||||||
if [ ! -e "${path}/${dbname}" ]; then
|
if [ ! -e "${path}/${dbname}" ]; then
|
||||||
cp ${defaultDB} "${path}/${dbname}"
|
cp ${defaultDB} "${path}/${dbname}"
|
||||||
|
chmod 770 "${path}/${dbname}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
maxIndex=$(${sq} 'SELECT InternalId FROM Users ORDER BY InternalId DESC LIMIT 1')
|
maxIndex=$(${sq} 'SELECT InternalId FROM Users ORDER BY InternalId DESC LIMIT 1')
|
||||||
|
@ -151,6 +152,23 @@ in {
|
||||||
maxIndex="1"
|
maxIndex="1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
${
|
||||||
|
concatStringsSep "\n"
|
||||||
|
(
|
||||||
|
map ({
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
}:
|
||||||
|
genUser snd fst)
|
||||||
|
(
|
||||||
|
lib.lists.zipLists cfg.Users
|
||||||
|
(
|
||||||
|
builtins.genList (x: x)
|
||||||
|
(builtins.length cfg.Users)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,17 @@ with lib; {
|
||||||
# Based on: https://github.com/jellyfin/jellyfin/blob/master/MediaBrowser.Model/Configuration/UserConfiguration.cs
|
# Based on: https://github.com/jellyfin/jellyfin/blob/master/MediaBrowser.Model/Configuration/UserConfiguration.cs
|
||||||
Users = mkOption {
|
Users = mkOption {
|
||||||
description = "User configuration";
|
description = "User configuration";
|
||||||
|
default = [];
|
||||||
type = lib.types.listOf (lib.types.submodule ({config, ...}: {
|
type = lib.types.listOf (lib.types.submodule ({config, ...}: {
|
||||||
options = {
|
options = {
|
||||||
Id = mkOption {
|
Id = mkOption {
|
||||||
type = types.str; # TODO: Limit the id to the pattern: "18B51E25-33FD-46B6-BBF8-DB4DD77D0679"
|
type = types.nullOr types.str; # TODO: Limit the id to the pattern: "18B51E25-33FD-46B6-BBF8-DB4DD77D0679"
|
||||||
description = "The ID of the user";
|
description = "The ID of the user";
|
||||||
example = "18B51E25-33FD-46B6-BBF8-DB4DD77D0679";
|
example = "18B51E25-33FD-46B6-BBF8-DB4DD77D0679";
|
||||||
|
default = null;
|
||||||
};
|
};
|
||||||
AudioLanguagePreference = mkOption {
|
AudioLanguagePreference = mkOption {
|
||||||
type = with types; either null str;
|
type = with types; nullOr str;
|
||||||
description = "The audio language preference. Defaults to 'Any Language'";
|
description = "The audio language preference. Defaults to 'Any Language'";
|
||||||
default = null;
|
default = null;
|
||||||
example = "eng";
|
example = "eng";
|
||||||
|
@ -63,10 +65,11 @@ with lib; {
|
||||||
example = false;
|
example = false;
|
||||||
};
|
};
|
||||||
InternalId = mkOption {
|
InternalId = mkOption {
|
||||||
type = types.int;
|
type = with types; nullOr int;
|
||||||
# NOTE: index is 1-indexed! NOT 0-indexed.
|
# NOTE: index is 1-indexed! NOT 0-indexed.
|
||||||
description = "The index of the user in the database. Be careful setting this option. 1 indexed.";
|
description = "The index of the user in the database. Be careful setting this option. 1 indexed.";
|
||||||
example = 69;
|
example = 69;
|
||||||
|
default = null;
|
||||||
};
|
};
|
||||||
LoginAttemptsBeforeLockout = mkOption {
|
LoginAttemptsBeforeLockout = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
|
@ -81,15 +84,16 @@ with lib; {
|
||||||
example = 5;
|
example = 5;
|
||||||
};
|
};
|
||||||
MaxParentalAgeRating = mkOption {
|
MaxParentalAgeRating = mkOption {
|
||||||
type = with types; either null int;
|
type = with types; nullOr int;
|
||||||
# idk no docs man
|
# idk no docs man
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
Password = mkOption {
|
Password = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
default = "";
|
||||||
};
|
};
|
||||||
HashedPasswordFile = mkOption {
|
HashedPasswordFile = mkOption {
|
||||||
type = types.path;
|
type = with types; either path str;
|
||||||
description = ''
|
description = ''
|
||||||
A path to a pbkdf2-sha512 hash
|
A path to a pbkdf2-sha512 hash
|
||||||
in this format [PHC string](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md).
|
in this format [PHC string](https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md).
|
||||||
|
@ -106,6 +110,7 @@ with lib; {
|
||||||
|
|
||||||
```
|
```
|
||||||
'';
|
'';
|
||||||
|
default = "";
|
||||||
example = ''
|
example = ''
|
||||||
# the format is: $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
# the format is: $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
||||||
$PBKDF2-SHA512$iterations=210000$D12C02D1DD15949D867BCA9971BE9987$67E75CDCD14E7F6FDDF96BAACBE9E84E5197FB9FE454FB039F5CD773D7DF558B57DC81DB42B6F7CF0E6B8207A771E5C0EE0DBFD91CE5BAF804FE53F70E61CD2E
|
$PBKDF2-SHA512$iterations=210000$D12C02D1DD15949D867BCA9971BE9987$67E75CDCD14E7F6FDDF96BAACBE9E84E5197FB9FE454FB039F5CD773D7DF558B57DC81DB42B6F7CF0E6B8207A771E5C0EE0DBFD91CE5BAF804FE53F70E61CD2E
|
||||||
|
@ -135,7 +140,7 @@ with lib; {
|
||||||
default = 0;
|
default = 0;
|
||||||
};
|
};
|
||||||
SubtitleLanguagePreference = mkOption {
|
SubtitleLanguagePreference = mkOption {
|
||||||
type = with types; either null str;
|
type = with types; nullOr str;
|
||||||
description = "The subtitle language preference. Defaults to 'Any Language'";
|
description = "The subtitle language preference. Defaults to 'Any Language'";
|
||||||
default = null;
|
default = null;
|
||||||
example = "eng";
|
example = "eng";
|
||||||
|
|
|
@ -16,8 +16,9 @@ in {
|
||||||
|
|
||||||
virtualisation.memorySize = 1024;
|
virtualisation.memorySize = 1024;
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = with pkgs; [
|
||||||
pkgs.sqlite
|
sqlite
|
||||||
|
file
|
||||||
];
|
];
|
||||||
|
|
||||||
services.declarative-jellyfin = {
|
services.declarative-jellyfin = {
|
||||||
|
@ -40,9 +41,9 @@ in {
|
||||||
machine.start()
|
machine.start()
|
||||||
machine.wait_for_unit("multi-user.target");
|
machine.wait_for_unit("multi-user.target");
|
||||||
machine.succeed("file /var/lib/jellyfin/data/jellyfin.db")
|
machine.succeed("file /var/lib/jellyfin/data/jellyfin.db")
|
||||||
users = machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users WHERE Username = 'admin'\"")
|
users = machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users\"")
|
||||||
print(users)
|
print(users)
|
||||||
if users == "":
|
if machine.succeed("sqlite3 /var/lib/jellyfin/data/jellyfin.db -- \"SELECT * FROM Users WHERE Username = 'admin'\"") == "":
|
||||||
assert False, "User not in db"
|
assert False, "User not in db"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue