Merge branch 'nixpkg_update' into 'main'

updates nix packages and removes immae-nix

See merge request hacc/infra/haccfiles!26
This commit is contained in:
Schweby mit Hut 2021-02-10 22:54:28 +00:00
commit fbcd19f8a3
12 changed files with 33 additions and 23617 deletions

View file

@ -3,7 +3,6 @@ let
sources = import ../nix/sources.nix;
in {
imports = [
"${sources.immae-nix}/modules/webapps/peertube.nix"
./nftnat
./decklink.nix
];

View file

@ -5,36 +5,29 @@
"homepage": "https://nix-community.github.io/home-manager/",
"owner": "nix-community",
"repo": "home-manager",
"rev": "91bd34620d73340be03642279ee0d1c64110ee6c",
"sha256": "1pwn2w21rmnk7nqzx9wmgb4k4kph7vfd1r9wcq9xdn7w27cjdg7v",
"rev": "209566c752c4428c7692c134731971193f06b37c",
"sha256": "1canlfkm09ssbgm3hq0kb9d86bdh84jhidxv75g98zq5wgadk7jm",
"type": "tarball",
"url": "https://github.com/nix-community/home-manager/archive/91bd34620d73340be03642279ee0d1c64110ee6c.tar.gz",
"url": "https://github.com/nix-community/home-manager/archive/209566c752c4428c7692c134731971193f06b37c.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"immae-nix": {
"branch": "master",
"ref": "master",
"repo": "https://git.immae.eu/perso/Immae/Config/Nix.git",
"rev": "238587099b92027ad780053f0f6217ad88b61ad2",
"type": "git"
},
"niv": {
"branch": "master",
"description": "Easy dependency management for Nix projects",
"homepage": "https://github.com/nmattia/niv",
"owner": "nmattia",
"repo": "niv",
"rev": "3cd7914b2c4cff48927e11c216dadfab7d903fe5",
"sha256": "1agq4nvbhrylf2s77kb4xhh9k7xcwdwggq764k4jgsbs70py8cw3",
"rev": "af958e8057f345ee1aca714c1247ef3ba1c15f5e",
"sha256": "1qjavxabbrsh73yck5dcq8jggvh3r2jkbr6b5nlz5d9yrqm9255n",
"type": "tarball",
"url": "https://github.com/nmattia/niv/archive/3cd7914b2c4cff48927e11c216dadfab7d903fe5.tar.gz",
"url": "https://github.com/nmattia/niv/archive/af958e8057f345ee1aca714c1247ef3ba1c15f5e.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nix-hexchen": {
"branch": "main",
"ref": "main",
"repo": "https://gitlab.com/hexchen/nixfiles.git",
"rev": "412491716b9a64dd4f436d9949cb7c26b669519c",
"rev": "c87f132c9d3932e61ddfeea50a6f810a19d41f79",
"type": "git"
},
"nixos-mailserver": {
@ -52,10 +45,10 @@
"homepage": "",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "85abeab48b5feda4b163e5bb32f50aad1164e415",
"sha256": "1nslb5p6cf5z691pf52j8bf880sdgav1fcf7bxjk3rad92bniq5g",
"rev": "d4c29df154dc6397ea47a7ed7dd0450a46dd4695",
"sha256": "015xcdirr9vh49dszgfb2rayr6mqscmmv2d3dh99ghv8gjcv050y",
"type": "tarball",
"url": "https://github.com/nixos/nixpkgs/archive/85abeab48b5feda4b163e5bb32f50aad1164e415.tar.gz",
"url": "https://github.com/nixos/nixpkgs/archive/d4c29df154dc6397ea47a7ed7dd0450a46dd4695.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs-unstable": {
@ -64,17 +57,17 @@
"homepage": "",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "891f607d5301d6730cb1f9dcf3618bcb1ab7f10e",
"sha256": "1cr39f0sbr0h5d83dv1q34mcpwnkwwbdk5fqlyqp2mnxghzwssng",
"rev": "8c8731330b53ba0061686f36f10f101e662a4717",
"sha256": "0ak4d254myq6cl3d7jkq6n0apxabvwjz62zdw9habnrqg8asl8gk",
"type": "tarball",
"url": "https://github.com/nixos/nixpkgs/archive/891f607d5301d6730cb1f9dcf3618bcb1ab7f10e.tar.gz",
"url": "https://github.com/nixos/nixpkgs/archive/8c8731330b53ba0061686f36f10f101e662a4717.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"pbb-nixfiles": {
"branch": "main",
"ref": "main",
"repo": "https://git.petabyte.dev/petabyteboy/nixfiles.git",
"rev": "0720c5dba283d782f2f887bf97aad339137d95dc",
"rev": "65e6159cbab6ba36b985d2ae7495cf68e0233393",
"type": "git"
}
}

View file

@ -6,33 +6,25 @@ let
# The fetchers. fetch_<type> fetches specs of type <type>.
#
fetch_file = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
in
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
else
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
fetch_file = pkgs: spec:
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; }
else
pkgs.fetchurl { inherit (spec) url sha256; };
fetch_tarball = pkgs: name: spec:
let
name' = sanitizeName name + "-src";
ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str);
# sanitize the name, though nix will still fail if name starts with period
name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src";
in
if spec.builtin or true then
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
else
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
fetch_git = name: spec:
let
ref =
if spec ? ref then spec.ref else
if spec ? branch then "refs/heads/${spec.branch}" else
if spec ? tag then "refs/tags/${spec.tag}" else
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
fetch_git = spec:
builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; };
fetch_local = spec: spec.path;
@ -48,21 +40,11 @@ let
# Various helpers
#
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
sanitizeName = name:
(
concatMapStrings (s: if builtins.isList s then "-" else s)
(
builtins.split "[^[:alnum:]+._?=-]+"
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
)
);
# The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources: system:
mkPkgs = sources:
let
sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {};
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in
@ -82,9 +64,9 @@ let
if ! builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs name spec
else if spec.type == "file" then fetch_file pkgs spec
else if spec.type == "tarball" then fetch_tarball pkgs name spec
else if spec.type == "git" then fetch_git name spec
else if spec.type == "git" then fetch_git spec
else if spec.type == "local" then fetch_local spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
else if spec.type == "builtin-url" then fetch_builtin-url name
@ -116,29 +98,25 @@ let
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
optionalAttrs = cond: as: if cond then as else {};
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
builtins_fetchTarball = { url, name, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
in
if lessThan nixVersion "1.12" then
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
fetchTarball { inherit name url; }
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
builtins_fetchurl = { url, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
in
if lessThan nixVersion "1.12" then
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
fetchurl { inherit url; }
else
fetchurl attrs;
@ -157,8 +135,7 @@ let
mkConfig =
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
, pkgs ? mkPkgs sources
}: rec {
# The sources, i.e. the attribute set of spec name to spec
inherit sources;

View file

@ -7,7 +7,6 @@ let
callPackage = pkgs.lib.callPackageWith (pkgs // newpkgs);
newpkgs = {
peertube = callPackage ./peertube { mylibs = import "${sources.immae-nix}/lib" { inherit pkgs; }; };
alps = callPackage ./alps {};
docker = pkgs.docker.overrideAttrs (super: {

File diff suppressed because it is too large Load diff

View file

@ -1,207 +0,0 @@
{ ldap ? false, sendmail ? false, light ? null, syden ? false, runCommand, libsass
, lib, stdenv, rsync, fetchzip, youtube-dl, fetchurl, mylibs, python, nodejs, nodePackages, yarn2nix-moretea }:
let
nodeHeaders = fetchurl {
url = "https://nodejs.org/download/release/v${nodejs.version}/node-v${nodejs.version}-headers.tar.gz";
sha256 = "17kf05a92r4y4n1lj78265wr6zhkpzbr1k8nbwrl8sq71npd6n5j";
};
source = mylibs.fetchedGithub ./peertube.json;
patchedSource = stdenv.mkDerivation (source // rec {
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
patches = [ ./yarn_fix_http_node.patch ]
++ lib.optionals ldap [ ./ldap.patch ]
++ lib.optionals sendmail [ ./sendmail.patch ]
++ lib.optionals syden [ ./syden.patch ];
installPhase = ''
mkdir $out
cp -a . $out/
'';
});
serverPatchedPackage = runCommand "server-package" {} ''
mkdir -p $out
cp ${patchedSource}/package.json $out/
cp ${patchedSource}/yarn.lock $out/
'';
clientPatchedPackage = runCommand "client-package" {} ''
mkdir -p $out
cp ${patchedSource}/client/package.json $out/
cp ${patchedSource}/client/yarn.lock $out/
'';
yarnModulesConfig = {
bcrypt = {
buildInputs = [ nodePackages.node-pre-gyp ];
postInstall = let
node_module_version = "72";
bcrypt_lib = fetchurl {
url = "https://github.com/kelektiv/node.bcrypt.js/releases/download/v3.0.7/bcrypt_lib-v3.0.7-node-v${node_module_version}-linux-x64-glibc.tar.gz";
sha256 = "0kpm9j0yc4lqsafldfsql3m72rr1fapljlb6ddxvy3zi13rb7ppx";
};
in
''
if [ "$(node -e "console.log(process.versions.modules)")" != "${node_module_version}" ]; then
echo "mismatching version with nodejs please update bcrypt derivation"
false
fi
mkdir lib && tar -C lib -xf ${bcrypt_lib}
patchShebangs ../node-pre-gyp
npm run install
'';
};
dtrace-provider = {
buildInputs = [ python nodePackages.node-gyp ];
postInstall = ''
npx node-gyp rebuild --tarball=${nodeHeaders}
'';
};
node-sass = {
buildInputs = [ libsass python ];
postInstall =
''
node scripts/build.js --tarball=${nodeHeaders}
'';
};
sharp = {
buildInputs = [ python nodePackages.node-gyp ];
postInstall =
let
tarball = fetchurl {
url = "https://github.com/lovell/sharp-libvips/releases/download/v8.8.1/libvips-8.8.1-linux-x64.tar.gz";
sha256 = "0xqv61g6s6rkvc31zq9a3bf8rp56ijnpw0xhr91hc88asqprd5yh";
};
in
''
mkdir vendor
tar -C vendor -xf ${tarball}
patchShebangs ../prebuild-install
npx node install/libvips
npx node install/dll-copy
npx prebuild-install || npx node-gyp rebuild --tarball=${nodeHeaders}
'';
};
utf-8-validate = {
buildInputs = [ nodePackages.node-gyp-build ];
};
youtube-dl = {
postInstall = ''
mkdir bin
ln -s ${youtube-dl}/bin/youtube-dl bin/youtube-dl
cat > bin/details <<EOF
{"version":"${youtube-dl.version}","path":null,"exec":"youtube-dl"}
EOF
'';
};
};
serverYarnModulesArg = rec {
pname = "peertube-server-yarn-modules";
version = source.version;
name = "${pname}-${version}";
packageJSON = "${serverPatchedPackage}/package.json";
yarnLock = "${serverPatchedPackage}/yarn.lock";
yarnNix = ./server-yarn-packages.nix;
pkgConfig = yarnModulesConfig;
};
clientYarnModulesArg = rec {
pname = "peertube-client-yarn-modules";
version = source.version;
name = "${pname}-${version}";
packageJSON = "${clientPatchedPackage}/package.json";
yarnLock = "${clientPatchedPackage}/yarn.lock";
yarnNix = ./client-yarn-packages.nix;
pkgConfig = yarnModulesConfig;
};
yarnModulesNoWorkspace = args: (yarn2nix-moretea.mkYarnModules args).overrideAttrs(old: {
buildPhase = builtins.replaceStrings [" ./package.json"] [" /dev/null; cp deps/*/package.json ."] old.buildPhase;
});
patchedPackages = stdenv.mkDerivation (source // rec {
patches = if ldap then [ ./ldap.patch ] else [ ./yarn_fix_http_node.patch ];
installPhase = ''
mkdir $out
cp package.json yarn.lock $out/
'';
});
serverYarnModules = yarnModulesNoWorkspace serverYarnModulesArg;
serverYarnModulesProd = yarnModulesNoWorkspace (serverYarnModulesArg // { yarnFlags = yarn2nix-moretea.defaultYarnFlags ++ [ "--production" ]; });
clientYarnModules = yarnModulesNoWorkspace clientYarnModulesArg;
server = stdenv.mkDerivation ({
pname = "peertube-server";
version = source.version;
src = patchedSource;
buildPhase = ''
ln -s ${serverYarnModules}/node_modules .
npm run build:server
'';
installPhase = ''
mkdir $out
cp -a dist $out
'';
buildInputs = [ nodejs serverYarnModules ];
});
client = stdenv.mkDerivation ({
pname = "peertube-client";
version = source.version;
src = patchedSource;
buildPhase = let
lightArg = if light == null then "" else if light == true then "--light" else "--light-language";
in ''
ln -s ${serverYarnModules}/node_modules .
cp -a ${clientYarnModules}/node_modules client/
chmod +w client/node_modules
patchShebangs .
npm run build:client -- ${lightArg}
'';
installPhase = ''
mkdir $out
cp -a client/dist $out
'';
buildInputs = [ nodejs clientYarnModules ];
});
package = stdenv.mkDerivation rec {
version = source.version;
pname = "peertube";
src = patchedSource;
buildPhase = ''
ln -s ${serverYarnModulesProd}/node_modules .
ln -s ${clientYarnModules}/node_modules client/
rm -rf dist && cp -a ${server}/dist dist
rm -rf client/dist && cp -a ${client}/dist client/
'';
installPhase = ''
mkdir $out
cp -a * $out
ln -s /tmp $out/.cache
'';
meta = {
description = "A free software to take back control of your videos";
longDescription = ''
PeerTube aspires to be a decentralized and free/libre alternative to video
broadcasting services.
PeerTube is not meant to become a huge platform that would centralize
videos from all around the world. Rather, it is a network of
inter-connected small videos hosters.
Anyone with a modicum of technical skills can host a PeerTube server, aka
an instance. Each instance hosts its users and their videos. In this way,
every instance is created, moderated and maintained independently by
various administrators.
You can still watch from your account videos hosted by other instances
though if the administrator of your instance had previously connected it
with other instances.
'';
license = stdenv.lib.licenses.agpl3Plus;
homepage = "https://joinpeertube.org/";
platforms = stdenv.lib.platforms.linux; # not sure here
maintainers = with stdenv.lib.maintainers; [ matthiasbeyer immae ];
};
};
in
package

View file

@ -1,597 +0,0 @@
commit ffb4a59047a014d6bb050b67a2fc7bc116be4682
Author: Ismaël Bouya <ismael.bouya@normalesup.org>
Date: Tue Feb 12 18:47:53 2019 +0100
Add LDAP authentication
diff --git a/config/default.yaml b/config/default.yaml
index 3260c62fc..dcce721b9 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -51,6 +51,19 @@ redis:
auth: null
db: 0
+auth:
+ local:
+ enabled: true
+ ldap:
+ enabled: true
+ url: ldap://localhost:389/dc=example,dc=com
+ insecure_tls: false
+ bind_dn: cn=admin,dc=example,dc=com
+ bind_password: adminPass
+ base: dc=example,dc=com
+ mail_entry: "mail"
+ user_filter: "(|(email=%username%)(uid=%username%))"
+
smtp:
hostname: null
port: 465
diff --git a/config/production.yaml.example b/config/production.yaml.example
index 30cd2ffe0..c56691bf4 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -51,6 +51,19 @@ redis:
auth: null
db: 0
+auth:
+ local:
+ enabled: true
+ ldap:
+ enabled: true
+ url: ldap://localhost:389/dc=example,dc=com
+ insecure_tls: false
+ bind_dn: cn=admin,dc=example,dc=com
+ bind_password: adminPass
+ base: dc=example,dc=com
+ mail_entry: "mail"
+ user_filter: "(|(email=%username%)(uid=%username%))"
+
# SMTP server to send emails
smtp:
hostname: null
diff --git a/package.json b/package.json
index 49d9faf97..31eccf797 100644
--- a/package.json
+++ b/package.json
@@ -112,6 +112,7 @@
"iso-639-3": "^1.0.1",
"js-yaml": "^3.5.4",
"jsonld": "~2.0.1",
+ "ldapjs": "^1.0.2",
"lodash": "^4.17.10",
"lru-cache": "^5.1.1",
"magnet-uri": "^5.1.4",
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 7fd77f3e8..45a667826 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -34,6 +34,21 @@ const CONFIG = {
AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
DB: config.has('redis.db') ? config.get<number>('redis.db') : null
},
+ AUTH: {
+ LOCAL: {
+ ENABLED: config.has('auth.local.enabled') ? config.get<boolean>('auth.local.enabled') : true,
+ },
+ LDAP: {
+ ENABLED: config.has('auth.ldap.enabled') ? config.get<boolean>('auth.ldap.enabled') : false,
+ URL: config.has('auth.ldap.url') ? config.get<string>('auth.ldap.url') : null,
+ INSECURE_TLS: config.has('auth.ldap.insecure_tls') ? config.get<boolean>('auth.ldap.insecure_tls') : false,
+ BIND_DN: config.has('auth.ldap.bind_dn') ? config.get<string>('auth.ldap.bind_dn') : null,
+ BIND_PASSWORD: config.has('auth.ldap.bind_password') ? config.get<string>('auth.ldap.bind_password') : null,
+ BASE: config.has('auth.ldap.base') ? config.get<string>('auth.ldap.base') : null,
+ MAIL_ENTRY: config.has('auth.ldap.mail_entry') ? config.get<string>('auth.ldap.mail_entry') : 'mail',
+ USER_FILTER: config.has('auth.ldap.user_filter') ? config.get<string>('auth.ldap.user_filter') : null
+ },
+ },
SMTP: {
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
diff --git a/server/initializers/migrations/0375-user-ldap-dn.ts b/server/initializers/migrations/0375-user-ldap-dn.ts
new file mode 100644
index 000000000..a9d68124b
--- /dev/null
+++ b/server/initializers/migrations/0375-user-ldap-dn.ts
@@ -0,0 +1,26 @@
+import * as Sequelize from 'sequelize'
+
+async function up (utils: {
+ transaction: Sequelize.Transaction,
+ queryInterface: Sequelize.QueryInterface,
+ sequelize: Sequelize.Sequelize
+}): Promise<void> {
+
+ {
+ const data = {
+ type: Sequelize.STRING,
+ allowNull: true,
+ defaultValue: null
+ }
+ await utils.queryInterface.addColumn('user', 'ldapDn', data)
+ }
+}
+
+function down (options) {
+ throw new Error('Not implemented.')
+}
+
+export {
+ up,
+ down
+}
diff --git a/server/lib/ldap.ts b/server/lib/ldap.ts
new file mode 100644
index 000000000..e6601e5cb
--- /dev/null
+++ b/server/lib/ldap.ts
@@ -0,0 +1,89 @@
+import * as express from 'express'
+import { createClient, Client, parseFilter } from 'ldapjs'
+import { logger } from '../helpers/logger'
+import { CONFIG } from '../initializers/config'
+
+class Ldap {
+
+ private static instance: Ldap
+ private initialized = false
+ private client: Client
+ private prefix: string
+
+ private constructor () {}
+
+ init () {
+ // Already initialized
+ if (this.initialized === true) return
+ this.initialized = true
+
+ this.client = createClient(Ldap.getLdapClientOptions())
+ }
+
+ static getLdapClientOptions () {
+ return Object.assign({}, {
+ url: CONFIG.AUTH.LDAP.URL,
+ reconnect: true,
+ tlsOptions: { rejectUnauthorized: !CONFIG.AUTH.LDAP.INSECURE_TLS }
+ })
+ }
+
+ getClient () {
+ this.init()
+ return this.client
+ }
+
+ findUser (username: string) {
+ const filter = parseFilter(CONFIG.AUTH.LDAP.USER_FILTER)
+ filter.forEach(function (element) {
+ if (element.value === '%username%') element.value = username
+ })
+ const opts = {
+ filter,
+ scope: 'sub',
+ attributes: [ CONFIG.AUTH.LDAP.MAIL_ENTRY, 'dn' ]
+ }
+
+ const client = this.getClient()
+
+ return new Promise(function (resolve, reject) {
+ client.bind(CONFIG.AUTH.LDAP.BIND_DN, CONFIG.AUTH.LDAP.BIND_PASSWORD, function (err) {
+ if (err) reject(err)
+ let entries = []
+ client.search(CONFIG.AUTH.LDAP.BASE, opts, function (err, search) {
+ if (err) reject(err)
+ search.on('searchEntry', function (entry) {
+ entries.push(entry.object)
+ })
+ search.on('end', function (result) {
+ if (entries.length === 1) {
+ resolve(entries[0])
+ } else {
+ reject("No user found corresponding to this username")
+ }
+ })
+ })
+ })
+ })
+ }
+
+ checkUser (dn: string, password: string) {
+ const client = this.getClient()
+ return new Promise(function (resolve, reject) {
+ client.bind(dn, password, function (err) {
+ resolve(!err)
+ })
+ })
+ }
+
+
+ static get Instance () {
+ return this.instance || (this.instance = new this())
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+ Ldap
+}
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
index 086856f41..ab10effd0 100644
--- a/server/lib/oauth-model.ts
+++ b/server/lib/oauth-model.ts
@@ -9,6 +9,7 @@ import { Transaction } from 'sequelize'
import { CONFIG } from '../initializers/config'
import * as LRUCache from 'lru-cache'
import { MOAuthTokenUser } from '@server/typings/models/oauth/oauth-token'
+import { MUserDefault } from '@server/typings/models'
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
@@ -74,7 +75,13 @@ function getRefreshToken (refreshToken: string) {
async function getUser (usernameOrEmail: string, password: string) {
logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).')
- const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ let user : MUserDefault
+ if (CONFIG.AUTH.LDAP.ENABLED) {
+ user = await UserModel.findOrCreateLDAPUser(usernameOrEmail)
+ }
+ if (!user && CONFIG.AUTH.LOCAL.ENABLED) {
+ user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ }
if (!user) return null
const passwordMatch = await user.isPasswordMatch(password)
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 4c2c5e278..0b38f7cb2 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -1,4 +1,5 @@
import { FindOptions, literal, Op, QueryTypes, where, fn, col } from 'sequelize'
+import { Ldap } from '../../lib/ldap'
import {
AfterDestroy,
AfterUpdate,
@@ -50,7 +51,9 @@ import { AccountModel } from './account'
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
import { values } from 'lodash'
import { DEFAULT_THEME_NAME, DEFAULT_USER_THEME_NAME, NSFW_POLICY_TYPES } from '../../initializers/constants'
+import { CONFIG } from '../../initializers/config'
import { clearCacheByUserId } from '../../lib/oauth-model'
+import { createUserAccountAndChannelAndPlaylist } from '../../lib/user'
import { UserNotificationSettingModel } from './user-notification-setting'
import { VideoModel } from '../video/video'
import { ActorModel } from '../activitypub/actor'
@@ -149,6 +152,11 @@ export class UserModel extends Model<UserModel> {
@Column(DataType.STRING(400))
pendingEmail: string
+ @AllowNull(true)
+ @Default(null)
+ @Column
+ ldapDn: string
+
@AllowNull(true)
@Default(null)
@Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean', true))
@@ -440,6 +448,48 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query)
}
+ static loadByLdapDn (ldapDn: string) {
+ const query = {
+ where: {
+ ldapDn
+ }
+ }
+
+ return UserModel.findOne(query)
+ }
+
+ static async findOrCreateLDAPUser (username: string) {
+ try {
+ const userInfos = await Ldap.Instance.findUser(username)
+ const user = await UserModel.loadByLdapDn(userInfos['dn'])
+ if (user) {
+ return user
+ } else {
+ return await UserModel.createLDAPUser(username, userInfos)
+ }
+ } catch (e) {
+ return null
+ }
+ }
+
+ static async createLDAPUser (username: string, userInfos: {}) {
+ const userToCreate = new UserModel({
+ username,
+ password: 'SomeInvalidPassword',
+ email: userInfos[CONFIG.AUTH.LDAP.MAIL_ENTRY],
+ ldapDn: userInfos['dn'],
+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
+ autoPlayVideo: true,
+ role: UserRole.USER,
+ videoQuota: CONFIG.USER.VIDEO_QUOTA,
+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
+ emailVerified: true,
+ adminFlags: UserAdminFlag.NONE
+ })
+ const { user } = await createUserAccountAndChannelAndPlaylist({ userToCreate })
+ return user
+ }
+
static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> {
const query = {
where: {
@@ -627,7 +677,11 @@ export class UserModel extends Model<UserModel> {
}
isPasswordMatch (password: string) {
- return comparePassword(password, this.password)
+ if (this.ldapDn === null) {
+ return comparePassword(password, this.password)
+ } else {
+ return Ldap.Instance.checkUser(this.ldapDn, password)
+ }
}
toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User {
diff --git a/yarn.lock b/yarn.lock
index 76ce7ed27..f087746df 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -616,6 +616,11 @@ arraybuffer.slice@~0.0.7:
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
+asn1@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+ integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=
+
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@@ -623,6 +628,11 @@ asn1@~0.2.3:
dependencies:
safer-buffer "~2.1.0"
+assert-plus@0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
+ integrity sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=
+
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
@@ -692,6 +702,13 @@ backo2@1.0.2:
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
+backoff@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f"
+ integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=
+ dependencies:
+ precond "0.2"
+
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -1001,6 +1018,16 @@ bull@^3.4.2:
util.promisify "^1.0.0"
uuid "^3.3.3"
+bunyan@^1.8.3:
+ version "1.8.12"
+ resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
+ integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=
+ optionalDependencies:
+ dtrace-provider "~0.8"
+ moment "^2.10.6"
+ mv "~2"
+ safe-json-stringify "~1"
+
busboy@^0.2.11:
version "0.2.14"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
@@ -1619,7 +1646,7 @@ d@1, d@^1.0.1:
es5-ext "^0.10.50"
type "^1.0.1"
-dashdash@^1.12.0:
+dashdash@^1.12.0, dashdash@^1.14.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
@@ -1845,6 +1872,13 @@ double-ended-queue@^2.1.0-0:
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
+dtrace-provider@~0.8:
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e"
+ integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==
+ dependencies:
+ nan "^2.14.0"
+
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@@ -2228,6 +2262,11 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+extsprintf@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.2.0.tgz#5ad946c22f5b32ba7f8cd7426711c6e8a3fc2529"
+ integrity sha1-WtlGwi9bMrp/jNdCZxHG6KP8JSk=
+
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@@ -2567,6 +2606,17 @@ glob@7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
+ integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=
+ dependencies:
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "2 || 3"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
glob@^7.0.3, glob@^7.1.1, glob@^7.1.3:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
@@ -3356,6 +3406,30 @@ latest-version@^3.0.0:
dependencies:
package-json "^4.0.0"
+ldap-filter@0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/ldap-filter/-/ldap-filter-0.2.2.tgz#f2b842be0b86da3352798505b31ebcae590d77d0"
+ integrity sha1-8rhCvguG2jNSeYUFsx68rlkNd9A=
+ dependencies:
+ assert-plus "0.1.5"
+
+ldapjs@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-1.0.2.tgz#544ff7032b7b83c68f0701328d9297aa694340f9"
+ integrity sha1-VE/3Ayt7g8aPBwEyjZKXqmlDQPk=
+ dependencies:
+ asn1 "0.2.3"
+ assert-plus "^1.0.0"
+ backoff "^2.5.0"
+ bunyan "^1.8.3"
+ dashdash "^1.14.0"
+ ldap-filter "0.2.2"
+ once "^1.4.0"
+ vasync "^1.6.4"
+ verror "^1.8.1"
+ optionalDependencies:
+ dtrace-provider "~0.8"
+
libxmljs@0.19.7:
version "0.19.7"
resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.19.7.tgz#96c2151b0b73f33dd29917edec82902587004e5a"
@@ -3724,7 +3798,7 @@ mimic-response@^2.0.0:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
-minimatch@3.0.4, minimatch@^3.0.4:
+"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -3825,7 +3899,7 @@ moment-timezone@^0.5.21, moment-timezone@^0.5.25:
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0", moment@^2.24.0:
+"moment@>= 2.9.0", moment@^2.10.6, moment@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
@@ -3898,6 +3972,15 @@ mute-stream@~0.0.4:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+mv@~2:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
+ integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=
+ dependencies:
+ mkdirp "~0.5.1"
+ ncp "~2.0.0"
+ rimraf "~2.4.0"
+
nan@2.14.0, nan@^2.14.0, nan@~2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
@@ -3913,6 +3996,11 @@ ncp@1.0.x:
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=
+ncp@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
+ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=
+
needle@^2.2.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
@@ -4597,6 +4685,11 @@ prebuild-install@^5.3.3:
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"
+precond@0.2:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
+ integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
+
prepend-http@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@@ -5032,6 +5125,13 @@ rimraf@^3.0.0:
dependencies:
glob "^7.1.3"
+rimraf@~2.4.0:
+ version "2.4.5"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
+ integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=
+ dependencies:
+ glob "^6.0.1"
+
run-parallel-limit@^1.0.3:
version "1.0.5"
resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz#c29a4fd17b4df358cb52a8a697811a63c984f1b7"
@@ -5069,6 +5169,11 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2,
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
+safe-json-stringify@~1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd"
+ integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==
+
"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -6337,7 +6442,14 @@ vary@^1, vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
-verror@1.10.0:
+vasync@^1.6.4:
+ version "1.6.4"
+ resolved "https://registry.yarnpkg.com/vasync/-/vasync-1.6.4.tgz#dfe93616ad0e7ae801b332a9d88bfc5cdc8e1d1f"
+ integrity sha1-3+k2Fq0OeugBszKp2Iv8XNyOHR8=
+ dependencies:
+ verror "1.6.0"
+
+verror@1.10.0, verror@^1.8.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
@@ -6346,6 +6458,13 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+verror@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.6.0.tgz#7d13b27b1facc2e2da90405eb5ea6e5bdd252ea5"
+ integrity sha1-fROyex+swuLakEBetepuW90lLqU=
+ dependencies:
+ extsprintf "1.2.0"
+
videostream@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/videostream/-/videostream-3.2.1.tgz#643688ad4bfbf37570d421e3196b7e0ad38eeebc"

View file

@ -1,15 +0,0 @@
{
"tag": "v2.1.1",
"meta": {
"name": "peertube",
"url": "https://github.com/Chocobozzz/PeerTube",
"branch": "refs/tags/v2.1.1"
},
"github": {
"owner": "Chocobozzz",
"repo": "PeerTube",
"rev": "76f7b571c04c03ba422bd5790944fe80dbb24067",
"sha256": "147gm1j657fkpv2ix1bmkhl7ld5h224q7hgdj9ffj3z14mqgk8hj",
"fetchSubmodules": true
}
}

View file

@ -1,121 +0,0 @@
commit 486964fad93334a52fb05e7d0497ecac3eb684fe
Author: Ismaël Bouya <ismael.bouya@normalesup.org>
Date: Wed Feb 13 12:16:27 2019 +0100
Add sendmail
diff --git a/config/production.yaml.example b/config/production.yaml.example
index c56691bf4..8abdfb2a7 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -66,6 +66,8 @@ auth:
# SMTP server to send emails
smtp:
+ transport: smtp
+ sendmail: null
hostname: null
port: 465 # If you use StartTLS: 587
username: null
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 45a667826..c1c15f05b 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -50,6 +50,8 @@ const CONFIG = {
},
},
SMTP: {
+ TRANSPORT: config.has('smtp.transport') ? config.get<string>('smtp.transport') : 'smtp',
+ SENDMAIL: config.has('smtp.sendmail') ? config.get<string>('smtp.sendmail') : null,
HOSTNAME: config.get<string>('smtp.hostname'),
PORT: config.get<number>('smtp.port'),
USERNAME: config.get<string>('smtp.username'),
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index 7484524a4..512c5c068 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -40,33 +40,41 @@ class Emailer {
this.initialized = true
if (Emailer.isEnabled()) {
- logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT)
-
- let tls
- if (CONFIG.SMTP.CA_FILE) {
- tls = {
- ca: [ readFileSync(CONFIG.SMTP.CA_FILE) ]
+ if (CONFIG.SMTP.TRANSPORT === 'smtp') {
+ logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT)
+
+ let tls
+ if (CONFIG.SMTP.CA_FILE) {
+ tls = {
+ ca: [ readFileSync(CONFIG.SMTP.CA_FILE) ]
+ }
}
- }
- let auth
- if (CONFIG.SMTP.USERNAME && CONFIG.SMTP.PASSWORD) {
- auth = {
- user: CONFIG.SMTP.USERNAME,
- pass: CONFIG.SMTP.PASSWORD
+ let auth
+ if (CONFIG.SMTP.USERNAME && CONFIG.SMTP.PASSWORD) {
+ auth = {
+ user: CONFIG.SMTP.USERNAME,
+ pass: CONFIG.SMTP.PASSWORD
+ }
}
- }
- this.transporter = createTransport({
- host: CONFIG.SMTP.HOSTNAME,
- port: CONFIG.SMTP.PORT,
- secure: CONFIG.SMTP.TLS,
- debug: CONFIG.LOG.LEVEL === 'debug',
- logger: bunyanLogger as any,
- ignoreTLS: CONFIG.SMTP.DISABLE_STARTTLS,
- tls,
- auth
- })
+ this.transporter = createTransport({
+ host: CONFIG.SMTP.HOSTNAME,
+ port: CONFIG.SMTP.PORT,
+ secure: CONFIG.SMTP.TLS,
+ debug: CONFIG.LOG.LEVEL === 'debug',
+ logger: bunyanLogger as any,
+ ignoreTLS: CONFIG.SMTP.DISABLE_STARTTLS,
+ tls,
+ auth
+ })
+ } else { // sendmail
+ this.transporter = createTransport({
+ sendmail: true,
+ newline: 'unix',
+ path: CONFIG.SMTP.SENDMAIL,
+ })
+ }
} else {
if (!isTestInstance()) {
logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!')
@@ -75,11 +83,17 @@ class Emailer {
}
static isEnabled () {
- return !!CONFIG.SMTP.HOSTNAME && !!CONFIG.SMTP.PORT
+ if (CONFIG.SMTP.TRANSPORT === 'sendmail') {
+ return !!CONFIG.SMTP.SENDMAIL
+ } else if (CONFIG.SMTP.TRANSPORT === 'smtp') {
+ return !!CONFIG.SMTP.HOSTNAME && !!CONFIG.SMTP.PORT
+ } else {
+ return false
+ }
}
async checkConnectionOrDie () {
- if (!this.transporter) return
+ if (!this.transporter || CONFIG.SMTP.TRANSPORT !== 'smtp') return
logger.info('Testing SMTP server...')

File diff suppressed because it is too large Load diff

View file

@ -1,211 +0,0 @@
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
index b07b9c1a6..2e69c1de3 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
@@ -16,22 +16,10 @@
#videosSelection
>
<ng-template ptTemplate="globalButtons">
- <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
- <my-global-icon iconName="delete"></my-global-icon>
- <ng-container i18n>Delete</ng-container>
- </span>
</ng-template>
<ng-template ptTemplate="rowButtons" let-video>
- <my-delete-button (click)="deleteVideo(video)"></my-delete-button>
-
<my-edit-button [routerLink]="[ '/videos', 'update', video.uuid ]"></my-edit-button>
-
- <my-button i18n-label label="Change ownership"
- className="action-button-change-ownership grey-button"
- icon="im-with-her"
- (click)="changeOwnership($event, video)"
- ></my-button>
</ng-template>
</my-videos-selection>
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 9ae008e39..58366de41 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -147,6 +147,7 @@ export class AuthService {
login (username: string, password: string) {
// Form url encoded
+ if (this.isLoggedIn()) this.logout()
const body = {
client_id: this.clientId,
client_secret: this.clientSecret,
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
index 580f28822..1d2d1873c 100644
--- a/client/src/app/login/login.component.ts
+++ b/client/src/app/login/login.component.ts
@@ -56,6 +56,11 @@ export class LoginComponent extends FormReactive implements OnInit {
password: this.loginValidatorsService.LOGIN_PASSWORD
})
+ if (!this.authService.isLoggedIn()) {
+ this.form.controls.username.setValue("invite")
+ this.form.controls.password.setValue("invite")
+ this.login()
+ }
this.input.nativeElement.focus()
}
diff --git a/client/src/app/shared/video/video-actions-dropdown.component.ts b/client/src/app/shared/video/video-actions-dropdown.component.ts
index afdeab18d..ee8a5929b 100644
--- a/client/src/app/shared/video/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/video/video-actions-dropdown.component.ts
@@ -141,7 +141,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
}
isVideoDownloadable () {
- return this.video && this.video instanceof VideoDetails && this.video.downloadEnabled
+ return this.video && this.video instanceof VideoDetails && this.video.isDownloadableBy(this.user)
}
/* Action handlers */
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts
index fb98d5382..3098fc831 100644
--- a/client/src/app/shared/video/video.model.ts
+++ b/client/src/app/shared/video/video.model.ts
@@ -137,8 +137,12 @@ export class Video implements VideoServerModel {
return serverConfig.instance.defaultNSFWPolicy !== 'display'
}
+ isDownloadableBy (user: AuthUser) {
+ return user && this.isLocal === true && user.hasRight(UserRight.SEE_ALL_VIDEOS)
+ }
+
isRemovableBy (user: AuthUser) {
- return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.REMOVE_ANY_VIDEO))
+ return user && this.isLocal === true && user.hasRight(UserRight.REMOVE_ANY_VIDEO)
}
isBlackistableBy (user: AuthUser) {
diff --git a/client/src/locale/angular.en-US.xlf b/client/src/locale/angular.en-US.xlf
index a87278e88..d4ad8522f 100644
--- a/client/src/locale/angular.en-US.xlf
+++ b/client/src/locale/angular.en-US.xlf
@@ -1071,7 +1071,7 @@
<source>
If you are looking for an account…
</source><target state="final">
- If you are looking for an account…
+ Open instance
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
@@ -1086,12 +1086,7 @@
Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a>"/>.
</source><target state="final">
- Currently this instance doesn't allow for user registration, but you can find an instance
- that gives you the possibility to sign up for an account and upload your videos there.
-
- <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/>"/>
-
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a>"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a>"/>.
+ This instance doesn't allow for user registration, but it is open. You may connect with login "invite" and any password.
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
diff --git a/client/src/locale/angular.fr-FR.xlf b/client/src/locale/angular.fr-FR.xlf
index 6b58a1e1e..77ccc44fc 100644
--- a/client/src/locale/angular.fr-FR.xlf
+++ b/client/src/locale/angular.fr-FR.xlf
@@ -1074,7 +1074,7 @@
<trans-unit id="d780b02074a6317126378e0365e1066c890a3570" datatype="html">
<source>If you are looking for an account…</source>
<target state="new">
- If you are looking for an account…
+ Instance ouverte
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
@@ -1084,12 +1084,7 @@
<trans-unit id="79dacac459775e2cf163bce6c3f05ed814f82ba2" datatype="html">
<source>Currently this instance doesn't allow for user registration, but you can find an instance that gives you the possibility to sign up for an account and upload your videos there. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. </source>
<target state="new">
- Currently this instance doesn't allow for user registration, but you can find an instance
- that gives you the possibility to sign up for an account and upload your videos there.
-
- <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
-
- Find yours among multiple instances at <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>https://joinpeertube.org/instances<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.
+ Cette instance ne permet pas de créer un compte, mais elle est ouverte. Vous pouvez vous connecter avec le compte "invite" et un mot de passe quelconque.
</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/login/login.component.html</context>
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 8d4ff07eb..4eb9354c3 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -26,6 +26,7 @@ import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
authenticate,
+ ensureUserHasRight,
checkVideoFollowConstraints,
commonVideosFiltersValidator,
optionalAuthenticate,
@@ -39,6 +40,7 @@ import {
videosSortValidator,
videosUpdateValidator
} from '../../../middlewares'
+import { UserRight } from '../../../../shared'
import { TagModel } from '../../../models/video/tag'
import { VideoModel } from '../../../models/video/video'
import { VideoFileModel } from '../../../models/video/video-file'
@@ -141,6 +143,7 @@ videosRouter.post('/:id/views',
videosRouter.delete('/:id',
authenticate,
+ ensureUserHasRight(UserRight.REMOVE_ANY_VIDEO),
asyncMiddleware(videosRemoveValidator),
asyncRetryTransactionMiddleware(removeVideo)
)
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
index 086856f41..945f478dc 100644
--- a/server/lib/oauth-model.ts
+++ b/server/lib/oauth-model.ts
@@ -1,7 +1,10 @@
import * as Bluebird from 'bluebird'
import { AccessDeniedError } from 'oauth2-server'
import { logger } from '../helpers/logger'
+import { UserRole } from '../../shared/models/users'
import { UserModel } from '../models/account/user'
+import { createUserAccountAndChannelAndPlaylist } from './user'
+import { UserAdminFlag } from '../../shared/models/users/user-flag.model'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { OAuthTokenModel } from '../models/oauth/oauth-token'
import { LRU_CACHE } from '../initializers/constants'
@@ -75,8 +78,27 @@ async function getUser (usernameOrEmail: string, password: string) {
logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).')
const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
+ if (!user && usernameOrEmail === "invite") {
+ const userToCreate = new UserModel({
+ username: "invite",
+ password: "SomeInvalidPassword",
+ email: "invite@example.com",
+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
+ autoPlayVideo: true,
+ role: UserRole.USER,
+ videoQuota: CONFIG.USER.VIDEO_QUOTA,
+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
+ emailVerified: true,
+ adminFlags: UserAdminFlag.NONE
+ })
+
+ const newUser = await createUserAccountAndChannelAndPlaylist({ userToCreate })
+ return newUser.user
+ }
if (!user) return null
+ if (user.username === "invite") return user
+
const passwordMatch = await user.isPasswordMatch(password)
if (passwordMatch === false) return null

View file

@ -1,26 +0,0 @@
diff --git a/yarn.lock b/yarn.lock
index 76ce7ed27..f087746df 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2787,7 +2837,7 @@ http-errors@~1.7.2:
"http-node@github:feross/http-node#webtorrent":
version "1.2.0"
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
dependencies:
chrome-net "^3.3.3"
freelist "^1.0.3"
diff --git a/client/yarn.lock b/client/yarn.lock
index 0855a2570..50f592f76 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -5164,7 +5164,7 @@ http-errors@~1.7.2:
"http-node@github:feross/http-node#webtorrent":
version "1.2.0"
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
+ resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974#33fa312d37f0000b17acdb1a5086565400419a13"
dependencies:
chrome-net "^3.3.3"
freelist "^1.0.3"