factorio: download using token, not password
Downloads were broken by upstream devs' addition of CAPTCHA to the login form. We now need only a slightly modified fetchurl to retrieve the binary distribution.
This commit is contained in:
parent
047c23782c
commit
ff22306255
@ -3,7 +3,7 @@
|
||||
, factorio-utils
|
||||
, releaseType
|
||||
, mods ? []
|
||||
, username ? "" , password ? ""
|
||||
, username ? "", token ? "" # get/reset token at https://factorio.com/profile
|
||||
, experimental ? false
|
||||
}:
|
||||
|
||||
@ -13,59 +13,101 @@ assert releaseType == "alpha"
|
||||
|
||||
let
|
||||
|
||||
# NB If you nix-prefetch-url any of these, be sure to add a --name arg,
|
||||
# where the ultimate "_" (before the version) is changed to a "-".
|
||||
helpMsg = ''
|
||||
|
||||
===FETCH FAILED===
|
||||
Please ensure you have set the username and token with config.nix, or
|
||||
/etc/nix/nixpkgs-config.nix if on NixOS.
|
||||
|
||||
Your token can be seen at https://factorio.com/profile (after logging in). It is
|
||||
not as sensitive as your password, but should still be safeguarded. There is a
|
||||
link on that page to revoke/invalidate the token, if you believe it has been
|
||||
leaked or wish to take precautions.
|
||||
|
||||
Example:
|
||||
{
|
||||
packageOverrides = pkgs: {
|
||||
factorio = pkgs.factorio.override {
|
||||
username = "FactorioPlayer1654";
|
||||
token = "d5ad5a8971267c895c0da598688761";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Alternatively, instead of providing the username+token, you may manually
|
||||
download the release through https://factorio.com/download , then add it to
|
||||
the store using e.g.:
|
||||
|
||||
releaseType=alpha
|
||||
version=0.16.51
|
||||
nix-prefetch-url file://$HOME/Downloads/factorio_\''${releaseType}_x64_\''${version}.tar.xz --name factorio_\''${releaseType}_x64-\''${version}.tar.xz
|
||||
|
||||
Note the ultimate "_" is replaced with "-" in the --name arg!
|
||||
'';
|
||||
|
||||
branch = if experimental then "experimental" else "stable";
|
||||
|
||||
binDists = {
|
||||
x86_64-linux = let bdist = bdistForArch { inUrl = "linux64"; inTar = "x64"; }; in {
|
||||
alpha = {
|
||||
stable = bdist { sha256 = "0b4hbpdcrh5hgip9q5dkmw22p66lcdhnr0kmb0w5dw6yi7fnxxh0"; fetcher = authenticatedFetch; };
|
||||
experimental = bdist { sha256 = "1qwfivl5wf0ii8c4prdl4yili23qimsh2cj874r37q3ygpjk3bd3"; version = "0.16.50"; fetcher = authenticatedFetch; };
|
||||
stable = bdist { sha256 = "0b4hbpdcrh5hgip9q5dkmw22p66lcdhnr0kmb0w5dw6yi7fnxxh0"; version = "0.16.51"; withAuth = true; };
|
||||
experimental = bdist { sha256 = "1qwfivl5wf0ii8c4prdl4yili23qimsh2cj874r37q3ygpjk3bd3"; version = "0.16.50"; withAuth = true; };
|
||||
};
|
||||
headless = {
|
||||
stable = bdist { sha256 = "0zrnpg2js0ysvx9y50h3gajldk16mv02dvrwnkazh5kzr1d9zc3c"; };
|
||||
stable = bdist { sha256 = "0zrnpg2js0ysvx9y50h3gajldk16mv02dvrwnkazh5kzr1d9zc3c"; version = "0.16.51"; };
|
||||
experimental = bdist { sha256 = "00691kr85p58qpxf3889p20nrgsvsyspx3c8yd11dkg46wly06z1"; version = "0.16.50"; };
|
||||
};
|
||||
demo = {
|
||||
stable = bdist { sha256 = "0zf61z8937yd8pyrjrqdjgd0rjl7snwrm3xw86vv7s7p835san6a"; version = "0.16.51"; };
|
||||
experimental = bdist { };
|
||||
};
|
||||
};
|
||||
i686-linux = let bdist = bdistForArch { inUrl = "linux32"; inTar = "i386"; }; in {
|
||||
alpha = {
|
||||
stable = bdist { sha256 = "0nnfkxxqnywx1z05xnndgh71gp4izmwdk026nnjih74m2k5j086l"; version = "0.14.23"; nameMut = asGz; };
|
||||
experimental = bdist { };
|
||||
};
|
||||
headless = {
|
||||
stable = bdist { };
|
||||
experimental = bdist { };
|
||||
};
|
||||
demo = {
|
||||
stable = bdist { };
|
||||
experimental = bdist { };
|
||||
stable = bdist { sha256 = "0nnfkxxqnywx1z05xnndgh71gp4izmwdk026nnjih74m2k5j086l"; version = "0.14.23"; withAuth = true; nameMut = asGz; };
|
||||
};
|
||||
};
|
||||
};
|
||||
actual = binDists.${stdenv.hostPlatform.system}.${releaseType}.${branch} or (throw "Factorio: unsupported platform");
|
||||
|
||||
bdistForArch = arch: { sha256 ? null
|
||||
, version ? "0.16.51"
|
||||
, fetcher ? fetchurl
|
||||
actual = binDists.${stdenv.hostPlatform.system}.${releaseType}.${branch} or (throw "Factorio ${releaseType}-${branch} binaries for ${stdenv.hostPlatform.system} are not available for download.");
|
||||
|
||||
bdistForArch = arch: { version
|
||||
, sha256
|
||||
, withAuth ? false
|
||||
, nameMut ? x: x
|
||||
}:
|
||||
if sha256 == null then
|
||||
throw "Factorio ${releaseType}-${arch.inTar} binaries are not (and were never?) available to download"
|
||||
else {
|
||||
inherit version arch;
|
||||
src = fetcher {
|
||||
inherit sha256;
|
||||
url = "https://www.factorio.com/get-download/${version}/${releaseType}/${arch.inUrl}";
|
||||
let
|
||||
url = "https://factorio.com/get-download/${version}/${releaseType}/${arch.inUrl}";
|
||||
name = nameMut "factorio_${releaseType}_${arch.inTar}-${version}.tar.xz";
|
||||
in {
|
||||
inherit version arch;
|
||||
src =
|
||||
if withAuth then
|
||||
(stdenv.lib.overrideDerivation
|
||||
(fetchurl {
|
||||
inherit name url sha256;
|
||||
curlOpts = [
|
||||
"--get"
|
||||
"--data-urlencode" "username@username"
|
||||
"--data-urlencode" "token@token"
|
||||
];
|
||||
})
|
||||
(_: { # This preHook hides the credentials from /proc
|
||||
preHook = ''
|
||||
echo -n "${username}" >username
|
||||
echo -n "${token}" >token
|
||||
'';
|
||||
failureHook = ''
|
||||
cat <<EOF
|
||||
${helpMsg}
|
||||
EOF
|
||||
'';
|
||||
})
|
||||
)
|
||||
else
|
||||
fetchurl { inherit name url sha256; };
|
||||
};
|
||||
};
|
||||
authenticatedFetch = callPackage ./fetch.nix { inherit username password; };
|
||||
asGz = builtins.replaceStrings [".xz"] [".gz"];
|
||||
|
||||
asGz = builtins.replaceStrings [".xz"] [".gz"];
|
||||
|
||||
configBaseCfg = ''
|
||||
use-system-read-write-data-directories=false
|
||||
|
@ -1,33 +0,0 @@
|
||||
{ stdenv, curl, xidel, cacert
|
||||
# Begin download parameters
|
||||
, username ? ""
|
||||
, password ? ""
|
||||
}:
|
||||
|
||||
{
|
||||
# URL to fetch.
|
||||
url ? ""
|
||||
|
||||
, name ? "factorio.tar.gz"
|
||||
|
||||
# Login URL.
|
||||
, loginUrl ? "https://www.factorio.com/login"
|
||||
|
||||
# SHA256 of the fetched URL.
|
||||
, sha256 ? ""
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
nativeBuildInputs = [ curl xidel ];
|
||||
|
||||
inherit name url loginUrl username password cacert;
|
||||
|
||||
builder = ./fetch.sh;
|
||||
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = sha256;
|
||||
outputHashMode = "flat";
|
||||
|
||||
# There's no point in downloading remotely, we'd just slow things down.
|
||||
preferLocalBuild = true;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
source $stdenv/setup
|
||||
|
||||
# Curl flags to increase reliability a bit.
|
||||
#
|
||||
# Can't use fetchurl, for several reasons. One is that we definitely
|
||||
# don't want --insecure for the login, though we need it for the
|
||||
# download as their download cert isn't in the standard linux bundle.
|
||||
curl="curl \
|
||||
--max-redirs 20 \
|
||||
--retry 3 \
|
||||
--cacert $cacert/etc/ssl/certs/ca-bundle.crt \
|
||||
-b cookies \
|
||||
-c cookies \
|
||||
$curlOpts \
|
||||
$NIX_CURL_FLAGS"
|
||||
|
||||
# We don't want the password to be on any program's argv, as it may be
|
||||
# visible in /proc. Writing it to file with echo should be safe, since
|
||||
# it's a shell builtin.
|
||||
echo -n "$password" > password
|
||||
# Might as well hide the username as well.
|
||||
echo -n "$username" > username
|
||||
|
||||
# Get a CSRF token.
|
||||
csrf=$($curl $loginUrl | xidel - -e '//input[@id="csrf_token"]/@value')
|
||||
|
||||
# Log in. We don't especially care about the result, but let's check if login failed.
|
||||
$curl --data-urlencode csrf_token="$csrf" \
|
||||
--data-urlencode username_or_email@username \
|
||||
--data-urlencode password@password \
|
||||
-d action=Login \
|
||||
$loginUrl -D headers > /dev/null
|
||||
|
||||
if grep -q 'Location: https://' headers; then
|
||||
# Now download. We need --insecure for this, but the sha256 should cover us.
|
||||
$curl --insecure --location --fail $url > $out || { echo "Login succeeded, but subsequent fetch failed."; exit 1; }
|
||||
set +x
|
||||
else
|
||||
set +x
|
||||
echo 'Login failed'
|
||||
echo 'Please set username and password with config.nix,'
|
||||
echo 'or /etc/nix/nixpkgs-config.nix if on NixOS.'
|
||||
echo
|
||||
echo 'Example:'
|
||||
echo '{'
|
||||
echo ' packageOverrides = pkgs: rec {'
|
||||
echo ' factorio = pkgs.factorio.override {'
|
||||
echo ' username = "<username or email address>";'
|
||||
echo ' password = "<password>";'
|
||||
echo ' };'
|
||||
echo ' };'
|
||||
echo '}'
|
||||
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in New Issue
Block a user