summary refs log tree commit diff
path: root/pkgs/games/factorio
diff options
context:
space:
mode:
authorEric Litak <elitak@gmail.com>2018-09-11 17:49:42 -0700
committerEric Litak <elitak@gmail.com>2018-09-20 02:27:42 -0700
commitff22306255bfe0d309485e59ce336cd28f84c884 (patch)
tree9527743b2fdd04e374e379c3bd4187434c5f1a30 /pkgs/games/factorio
parent047c23782c1a0b77734e2334118156cbcea4bcae (diff)
downloadnixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar.gz
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar.bz2
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar.lz
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar.xz
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.tar.zst
nixpkgs-ff22306255bfe0d309485e59ce336cd28f84c884.zip
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.
Diffstat (limited to 'pkgs/games/factorio')
-rw-r--r--pkgs/games/factorio/default.nix104
-rw-r--r--pkgs/games/factorio/fetch.nix33
-rw-r--r--pkgs/games/factorio/fetch.sh55
3 files changed, 73 insertions, 119 deletions
diff --git a/pkgs/games/factorio/default.nix b/pkgs/games/factorio/default.nix
index bb019e57026..4b568a2aaf5 100644
--- a/pkgs/games/factorio/default.nix
+++ b/pkgs/games/factorio/default.nix
@@ -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 {
+    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 = fetcher {
-        inherit sha256;
-        url = "https://www.factorio.com/get-download/${version}/${releaseType}/${arch.inUrl}";
-        name = nameMut "factorio_${releaseType}_${arch.inTar}-${version}.tar.xz";
-      };
+      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
diff --git a/pkgs/games/factorio/fetch.nix b/pkgs/games/factorio/fetch.nix
deleted file mode 100644
index 7dbe2064a5c..00000000000
--- a/pkgs/games/factorio/fetch.nix
+++ /dev/null
@@ -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;
-}
diff --git a/pkgs/games/factorio/fetch.sh b/pkgs/games/factorio/fetch.sh
deleted file mode 100644
index 312dc9b6d61..00000000000
--- a/pkgs/games/factorio/fetch.sh
+++ /dev/null
@@ -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