271 lines
7 KiB
Nix
271 lines
7 KiB
Nix
{ pkgs, shb, ... }:
|
|
let
|
|
port = 9096;
|
|
|
|
commonTestScript = shb.test.mkScripts {
|
|
hasSSL = { node, ... }: !(isNull node.config.shb.jellyfin.ssl);
|
|
waitForServices =
|
|
{ ... }:
|
|
[
|
|
"jellyfin.service"
|
|
"nginx.service"
|
|
];
|
|
waitForPorts =
|
|
{ node, ... }:
|
|
[
|
|
port
|
|
];
|
|
waitForUrls =
|
|
{ proto_fqdn, ... }:
|
|
[
|
|
"${proto_fqdn}/System/Info/Public"
|
|
];
|
|
extraScript =
|
|
{ node, ... }:
|
|
''
|
|
headers = unline_with(" ", """
|
|
-H 'Content-Type: application/json'
|
|
-H 'Authorization: MediaBrowser Client="Android TV", Device="Nvidia Shield", DeviceId="ZQ9YQHHrUzk24vV", Version="0.15.3"'
|
|
""")
|
|
with subtest("api login success"):
|
|
response = curl(client, """{"code":%{response_code}}""", "${node.config.test.proto_fqdn}/Users/AuthenticateByName",
|
|
data="""{"Username": "jellyfin", "Pw": "admin"}""",
|
|
extra=headers)
|
|
if response['code'] != 200:
|
|
raise Exception(f"Expected success, got: {response['code']}")
|
|
|
|
with subtest("api login failure"):
|
|
response = curl(client, """{"code":%{response_code}}""", "${node.config.test.proto_fqdn}/Users/AuthenticateByName",
|
|
data="""{"Username": "jellyfin", "Pw": "badpassword"}""",
|
|
extra=headers)
|
|
if response['code'] != 401:
|
|
raise Exception(f"Expected failure, got: {response['code']}")
|
|
'';
|
|
};
|
|
|
|
basic =
|
|
{ config, ... }:
|
|
{
|
|
imports = [
|
|
shb.test.baseModule
|
|
../../modules/services/jellyfin.nix
|
|
];
|
|
test = {
|
|
subdomain = "j";
|
|
};
|
|
|
|
shb.jellyfin = {
|
|
enable = true;
|
|
inherit (config.test) subdomain domain;
|
|
inherit port;
|
|
admin = {
|
|
username = "jellyfin";
|
|
password.result = config.shb.hardcodedsecret.jellyfinAdminPassword.result;
|
|
};
|
|
debug = true;
|
|
};
|
|
|
|
shb.hardcodedsecret.jellyfinAdminPassword = {
|
|
request = config.shb.jellyfin.admin.password.request;
|
|
settings.content = "admin";
|
|
};
|
|
|
|
environment.systemPackages = [
|
|
pkgs.sqlite
|
|
];
|
|
};
|
|
|
|
clientLogin =
|
|
{ config, ... }:
|
|
{
|
|
imports = [
|
|
shb.test.clientLoginModule
|
|
];
|
|
virtualisation.memorySize = 4096;
|
|
|
|
test = {
|
|
subdomain = "j";
|
|
};
|
|
|
|
test.login = {
|
|
browser = "firefox";
|
|
# I tried without the path part but it randomly selects either the wizard
|
|
# or the page that selects a server.
|
|
# startUrl = "${config.test.proto}://${config.test.fqdn}/web/#/wizardstart.html";
|
|
# startUrl = "${config.test.proto}://${config.test.fqdn}";
|
|
startUrl = "${config.test.proto}://${config.test.fqdn}/web/#/login.html";
|
|
usernameFieldLabelRegex = "[Uu]ser";
|
|
loginButtonNameRegex = "Sign In";
|
|
testLoginWith = [
|
|
# I just couldn't make this work. It's very flaky.
|
|
# Most of the time, the login jellyfin page doesn't even load
|
|
# and the playwright browser is stuck on the splash page.
|
|
# I resorted to test the API directly.
|
|
# { username = "jellyfin"; password = "badpassword"; nextPageExpect = [
|
|
# "expect(page).to_have_title(re.compile('Jellyfin'))"
|
|
# "expect(page.get_by_text(re.compile('[Ii]nvalid'))).to_be_visible(timeout=30000)"
|
|
# ]; }
|
|
# { username = "jellyfin"; password = "admin"; nextPageExpect = [
|
|
# "expect(page).to_have_title(re.compile('Jellyfin'))"
|
|
# "expect(page.get_by_text(re.compile('[Ii]nvalid'))).not_to_be_visible(timeout=30000)"
|
|
# "expect(page.get_by_role('label', re.compile('[Uu]ser'))).not_to_be_visible(timeout=30000)"
|
|
# "expect(page.get_by_text(re.compile('[Pp]assword'))).not_to_be_visible(timeout=30000)"
|
|
# ]; }
|
|
];
|
|
};
|
|
};
|
|
|
|
https =
|
|
{ config, ... }:
|
|
{
|
|
shb.jellyfin = {
|
|
ssl = config.shb.certs.certs.selfsigned.n;
|
|
};
|
|
test = {
|
|
hasSSL = true;
|
|
};
|
|
};
|
|
|
|
ldap =
|
|
{ config, ... }:
|
|
{
|
|
shb.jellyfin = {
|
|
ldap = {
|
|
enable = true;
|
|
host = "127.0.0.1";
|
|
port = config.shb.lldap.ldapPort;
|
|
dcdomain = config.shb.lldap.dcdomain;
|
|
adminPassword.result = config.shb.hardcodedsecret.jellyfinLdapUserPassword.result;
|
|
};
|
|
};
|
|
|
|
shb.hardcodedsecret.jellyfinLdapUserPassword = {
|
|
request = config.shb.jellyfin.ldap.adminPassword.request;
|
|
settings.content = "ldapUserPassword";
|
|
};
|
|
};
|
|
|
|
sso =
|
|
{ config, ... }:
|
|
{
|
|
shb.jellyfin = {
|
|
sso = {
|
|
enable = true;
|
|
endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
|
sharedSecret.result = config.shb.hardcodedsecret.jellyfinSSOPassword.result;
|
|
sharedSecretForAuthelia.result = config.shb.hardcodedsecret.jellyfinSSOPasswordAuthelia.result;
|
|
};
|
|
};
|
|
|
|
shb.hardcodedsecret.jellyfinSSOPassword = {
|
|
request = config.shb.jellyfin.sso.sharedSecret.request;
|
|
settings.content = "ssoPassword";
|
|
};
|
|
|
|
shb.hardcodedsecret.jellyfinSSOPasswordAuthelia = {
|
|
request = config.shb.jellyfin.sso.sharedSecretForAuthelia.request;
|
|
settings.content = "ssoPassword";
|
|
};
|
|
};
|
|
|
|
jellyfinTest =
|
|
name:
|
|
{ nodes, testScript }:
|
|
shb.test.runNixOSTest {
|
|
name = "jellyfin_${name}";
|
|
|
|
interactive.nodes.server = {
|
|
environment.systemPackages = [
|
|
pkgs.sqlite
|
|
];
|
|
};
|
|
|
|
inherit nodes;
|
|
inherit testScript;
|
|
};
|
|
in
|
|
{
|
|
basic = jellyfinTest "basic" {
|
|
nodes.server = {
|
|
imports = [
|
|
basic
|
|
clientLogin
|
|
];
|
|
};
|
|
|
|
# Client login does not work without SSL.
|
|
# At least, I couldn't make it work.
|
|
nodes.client = { };
|
|
|
|
testScript = commonTestScript.access;
|
|
};
|
|
|
|
backup = jellyfinTest "backup" {
|
|
nodes.server =
|
|
{ config, ... }:
|
|
{
|
|
imports = [
|
|
basic
|
|
(shb.test.backup config.shb.jellyfin.backup)
|
|
];
|
|
};
|
|
|
|
nodes.client = { };
|
|
|
|
testScript = commonTestScript.backup;
|
|
};
|
|
|
|
https = jellyfinTest "https" {
|
|
nodes.server = {
|
|
imports = [
|
|
basic
|
|
shb.test.certs
|
|
https
|
|
];
|
|
};
|
|
|
|
nodes.client =
|
|
{ config, lib, ... }:
|
|
{
|
|
imports = [
|
|
shb.test.baseModule
|
|
clientLogin
|
|
];
|
|
};
|
|
|
|
testScript = commonTestScript.access;
|
|
};
|
|
|
|
ldap = jellyfinTest "ldap" {
|
|
nodes.server = {
|
|
imports = [
|
|
basic
|
|
shb.test.ldap
|
|
ldap
|
|
];
|
|
};
|
|
|
|
nodes.client = { };
|
|
|
|
testScript = commonTestScript.access;
|
|
};
|
|
|
|
sso = jellyfinTest "sso" {
|
|
nodes.server =
|
|
{ config, pkgs, ... }:
|
|
{
|
|
imports = [
|
|
basic
|
|
shb.test.certs
|
|
https
|
|
shb.test.ldap
|
|
(shb.test.sso config.shb.certs.certs.selfsigned.n)
|
|
sso
|
|
];
|
|
};
|
|
|
|
nodes.client = { };
|
|
|
|
testScript = commonTestScript.access;
|
|
};
|
|
}
|