summaryrefslogtreecommitdiff
path: root/overlays
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-12-13 21:25:24 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2019-05-24 01:40:13 +0200
commit24fd1fe6c62b7a9fc347794fde043285da272f5c (patch)
tree65557bf1d241ca389b619dbd24d18d51932ee030 /overlays
downloadNUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.tar.gz
NUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.tar.zst
NUR-24fd1fe6c62b7a9fc347794fde043285da272f5c.zip
Initial commit published for NUR
Diffstat (limited to 'overlays')
-rw-r--r--overlays/bitlbee/bitlbee_long_nicks.patch56
-rw-r--r--overlays/bitlbee/default.nix5
-rw-r--r--overlays/bundix/default.nix7
-rw-r--r--overlays/databases/mysql/default.nix12
-rw-r--r--overlays/databases/postgresql/default.nix11
-rw-r--r--overlays/databases/postgresql/postgresql_run_socket_path.patch12
-rw-r--r--overlays/default.nix31
-rw-r--r--overlays/dwm/default.nix7
-rw-r--r--overlays/dwm/dwm_config.h98
-rw-r--r--overlays/elinks/default.nix14
-rw-r--r--overlays/elinks/elinks.json15
-rw-r--r--overlays/environments/default.nix3
-rw-r--r--overlays/environments/immae-eu.nix116
-rw-r--r--overlays/gitweb/default.nix7
-rw-r--r--overlays/gitweb/theme/git-favicon.pngbin0 -> 1125 bytes
-rw-r--r--overlays/gitweb/theme/git-logo.pngbin0 -> 2412 bytes
-rw-r--r--overlays/gitweb/theme/gitweb.css783
-rw-r--r--overlays/gitweb/theme/gitweb.js27
-rw-r--r--overlays/goaccess/default.nix13
-rw-r--r--overlays/kanboard/default.nix18
-rw-r--r--overlays/ldapvi/default.nix3
-rw-r--r--overlays/ldapvi/ldapvi.json14
-rw-r--r--overlays/lesspipe/default.nix5
-rw-r--r--overlays/neomutt/default.nix8
-rw-r--r--overlays/nixops/default.nix7
-rw-r--r--overlays/pass/default.nix8
-rw-r--r--overlays/pass/pass-fix-pass-init.patch42
-rw-r--r--overlays/pass/pass.json14
-rw-r--r--overlays/pelican/default.nix6
-rw-r--r--overlays/pelican/pelican.json15
-rw-r--r--overlays/profanity/default.nix9
-rw-r--r--overlays/python-packages/buildbot.nix8
-rw-r--r--overlays/python-packages/default.nix28
-rw-r--r--overlays/sc-im/default.nix9
-rw-r--r--overlays/shaarli/default.nix10
-rw-r--r--overlays/shaarli/shaarli_ldap.patch420
-rw-r--r--overlays/slrn/default.nix11
-rw-r--r--overlays/taskwarrior/default.nix13
-rw-r--r--overlays/vit/default.nix8
-rw-r--r--overlays/vit/vit.json15
-rw-r--r--overlays/weboob/default.nix15
-rw-r--r--overlays/weechat/default.nix14
-rw-r--r--overlays/ympd/default.nix5
-rw-r--r--overlays/ympd/ympd-password-env.patch23
-rw-r--r--overlays/ympd/ympd.json15
45 files changed, 1960 insertions, 0 deletions
diff --git a/overlays/bitlbee/bitlbee_long_nicks.patch b/overlays/bitlbee/bitlbee_long_nicks.patch
new file mode 100644
index 00000000..70be0925
--- /dev/null
+++ b/overlays/bitlbee/bitlbee_long_nicks.patch
@@ -0,0 +1,56 @@
1diff --git a/bitlbee.h b/bitlbee.h
2index 17ab2979..5858277e 100644
3--- a/bitlbee.h
4+++ b/bitlbee.h
5@@ -121,7 +121,7 @@ extern "C" {
6 #define CONTROL_TOPIC "Welcome to the control channel. Type \2help\2 for help information."
7 #define IRCD_INFO PACKAGE " <http://www.bitlbee.org/>"
8
9-#define MAX_NICK_LENGTH 24
10+#define MAX_NICK_LENGTH 99
11
12 #define HELP_FILE VARDIR "help.txt"
13 #define CONF_FILE_DEF ETCDIR "bitlbee.conf"
14diff --git a/tests/check_nick.c b/tests/check_nick.c
15index ca5e5111..909fdcc9 100644
16--- a/tests/check_nick.c
17+++ b/tests/check_nick.c
18@@ -11,16 +11,16 @@
19 START_TEST(test_nick_strip){
20 int i;
21 const char *get[] = { "test:", "test", "test\n",
22- "thisisaveryveryveryverylongnick",
23- "thisisave:ryveryveryverylongnick",
24+ "thisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnick",
25+ "thisis:averyveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnick",
26 "t::::est",
27 "test123",
28 "123test",
29 "123",
30 NULL };
31 const char *expected[] = { "test", "test", "test",
32- "thisisaveryveryveryveryl",
33- "thisisaveryveryveryveryl",
34+ "thisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnickthisisaveryve",
35+ "thisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnickthisisaveryve",
36 "test",
37 "test123",
38 "_123test",
39@@ -28,7 +28,7 @@ START_TEST(test_nick_strip){
40 NULL };
41
42 for (i = 0; get[i]; i++) {
43- char copy[60];
44+ char copy[260];
45 strcpy(copy, get[i]);
46 nick_strip(NULL, copy);
47 fail_unless(strcmp(copy, expected[i]) == 0,
48@@ -53,7 +53,7 @@ END_TEST
49
50 START_TEST(test_nick_ok_notok)
51 {
52- const char *nicks[] = { "thisisaveryveryveryveryveryveryverylongnick",
53+ const char *nicks[] = { "thisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnickthisisaveryveryveryveryveryveryverylongnick",
54 "\nillegalchar", "", "nick%", "123test", NULL };
55 int i;
56
diff --git a/overlays/bitlbee/default.nix b/overlays/bitlbee/default.nix
new file mode 100644
index 00000000..5183d012
--- /dev/null
+++ b/overlays/bitlbee/default.nix
@@ -0,0 +1,5 @@
1self: super: {
2 bitlbee = super.bitlbee.overrideAttrs(old: {
3 patches = (old.patches or []) ++ [ ./bitlbee_long_nicks.patch ];
4 });
5}
diff --git a/overlays/bundix/default.nix b/overlays/bundix/default.nix
new file mode 100644
index 00000000..6c4046cf
--- /dev/null
+++ b/overlays/bundix/default.nix
@@ -0,0 +1,7 @@
1self: super: {
2 bundix = super.bundix.overrideAttrs (old: {
3 preBuild = (old.preBuild or "") + ''
4 sed -i -e "/case obj/a\ when nil\n nil" lib/bundix/nixer.rb
5 '';
6 });
7}
diff --git a/overlays/databases/mysql/default.nix b/overlays/databases/mysql/default.nix
new file mode 100644
index 00000000..5e402841
--- /dev/null
+++ b/overlays/databases/mysql/default.nix
@@ -0,0 +1,12 @@
1self: super: rec {
2 mariadb = mariadbPAM;
3 mariadbPAM = super.mariadb.overrideAttrs(old: {
4 cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ];
5 buildInputs = old.buildInputs ++ [ self.pam ];
6 }) // (with super.mariadb; {
7 inherit client;
8 servier = super.mariadb;
9 inherit connector-c;
10 inherit galera;
11 });
12}
diff --git a/overlays/databases/postgresql/default.nix b/overlays/databases/postgresql/default.nix
new file mode 100644
index 00000000..8d1405e3
--- /dev/null
+++ b/overlays/databases/postgresql/default.nix
@@ -0,0 +1,11 @@
1self: super: rec {
2 postgresql_11_custom = super.postgresql_11.overrideAttrs(old: {
3 # datadir in /var/lib/postgresql is named after psqlSchema
4 passthru = old.passthru // { psqlSchema = "11.0"; };
5 configureFlags = old.configureFlags ++ [ "--with-pam" ];
6 buildInputs = (old.buildInputs or []) ++ [ self.pam ];
7 patches = old.patches ++ [
8 ./postgresql_run_socket_path.patch
9 ];
10 });
11}
diff --git a/overlays/databases/postgresql/postgresql_run_socket_path.patch b/overlays/databases/postgresql/postgresql_run_socket_path.patch
new file mode 100644
index 00000000..b558c7b7
--- /dev/null
+++ b/overlays/databases/postgresql/postgresql_run_socket_path.patch
@@ -0,0 +1,12 @@
1diff -Naur postgresql-9.2.0.sockets/src/include/pg_config_manual.h postgresql-9.2.0/src/include/pg_config_manual.h
2--- postgresql-9.2.0.sockets/src/include/pg_config_manual.h 2012-09-06 17:26:17.000000000 -0400
3+++ postgresql-9.2.0/src/include/pg_config_manual.h 2012-09-06 18:13:18.183092471 -0400
4@@ -144,7 +144,7 @@
5 * here's where to twiddle it. You can also override this at runtime
6 * with the postmaster's -k switch.
7 */
8-#define DEFAULT_PGSOCKET_DIR "/tmp"
9+#define DEFAULT_PGSOCKET_DIR "/run/postgresql"
10
11 /*
12 * The random() function is expected to yield values between 0 and
diff --git a/overlays/default.nix b/overlays/default.nix
new file mode 100644
index 00000000..408515ed
--- /dev/null
+++ b/overlays/default.nix
@@ -0,0 +1,31 @@
1{
2 mylibs = self: super: { mylibs = import ../libs.nix { pkgs = self; }; };
3 mypkgs = self: super: import ../pkgs { pkgs = self; };
4
5 bitlbee = import ./bitlbee;
6 bundix = import ./bundix;
7 dwm = import ./dwm;
8 elinks = import ./elinks;
9 gitweb = import ./gitweb;
10 goaccess = import ./goaccess;
11 kanboard = import ./kanboard;
12 ldapvi = import ./ldapvi;
13 lesspipe = import ./lesspipe;
14 mysql = import ./databases/mysql;
15 neomutt = import ./neomutt;
16 nixops = import ./nixops;
17 pass = import ./pass;
18 pelican = import ./pelican;
19 postgresql = import ./databases/postgresql;
20 profanity = import ./profanity;
21 sc-im = import ./sc-im;
22 shaarli = import ./shaarli;
23 slrn = import ./slrn;
24 taskwarrior = import ./taskwarrior;
25 vit = import ./vit;
26 weboob = import ./weboob;
27 weechat = import ./weechat;
28 ympd = import ./ympd;
29}
30// import ./python-packages
31// import ./environments
diff --git a/overlays/dwm/default.nix b/overlays/dwm/default.nix
new file mode 100644
index 00000000..96ed3ff5
--- /dev/null
+++ b/overlays/dwm/default.nix
@@ -0,0 +1,7 @@
1self: super: {
2 dwm = super.dwm.overrideAttrs(old: rec {
3 postPatch = ''
4 cp ${./dwm_config.h} ./config.h
5 '';
6 });
7}
diff --git a/overlays/dwm/dwm_config.h b/overlays/dwm/dwm_config.h
new file mode 100644
index 00000000..b1587e88
--- /dev/null
+++ b/overlays/dwm/dwm_config.h
@@ -0,0 +1,98 @@
1/* See LICENSE file for copyright and license details. */
2
3/* appearance */
4static const unsigned int borderpx = 1; /* border pixel of windows */
5static const unsigned int snap = 32; /* snap pixel */
6static const int showbar = 1; /* 0 means no bar */
7static const int topbar = 1; /* 0 means bottom bar */
8static const char *fonts[] = { "monospace:size=10" };
9static const char dmenufont[] = "monospace:size=10";
10static const char col_gray1[] = "#222222";
11static const char col_gray2[] = "#444444";
12static const char col_gray3[] = "#bbbbbb";
13static const char col_gray4[] = "#eeeeee";
14static const char col_cyan[] = "#005577";
15static const char *colors[][3] = {
16 /* fg bg border */
17 [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
18 [SchemeSel] = { col_gray4, col_cyan, col_cyan },
19};
20
21/* tagging */
22static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
23
24static const Rule rules[] = {
25 /* xprop(1):
26 * WM_CLASS(STRING) = instance, class
27 * WM_NAME(STRING) = title
28 */
29 /* class instance title tags mask isfloating monitor */
30 { "Nextcloud", NULL, NULL, 9 << 8, 0, -1 },
31};
32
33/* layout(s) */
34static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
35static const int nmaster = 1; /* number of clients in master area */
36static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
37
38static const Layout layouts[] = {
39 /* symbol arrange function */
40 { "[M]", monocle }, /* first entry is default */
41 { "[]=", tile },
42 { "><>", NULL }, /* no layout function means floating behavior */
43};
44
45/* key definitions */
46#define MODKEY Mod1Mask
47#define TAGKEYS(KEY,TAG) \
48 { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
49 { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
50 { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
51 { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
52
53/* helper for spawning shell commands in the pre dwm-5.0 fashion */
54#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
55
56/* commands */
57static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
58static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
59static const char *termcmd[] = { "st", NULL };
60
61static Key keys[] = {
62 /* modifier key function argument */
63 { MODKEY, XK_p, spawn, {.v = dmenucmd } },
64 { MODKEY, XK_t, spawn, {.v = termcmd } },
65 { MODKEY, XK_Tab, view, {0} },
66 { MODKEY|ShiftMask, XK_c, killclient, {0} },
67 { MODKEY, XK_j, focusstack, {.i = +1 } },
68 { MODKEY, XK_k, focusstack, {.i = -1 } },
69 { MODKEY, XK_Return, zoom, {0} },
70 TAGKEYS( XK_1, 0)
71 TAGKEYS( XK_2, 1)
72 TAGKEYS( XK_3, 2)
73 TAGKEYS( XK_4, 3)
74 TAGKEYS( XK_5, 4)
75 TAGKEYS( XK_6, 5)
76 TAGKEYS( XK_7, 6)
77 TAGKEYS( XK_8, 7)
78 TAGKEYS( XK_9, 8)
79 { MODKEY|ShiftMask, XK_q, quit, {0} },
80};
81
82/* button definitions */
83/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
84static Button buttons[] = {
85 /* click event mask button function argument */
86 { ClkLtSymbol, 0, Button1, setlayout, {0} },
87 { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
88 { ClkWinTitle, 0, Button2, zoom, {0} },
89 { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
90 { ClkClientWin, MODKEY, Button1, movemouse, {0} },
91 { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
92 { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
93 { ClkTagBar, 0, Button1, view, {0} },
94 { ClkTagBar, 0, Button3, toggleview, {0} },
95 { ClkTagBar, MODKEY, Button1, tag, {0} },
96 { ClkTagBar, MODKEY, Button3, toggletag, {0} },
97};
98
diff --git a/overlays/elinks/default.nix b/overlays/elinks/default.nix
new file mode 100644
index 00000000..1744dc0b
--- /dev/null
+++ b/overlays/elinks/default.nix
@@ -0,0 +1,14 @@
1self: super: {
2 elinks = super.elinks.overrideAttrs (old:
3 self.mylibs.fetchedGithub ./elinks.json // rec {
4 preConfigure = ''sh autogen.sh'';
5 buildInputs = old.buildInputs ++ (with self; [ gettext automake autoconf ]);
6 configureFlags = [
7 "--disable-smb" "--without-x" "--enable-cgi"
8 "--enable-leds" "--enable-256-colors"
9 "--enable-html-highlight" "--with-zlib"
10 ];
11 patches = [];
12 }
13 );
14}
diff --git a/overlays/elinks/elinks.json b/overlays/elinks/elinks.json
new file mode 100644
index 00000000..ea13b1fa
--- /dev/null
+++ b/overlays/elinks/elinks.json
@@ -0,0 +1,15 @@
1{
2 "tag": "f86be65-master",
3 "meta": {
4 "name": "elinks",
5 "url": "https://github.com/nabetaro/elinks",
6 "branch": "master"
7 },
8 "github": {
9 "owner": "nabetaro",
10 "repo": "elinks",
11 "rev": "f86be659718c0cd0a67f88b42f07044c23d0d028",
12 "sha256": "1jxb7xgawcjkb3gw4gqyw26g02709wwdbhyczfckh3l4njxhy14m",
13 "fetchSubmodules": true
14 }
15}
diff --git a/overlays/environments/default.nix b/overlays/environments/default.nix
new file mode 100644
index 00000000..630b0bd1
--- /dev/null
+++ b/overlays/environments/default.nix
@@ -0,0 +1,3 @@
1{
2 immae-eu = import ./immae-eu.nix;
3}
diff --git a/overlays/environments/immae-eu.nix b/overlays/environments/immae-eu.nix
new file mode 100644
index 00000000..1f27e7ca
--- /dev/null
+++ b/overlays/environments/immae-eu.nix
@@ -0,0 +1,116 @@
1self: super: with self;
2let
3 # https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh
4 # https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks
5 paths = [
6 # archives
7 lzo unzip bzip2 p7zip xz
8 # unrar is unfree
9
10 # backups
11 duply
12
13 # calendar/contacts
14 abook khard khal cadaver vdirsyncer pal
15
16 # computing
17 boinctui
18
19 # cryptocurrencies
20 cardano sia monero
21 xmr-stak
22 solc
23 iota-cli-app
24
25 # debugging
26 rr valgrind netcat-gnu strace
27
28 # documentations
29 unicodeDoc
30
31 # e-mails
32 muttprint mutt-ics
33 notmuch-python2 notmuch-python3 notmuch-vim
34 neomutt mairix notmuch
35 bogofilter fetchmail
36
37 # git
38 vcsh gitRepo gitAndTools.stgit tig
39
40 # graphical tools
41 nextcloud-client firefox
42 dwm dmenu st
43
44 # images
45 feh imagemagick tiv graphicsmagick
46
47 # internet browsing
48 w3m lynx links elinks browsh weboob urlview googler urlwatch
49
50 # less
51 python3Packages.pygments lesspipe highlight sourceHighlight
52
53 # monitoring
54 cnagios mtop pg_activity nagios-cli mtr
55 iftop htop iotop iperf
56 goaccess
57 # nagnu
58
59 # messaging/forums/news
60 flrn slrn
61 telegram-cli telegram-history-dump telegramircd
62 weechat profanity
63 newsboat irssi
64
65 # nix
66 mylibs.yarn2nixPackage.yarn2nix
67 nixops nix-prefetch-scripts nix-generate-from-cpan
68 nix-zsh-completions bundix nodePackages.bower2nix
69 nodePackages.node2nix
70 # (nixos {}).nixos-generate-config
71 # (nixos {}).nixos-install
72 # (nixos {}).nixos-enter
73 # (nixos {}).manual.manpages
74
75 # note taking
76 note terminal-velocity jrnl
77
78 # office
79 sc-im ranger
80 genius bc
81 ledger
82 tmux
83 rtorrent
84 ldapvi
85
86 # password management
87 pass apg pwgen
88
89 # pdf
90 pdftk poppler_utils
91
92 # programming
93 pelican emacs26-nox ctags
94 wdiff
95
96 # security
97 keybase
98
99 # todolist/time management
100 taskwarrior vit timewarrior
101
102 # video/music
103 youtube-dl ncmpc ncmpcpp ffmpeg
104
105 # other tools
106 pgloader s3cmd lftp jq cpulimit libxslt
107 ];
108in
109{
110 myEnvironments.immae-eu = buildEnv {
111 name = "immae-eu-packages";
112 inherit paths;
113 pathsToLink = [ "/bin" "/etc" "/include" "/lib" "/libexec" "/share"];
114 extraOutputsToInstall = [ "bin" "man" "doc" "info" ];
115 };
116}
diff --git a/overlays/gitweb/default.nix b/overlays/gitweb/default.nix
new file mode 100644
index 00000000..aa17d22f
--- /dev/null
+++ b/overlays/gitweb/default.nix
@@ -0,0 +1,7 @@
1self: super: {
2 gitweb = super.gitweb.overrideAttrs(old: {
3 installPhase = old.installPhase + ''
4 cp -r ${./theme} $out/gitweb-theme;
5 '';
6 });
7}
diff --git a/overlays/gitweb/theme/git-favicon.png b/overlays/gitweb/theme/git-favicon.png
new file mode 100644
index 00000000..4fa44bb0
--- /dev/null
+++ b/overlays/gitweb/theme/git-favicon.png
Binary files differ
diff --git a/overlays/gitweb/theme/git-logo.png b/overlays/gitweb/theme/git-logo.png
new file mode 100644
index 00000000..fdaf7b73
--- /dev/null
+++ b/overlays/gitweb/theme/git-logo.png
Binary files differ
diff --git a/overlays/gitweb/theme/gitweb.css b/overlays/gitweb/theme/gitweb.css
new file mode 100644
index 00000000..83e07425
--- /dev/null
+++ b/overlays/gitweb/theme/gitweb.css
@@ -0,0 +1,783 @@
1/* Reset
2------------------------------------------------------------------------- */
3
4/* Based on http://meyerweb.com/eric/tools/css/reset/ */
5/* v1.0 | 20080212 */
6
7html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p,
8blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
9font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b,
10u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table,
11caption, tbody, tfoot, thead, tr, th, td {
12 margin: 0;
13 padding: 0;
14 border: 0;
15 outline: 0;
16 font-size: 100%;
17 vertical-align: baseline;
18 background: transparent;
19}
20
21ol, ul { list-style: none; }
22
23blockquote, q { quotes: none; }
24
25blockquote:before, blockquote:after,
26q:before, q:after {
27 content: '';
28 content: none;
29}
30
31:focus { outline: 0; }
32
33ins { text-decoration: none; }
34
35del { text-decoration: line-through; }
36
37table {
38 border-collapse: collapse;
39 border-spacing: 0;
40}
41
42a { outline: none; }
43
44/* General
45---------------------------------------------------------------------------- */
46
47html {
48 position: relative;
49 min-height: 100%;
50}
51
52body {
53 font: 13px Helvetica,arial,freesans,clean,sans-serif;
54 line-height: 1.4;
55 margin: 0 0 105px;
56 background-color: #fff;
57 color: #000000;
58}
59
60/* Monospaced Fonts */
61.sha1, .mode, .diff_tree .list, .pre, .diff, .patchset {
62 font-family: 'Consolas','Bitstream Vera Sans Mono',monospace;
63}
64
65a:link, a:visited {
66 color: #4183C4;
67 text-decoration: none;
68}
69
70a:hover {
71 text-decoration: underline;
72}
73
74td.list a[href*='tree'], td.list a[href*='blob'] {
75 padding-left: 20px;
76 display: block;
77 float: left;
78 height: 16px;
79 line-height: 16px;
80}
81
82td.list a[href*='tree'] {
83 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABq0lEQVQ4y8WTu4oUQRSGv+rtGVuxhwVFdFEEE2c3d0HYTEMTn8DEVxADQTDUF9DMwMxQMBMx8AEWzRQ3cBHd9TI91+2urjq/QbczY2IygSep4nD+79yqnCRWsYQVbWVACvDh5ZXdrLe15dwyT1TjT/sxFFeB6i+VA2B6+cb7kAI4Jf0LO087zjlQI8Y5Qvnj0sHug321XoC1bk+K9eHk6+s7wPMUgKAS88eqb4+Jfg2SHs7lZBvX2Nh+2EUCDGSAcMnJsx9f7NxfAGqXyDzRd5EJO/pMPT1gcviGTnYOVIN5pAAE8v7dLrKL8xnglFk4ws9Afko9HpH3b5Gd2mwb/lOBmgrSdYhJugDUCenxM6xv3p4HCsP8F0LxCsUhCkMURihOyM7fg0osASTFEpu9a4LjGIUCqwcoDiEUrX+E4hRUQb20RiokC1j9vckUhygU7X3QZh7NAVKYL7YBeMkRUfjVCotF2XGIwnghtrJpMywB5G0QZj9P1JNujuWJ1AHLQadRrACPkuZ0SSSWpeStWgDK6tHek5vbiOs48n++XQHurcf0rFng//6NvwG+iB9/4duaTgAAAABJRU5ErkJgggo=) center left no-repeat;
84}
85
86td.list a[href*='blob'] {
87 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAA6ElEQVQoFQXBMW5TQRgGwNnHnoE0QbiCjoIooUmTU3AuS1BwIoTSUdJBigg3GCWOg9/++zHTop078wIAsPMrE4SL5/1aIyMjIyMjz/m0tbFECFdrPeaQQw75mz/5nZH7fN7aWILmauSYfznmmIfss8vIUx7zZWsTTXM5vpWvTk5Wq9VHQP/gtgOLa0Qpw940vAQdaG6thpOhlOkG0AEuAVGmEkAH+G4YSikxXQM6wDsAMRFAB/ihDNNUmN4DOsAbBAEAdICfpmmaAt4COoj2GgCASbIkZh1NAACznhQt2itnFgAAlF3u/gMDtJXPzQxoswAAAABJRU5ErkJgggo=) center left no-repeat;
88}
89
90i {
91 font-style: normal;
92}
93
94td, th {
95 padding: 5px;
96}
97
98.page_nav br {
99 display: none;
100}
101
102/* Page Header
103---------------------------------------------------------------------------- */
104
105.page_header {
106 height: 50px;
107 line-height: 50px;
108 position: relative;
109 padding: 0 27px;
110 margin-bottom: 20px;
111 font-size: 20px;
112 font-family: Helvetica, Arial, Freesans, Clean, sans-serif;
113 background: #FFFFFF; /* old browsers */
114 background: -moz-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%); /* firefox */
115 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FFFFFF), color-stop(100%,#F5F5F5)); /* webkit */
116 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#F5F5F5',GradientType=0 ); /* ie */
117 background: -o-linear-gradient(top, #FFFFFF 0%, #F5F5F5 100%);
118 border-bottom: 1px solid #dfdfdf;
119}
120
121.page_header a:link, .page_header a:visited {
122 color: #4183C4;
123 text-decoration: none;
124 padding: 3px;
125 font-weight: bold;
126}
127
128.page_header a:hover {
129 font-weight: bold;
130 padding: 3px;
131 text-decoration: underline;
132}
133
134.page_header a:first-child {
135 background: transparent;
136}
137
138.page_header img.logo {
139 position: relative;
140 top: 7px;
141 margin-right: 5px;
142}
143
144/* Page Footer
145---------------------------------------------------------------------------- */
146
147.page_footer {
148 position: absolute;
149 left: 0;
150 bottom: 0;
151 width: 100%;
152 height: 80px;
153 line-height: 80px;
154 margin-top: 15px;
155 background: #f1f1f1;
156 border-top: 2px solid #ddd;
157 border-bottom: 1px solid #ddd;
158}
159
160.page_footer_text {
161 color: #666;
162 display: inline;
163 float: left;
164 margin-left: 25px;
165 width: 80%;
166 overflow: hidden;
167 white-space: nowrap;
168 text-overflow: ellipsis;
169}
170
171a.rss_logo {
172 float: right;
173 padding: 3px 1px;
174 width: 35px;
175 line-height: 10px;
176 border: 1px solid;
177 border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
178 color: #ffffff;
179 background-color: #ff6600;
180 font-weight: bold;
181 font-family: sans-serif;
182 font-size: 80%;
183 text-align: center;
184 text-decoration: none;
185 margin-top: 30px;
186 margin-left: 5px;
187}
188
189a.rss_logo:hover {
190 background-color: #ee5500;
191}
192
193.rss_logo {
194 margin-right: 25px;
195 background: yellow;
196}
197
198.rss_logo:last-child {
199 margin-right: 5px;
200}
201
202/* Index include
203---------------------------------------------------------------------------- */
204
205.index_include {
206 width: 95%;
207 margin: 0 auto 15px;
208 background: -moz-linear-gradient(center top , #FFFFFF 0%, #F5F5F5 100%) repeat scroll 0 0 transparent;
209 border: 1px solid #DFDFDF;
210 padding: 8px;
211 -webkit-box-sizing: border-box;
212 -moz-box-sizing: border-box;
213 box-sizing: border-box;
214}
215
216/* Elements
217---------------------------------------------------------------------------- */
218
219.project_list,
220.shortlog,
221.tree,
222.commit_search,
223.history {
224 width: 95%;
225 margin: 0 auto 15px auto;
226 border: 1px solid #d8d8d8;
227 -moz-box-shadow: 0 0 3px rgba(0,0,0,0.2);
228 -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.2);
229 box-shadow: 0 0 3px rgba(0,0,0,0.2);
230}
231
232.project_list th,
233.shortlog th,
234.tree th,
235.commit_search th {
236 color: #afafaf;
237 font-weight: normal;
238}
239
240.project_list th {
241 font-weight: bold;
242}
243
244.project_list tr,
245.shortlog tr,
246.tree tr,
247.commit_search tr {
248 background: #eaeaea;
249 height: 2.5em;
250 text-align: left;
251 color: #545454;
252}
253
254.project_list tr.dark, .project_list tr.light,
255.shortlog tr.dark, .shortlog tr.light,
256.tree tr.dark, .tree tr.light,
257.commit_search tr.dark, .commit_search tr.light,
258.history tr.dark, .history tr.light,
259.heads tr.dark, .heads tr.light {
260 background: #F9F9F9; /* old browsers */
261 background: -moz-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%); /* firefox */
262 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#F9F9F9), color-stop(100%,#EFEFEF)); /* webkit */
263 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F9F9F9', endColorstr='#EFEFEF',GradientType=0 ); /* ie */
264 background: -o-linear-gradient(top, #F9F9F9 0%, #EFEFEF 100%);
265 height: 2.5em;
266 border-bottom: 1px solid #e1e1e1;
267}
268
269th .header {
270 background: transparent;
271 border: 0;
272 padding: 0;
273 font-weight: bold;
274}
275
276.tree {
277 width: 100%;
278 margin: 0;
279}
280
281.projsearch {
282 position: absolute;
283 right: 4%;
284 top: 15px;
285}
286
287.projsearch a {
288 display: none;
289}
290
291.commit_search {
292 background: #eaeaea;
293}
294
295.page_nav,
296.list_head,
297.page_path,
298.search {
299 width: 94%;
300 background: #eaeaea;
301 color: #545454;
302 border: 1px solid #d8d8d8;
303 padding: 5px;
304 margin: 0 auto 15px auto;
305}
306
307.history {
308 background: #eaeaea;
309}
310
311.title {
312 margin: 0 auto 15px auto;
313 padding: 5px;
314 width: 95%;
315}
316
317.readme {
318 background: #eaf2f5;
319 border: 1px solid #bedce7;
320 -moz-box-sizing: border-box;
321 -webkit-box-sizing: border-box;
322 box-sizing: border-box;
323 margin: 0 auto 15px auto;
324 padding: 15px;
325 width: 95%;
326}
327
328.readme h1 {
329 display: block;
330 font-size: 2em;
331 font-weight: bold;
332 margin-bottom: 0.67em;
333 margin-top: 0;
334}
335
336.readme h2 {
337 font-size: 1.5em;
338 font-weight: bold;
339 margin-bottom: 0.83em;
340}
341
342
343.readme h3 {
344 font-size: 1.17em;
345 font-weight: bold;
346 margin-bottom: 1em;
347}
348
349.readme p {
350 margin-bottom: 1em;
351}
352
353.readme ul {
354 list-style: disc;
355 margin-bottom: 1em;
356 margin-left: 1.5em;
357}
358
359.readme ul ul {
360 margin-bottom: 0;
361}
362
363.readme ol {
364 list-style: decimal;
365 margin-bottom: 1em;
366 margin-left: 1.5em;
367}
368
369.readme ol ol {
370 margin-bottom: 0;
371}
372
373.readme pre {
374 font-family: monospace;
375 margin: 1em 0;
376 white-space: pre;
377}
378
379.readme tt, .readme code, .readme kbd, .readme samp {
380 font-family: monospace;
381}
382
383.readme blockquote {
384 margin: 1em;
385}
386
387.projects_list,
388.tags {
389 width: 95%;
390 background: #f0f0f0;
391 color: #545454;
392 border: 1px solid #d8d8d8;
393 padding: 5px;
394 margin: 0 auto 15px auto;
395}
396
397.heads {
398 width: 95%;
399 color: #545454;
400 border: 1px solid #d8d8d8;
401 padding: 5px;
402 margin: 0 auto 15px auto;
403}
404
405.header {
406 width: 94%;
407 margin: 0 auto 15px auto;
408 background: #eaf2f5;
409 border: 1px solid #bedce7;
410 padding: 5px;
411}
412
413.header .age {
414 float: left;
415 color: #000;
416 font-weight: bold;
417 width: 10em;
418}
419
420.title_text {
421 width: 94%;
422 background: #eaf2f5;
423 border: 1px solid #bedce7;
424 padding: 5px;
425 margin: 0 auto 0 auto;
426}
427
428.log_body {
429 width: 94%;
430 background: #eaf2f5;
431 border: 1px solid #bedce7;
432 border-top: 0;
433 padding: 5px;
434 margin: 0 auto 15px auto;
435}
436
437.page_body {
438 line-height: 1.4em;
439 width: 94%;
440 background: #f8f8f8;
441 border: 1px solid #d8d8d8;
442 padding: 5px;
443 margin: 15px auto 15px auto;
444}
445
446.diff_tree {
447 width: 95%;
448 background: #f0f0f0;
449 border: 1px solid #d8d8d8;
450 padding: 5px;
451 margin: 0 auto 15px auto;
452}
453
454.page_body > .list_head {
455 width: 98.5%;
456}
457
458.page_body > .diff_tree {
459 width: 99.5%;
460}
461
462.patch > .header {
463 width: 99%;
464}
465
466.author .avatar,
467.author_date .avatar {
468 position: relative;
469 top: 3px;
470}
471
472.object_header .avatar {
473 border: 1px solid #D8D8D8;
474 float: right;
475}
476
477.object_header td,
478.object_header th {
479 vertical-align: top;
480}
481
482/* Refs
483---------------------------------------------------------------------------- */
484
485span.refs span {
486 color: #707070;
487 display: inline-block;
488 margin: 0;
489 background-color: #eee;
490 border: 1px solid #ccc;
491 border-radius: 3px;
492 height: 18px;
493 padding: 0 6px;
494 text-overflow: ellipsis;
495}
496
497span.refs span.ref {
498 color: #707070;
499 display: inline-block;
500 margin: 0;
501 background-color: #c4c4ff;
502 border: 1px solid #7878ff;
503 border-radius: 3px;
504 height: 18px;
505 padding: 0 6px;
506 text-overflow: ellipsis;
507 background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUnpolg7AAAAHJQTFRFAAAAVVWqZmbMVVXVYGDgbW3td3fuc3PzdHT0cHD1d3f6dHT6dnb7dHT7dnb8dnb8dnb9d3f9dnb+eHj+d3f+eHj+d3f+d3f+d3f+eHj+d3f+eHj+d3f+eHj+d3f+d3f+eHj+d3f+d3f+d3f+eHj/////V9oQhQAAACR0Uk5TAAIEBQcNDhMVGCotNTZAT217i5CgobvExtjZ4eLr7vP09ff7uqQ6cgAAAAFiS0dEJcMByQ8AAABUSURBVBjTpc43AoAwDENRh95bgNBM1f3PyOpslD++RSJ61YgH5M2IbIkn4GocSR1MZVBL4t2n4FgkbaxI8Sqph041WknZCWAIrcmEUbpf3lNe0N9u59YFYHnZ78gAAAAASUVORK5CYII=);
508 background-repeat: no-repeat;
509 padding-left: 18px;
510}
511
512span.refs span.tag {
513 color: #707070;
514 display: inline-block;
515 margin: 0;
516 background-color: #ffffab;
517 border: 1px solid #d9d93b;
518 border-radius: 3px;
519 height: 18px;
520 padding: 0 6px;
521 text-overflow: ellipsis;
522 background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUZZ+h9RwAAAGZQTFRFAAAAtrYkwMBAwMBAx8c4yso11NQ71NQ51dU52Ng71tY519c719c719c62Ng719c719c62Ng72dk62Ng62Ng72Ng72dk62Ng72Ng62dk62dk72dk62Ng62dk72Ng72Ng72dk7////ou/AnQAAACB0Uk5TAAYHCxESLjRCWWlqa4uNkpissbrO19jc3ufs8vf6/f7atAU2AAAAAWJLR0QhxGwNFgAAAF1JREFUGFeNy0cOgCAABVGw94rY5d//lC7omhhn+ZIh5Gf1xPk0Zi5dAABROIQjSU/fsAXhDkCUljAv8jW2wlQpaixpo4Nj+dtatVpjkSJjLNaizRVpvhBCu/4h391jzw1lU12Z7wAAAABJRU5ErkJggg==);
523 background-repeat: no-repeat;
524 padding-left: 18px;
525}
526
527span.refs span.head {
528 color: #707070;
529 display: inline-block;
530 margin: 0;
531 background-color: #c4ffc4;
532 border: 1px solid #78ff78;
533 border-radius: 3px;
534 height: 18px;
535 padding: 0 6px;
536 text-overflow: ellipsis;
537 background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSYDsafX/gAAAUpJREFUOMvVkjFLA0EQhd/s7l06MSCihbV/wC5/QBDEIFYWprRIIQQJFqKFQi4kUbBQsFSwtrUQLQULUTBFLCzVIgimCXe7z0q5yIWcqfRVwzDzMTNvgL8mSUqWw3JOtFQJdsIwLDYyjdYgkEmkazl2oVtQWk36nn8AYBYASmFpxmizGtnoqO7Vb+M9KglEkASdpWU872nvVCiPRpuTnz2JIHGyqX3d0kZfR1G0Ht+g/do+FIhOBbLW3n/FNb/28D0puZ+dyL44ur1UoH5yzt2JyIj6UGdDgwrPhYzSagNEszJaeU/lWlylbmnaeGZZICsAppxzi6nt73HK85oQCMknOuarpno+FIjglVjZDXaCS2yDv3rIHlCb88FY0BlUl3hs7ektkhckb5DFWhoz+n12zr7ZPLpYUqLm0oBMn8NUzLhpAgjpWMS/1CcSJ3ykD7Rk1QAAAABJRU5ErkJggg==);
538 background-repeat: no-repeat;
539 padding-left: 18px;
540}
541
542span.refs a {
543 color: #4e4e4e;
544 font: 11px "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, monospace;
545 line-height: 18px;
546}
547
548/* Diffs
549---------------------------------------------------------------------------- */
550
551div.diff.to_file a.path,
552div.diff.to_file {
553 color: #007000;
554}
555
556div.diff.from_file a.path,
557div.diff.from_file {
558 color: #aa0000;
559}
560
561.patch .header {
562 margin: 0;
563}
564
565.patchset {
566 overflow-x: auto;
567 overflow-y: hidden;
568}
569
570.chunk_header {
571 background: #eaf2f5;
572 color: #999;
573}
574
575.rem {
576 background: #ffdddd;
577}
578.rem .marked {
579 background: #ffaaaa;
580}
581.add {
582 background: #ddffdd;
583}
584.add .marked {
585 background: #7dff7d;
586}
587
588.extended_header {
589 width: 99.5%;
590}
591
592div.chunk_block {
593 overflow: hidden;
594}
595
596div.chunk_block div.old {
597 float: left;
598 width: 50%;
599 overflow: hidden;
600 border-right: 5px solid #EAF2F5;
601}
602
603div.chunk_block.rem,
604div.chunk_block.add {
605 background: transparent;
606}
607
608div.chunk_block div.old .add,
609div.chunk_block div.old .rem {
610 padding-right: 3px;
611}
612
613div.chunk_block div.new .add,
614div.chunk_block div.new .rem {
615 padding-left: 3px;
616}
617
618div.chunk_block div.new {
619 margin-left: 50%;
620 width: 50%;
621 border-left: 5px solid #EAF2F5;
622}
623
624/* Category
625---------------------------------------------------------------------------- */
626
627td.category {
628 background: #E6F1F6; /* old browsers */
629 background: -moz-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); /* firefox */
630 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#C8D8E7), color-stop(100%,#E6F1F3)); /* webkit */
631 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C8D8E7', endColorstr='#E6F1F3',GradientType=0 ); /* ie */
632 background: -o-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%);
633 font-weight: bold;
634 border-bottom: 1px solid #D1D1D1;
635 border-top: 1px solid #D1D1D1;
636}
637
638/* Age
639---------------------------------------------------------------------------- */
640
641/* noage: "No commits" */
642.project_list td.noage {
643 color: #cdcdcd;
644}
645
646/* age2: 60*60*24*2 <= age */
647.project_list td.age2, .blame td.age2 {
648 color: #545454;
649}
650
651/* age1: 60*60*2 <= age < 60*60*24*2 */
652.project_list td.age1 {
653 color: #009900;
654}
655
656/* age0: age < 60*60*2 */
657.project_list td.age0 {
658 color: #009900;
659 font-weight: bold;
660}
661
662/* File status
663---------------------------------------------------------------------------- */
664
665.diff_tree span.file_status.new {
666 color: #008000;
667}
668
669table.diff_tree span.file_status.deleted {
670 color: #c00000;
671}
672
673table.diff_tree span.file_status.moved,
674table.diff_tree span.file_status.mode_chnge {
675 color: #545454;
676}
677
678table.diff_tree span.file_status.copied {
679 color: #70a070;
680}
681
682span.cntrl {
683 border: dashed #aaaaaa;
684 border-width: 1px;
685 padding: 0px 2px 0px 2px;
686 margin: 0px 2px 0px 2px;
687}
688
689span.match {
690 background: #aaffaa;
691 color: #000;
692}
693
694td.error {
695 color: red;
696 background: yellow;
697}
698
699/* blob view */
700
701td.pre, div.pre, div.diff {
702 white-space: pre-wrap;
703}
704
705/* JavaScript-based timezone manipulation */
706
707.popup { /* timezone selection UI */
708 position: absolute;
709 /* "top: 0; right: 0;" would be better, if not for bugs in browsers */
710 top: 0; left: 0;
711 border: 1px solid #d8d8d8;
712 padding: 2px;
713 background-color: #f0f0f0;
714 font-style: normal;
715 color: #545454;
716 cursor: auto;
717}
718
719.close-button { /* close timezone selection UI without selecting */
720 /* float doesn't work within absolutely positioned container,
721 * if width of container is not set explicitly */
722 /* float: right; */
723 position: absolute;
724 top: 0px; right: 0px;
725 border: 1px solid #ffaaaa;
726 margin: 1px 1px 1px 1px;
727 padding-bottom: 2px;
728 width: 12px;
729 height: 10px;
730 font-size: 9px;
731 font-weight: bold;
732 text-align: center;
733 background-color: #ffdddd;
734 cursor: pointer;
735}
736
737/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */
738
739/* Highlighting theme definition: */
740
741.num { color:#6ecf36; }
742.esc { color:#ff00ff; }
743.str { color:#ff00d3; background-color: #edc9ec }
744.dstr { color:#818100; }
745.slc { color:#838183; font-style:italic; }
746.com { color:#838183; font-style:italic; }
747.dir { color:#008200; }
748.sym { color:#000000; }
749.line { color:#555555; }
750.kwa { color:#666666; font-weight:bold; }
751.kwb { color:#6b3099; }
752.kwc { color:#d4663d; }
753.kwd { color:#2928ff; }
754
755/**** Styles supplémentaires *****/
756
757.readme div.toc {
758 float: right;
759 border: 1px solid black;
760 background-color: white;
761}
762.readme div.toc span.toctitle {
763 display: inline-block;
764 width: 100%;
765 text-align: center;
766 font-weight: bold;
767}
768
769.readme table {
770 background-color: white;
771}
772
773.readme table thead tr {
774 background-color: #ccc;
775}
776
777.readme table tbody tr:nth-child(2n) {
778 background-color: #f8f8f8;
779}
780
781.readme table td, .readme table th {
782 border: 1px solid black;
783}
diff --git a/overlays/gitweb/theme/gitweb.js b/overlays/gitweb/theme/gitweb.js
new file mode 100644
index 00000000..72f3cfa5
--- /dev/null
+++ b/overlays/gitweb/theme/gitweb.js
@@ -0,0 +1,27 @@
1function include(filename, onload) {
2 var head = document.getElementsByTagName('head')[0];
3 var script = document.createElement('script');
4 script.src = filename;
5 script.type = 'text/javascript';
6 script.onload = script.onreadystatechange = function() {
7 if (script.readyState) {
8 if (script.readyState === 'complete' || script.readyState === 'loaded') {
9 script.onreadystatechange = null;
10 onload();
11 }
12 }
13 else {
14 onload();
15 }
16 }
17 head.appendChild(script);
18}
19
20include('static/gitweb.js', function() {});
21include('//code.jquery.com/jquery-3.1.0.min.js', function() {
22 $("div.title").each(function(index, element) {
23 if ($(element).text() === "readme" || $(element).text() === " ") {
24 $(element).hide();
25 }
26 });
27});
diff --git a/overlays/goaccess/default.nix b/overlays/goaccess/default.nix
new file mode 100644
index 00000000..12b28f3b
--- /dev/null
+++ b/overlays/goaccess/default.nix
@@ -0,0 +1,13 @@
1self: super: {
2 goaccess = super.goaccess.overrideAttrs(old: rec {
3 name = "goaccess-${version}";
4 version = "1.3";
5 src = self.fetchurl {
6 url = "https://tar.goaccess.io/${name}.tar.gz";
7 sha256 = "16vv3pj7pbraq173wlxa89jjsd279004j4kgzlrsk1dz4if5qxwc";
8 };
9 configureFlags = old.configureFlags ++ [ "--enable-tcb=btree" ];
10 buildInputs = old.buildInputs ++ [ self.tokyocabinet self.bzip2 ];
11 });
12
13}
diff --git a/overlays/kanboard/default.nix b/overlays/kanboard/default.nix
new file mode 100644
index 00000000..81b39fec
--- /dev/null
+++ b/overlays/kanboard/default.nix
@@ -0,0 +1,18 @@
1self: super: {
2 kanboard = { kanboard_config ? "/etc/kanboard/config.php" }:
3 super.kanboard.overrideAttrs(old: rec {
4 name = "kanboard-${version}";
5 version = "1.2.9";
6 src = self.fetchFromGitHub {
7 owner = "kanboard";
8 repo = "kanboard";
9 rev = "c4152316b14936556edf3bcc4d11f16ba31b8ae7";
10 sha256 = "18bn9zhyfc5x28hwcxss7chdq7c8rshc8jxgai65i5l68iwhvjg7";
11 };
12 installPhase = ''
13 cp -a . $out
14 ln -s ${kanboard_config} $out/config.php
15 mv $out/data $out/dataold
16 '';
17 });
18}
diff --git a/overlays/ldapvi/default.nix b/overlays/ldapvi/default.nix
new file mode 100644
index 00000000..030e6769
--- /dev/null
+++ b/overlays/ldapvi/default.nix
@@ -0,0 +1,3 @@
1self: super: {
2 ldapvi = super.ldapvi.overrideAttrs (old: self.mylibs.fetchedGit ./ldapvi.json);
3}
diff --git a/overlays/ldapvi/ldapvi.json b/overlays/ldapvi/ldapvi.json
new file mode 100644
index 00000000..ceaff712
--- /dev/null
+++ b/overlays/ldapvi/ldapvi.json
@@ -0,0 +1,14 @@
1{
2 "tag": "f1d42ba-master",
3 "meta": {
4 "name": "ldapvi",
5 "url": "http://www.lichteblau.com/git/ldapvi.git",
6 "branch": "master"
7 },
8 "git": {
9 "url": "http://www.lichteblau.com/git/ldapvi.git",
10 "rev": "f1d42bad66cc4623d1ff21fbd5dddbf5009d3e40",
11 "sha256": "0c2h4b1spp9z6a16gy9azf0wyxq397yy7001x1zlvc7c60q11wry",
12 "fetchSubmodules": true
13 }
14}
diff --git a/overlays/lesspipe/default.nix b/overlays/lesspipe/default.nix
new file mode 100644
index 00000000..e53feae6
--- /dev/null
+++ b/overlays/lesspipe/default.nix
@@ -0,0 +1,5 @@
1self: super: {
2 lesspipe = super.lesspipe.overrideAttrs(old: {
3 configureFlags = (old.configureFlags or []) ++ [ "--yes" ];
4 });
5}
diff --git a/overlays/neomutt/default.nix b/overlays/neomutt/default.nix
new file mode 100644
index 00000000..c8578c9a
--- /dev/null
+++ b/overlays/neomutt/default.nix
@@ -0,0 +1,8 @@
1self: super: {
2 neomutt = super.neomutt.overrideAttrs (old:
3 {
4 buildInputs = old.buildInputs ++ [ self.gdbm ];
5 configureFlags = old.configureFlags ++ [ "--gdbm" ];
6 }
7 );
8}
diff --git a/overlays/nixops/default.nix b/overlays/nixops/default.nix
new file mode 100644
index 00000000..eb29ecd0
--- /dev/null
+++ b/overlays/nixops/default.nix
@@ -0,0 +1,7 @@
1self: super: {
2 nixops = super.nixops.overrideAttrs (old: {
3 preConfigure = (old.preConfigure or "") + ''
4 sed -i -e "/'keyFile'/s/'path'/'string'/" nixops/backends/__init__.py
5 '';
6 });
7}
diff --git a/overlays/pass/default.nix b/overlays/pass/default.nix
new file mode 100644
index 00000000..df42cf19
--- /dev/null
+++ b/overlays/pass/default.nix
@@ -0,0 +1,8 @@
1self: super: {
2 pass = (super.pass.withExtensions (exts: [ exts.pass-otp ])).overrideAttrs (old:
3 self.mylibs.fetchedGit ./pass.json // {
4 patches = old.patches ++ [ ./pass-fix-pass-init.patch ];
5 }
6 );
7
8}
diff --git a/overlays/pass/pass-fix-pass-init.patch b/overlays/pass/pass-fix-pass-init.patch
new file mode 100644
index 00000000..10a76c16
--- /dev/null
+++ b/overlays/pass/pass-fix-pass-init.patch
@@ -0,0 +1,42 @@
1From 33e8f1cd0065639a948d7b5ba3f93d43bdf7f3be Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= <ismael.bouya@normalesup.org>
3Date: Sun, 11 Nov 2018 19:47:33 +0100
4Subject: [PATCH] Fix pass init for some gpg keys
5
6This fixes the pass init for gpg keys which have their main key as
7encryption key. This may happen for instance with RSA keys and specific
8configuration.
9---
10 src/password-store.sh | 2 +-
11 tests/t0300-reencryption.sh | 2 +-
12 2 files changed, 2 insertions(+), 2 deletions(-)
13
14diff --git a/src/password-store.sh b/src/password-store.sh
15index d89d455..44d122e 100755
16--- a/src/password-store.sh
17+++ b/src/password-store.sh
18@@ -124,7 +124,7 @@ reencrypt_path() {
19 IFS=";" eval 'GPG_RECIPIENTS+=( $group )' # http://unix.stackexchange.com/a/92190
20 unset "GPG_RECIPIENTS[$index]"
21 done
22- gpg_keys="$($GPG $PASSWORD_STORE_GPG_OPTS --list-keys --with-colons "${GPG_RECIPIENTS[@]}" | sed -n 's/^sub:[^:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u)"
23+ gpg_keys="$($GPG $PASSWORD_STORE_GPG_OPTS --list-keys --with-colons "${GPG_RECIPIENTS[@]}" | sed -n 's/^[ps]ub:[^:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u)"
24 fi
25 current_keys="$(LC_ALL=C $GPG $PASSWORD_STORE_GPG_OPTS -v --no-secmem-warning --no-permission-warning --decrypt --list-only --keyid-format long "$passfile" 2>&1 | sed -n 's/^gpg: public key is \([A-F0-9]\+\)$/\1/p' | LC_ALL=C sort -u)"
26
27diff --git a/tests/t0300-reencryption.sh b/tests/t0300-reencryption.sh
28index 3c88987..57d873f 100755
29--- a/tests/t0300-reencryption.sh
30+++ b/tests/t0300-reencryption.sh
31@@ -7,7 +7,7 @@ cd "$(dirname "$0")"
32 INITIAL_PASSWORD="will this password live? a big question indeed..."
33
34 canonicalize_gpg_keys() {
35- $GPG --list-keys --with-colons "$@" | sed -n 's/sub:[^:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u
36+ $GPG --list-keys --with-colons "$@" | sed -n 's/[ps]ub:[^:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u
37 }
38 gpg_keys_from_encrypted_file() {
39 $GPG -v --no-secmem-warning --no-permission-warning --decrypt --list-only --keyid-format long "$1" 2>&1 | grep "public key is" | cut -d ' ' -f 5 | LC_ALL=C sort -u
40--
412.19.1
42
diff --git a/overlays/pass/pass.json b/overlays/pass/pass.json
new file mode 100644
index 00000000..a4638c13
--- /dev/null
+++ b/overlays/pass/pass.json
@@ -0,0 +1,14 @@
1{
2 "tag": "d29a389-master",
3 "meta": {
4 "name": "password-store",
5 "url": "https://git.zx2c4.com/password-store/",
6 "branch": "master"
7 },
8 "git": {
9 "url": "https://git.zx2c4.com/password-store/",
10 "rev": "d29a389a40524c684595f51bb937f66958bc14ea",
11 "sha256": "17g43i0if9nggcq6005iyxxy9my8s15ihc2nzwjgqzhy3svh5xvn",
12 "fetchSubmodules": true
13 }
14}
diff --git a/overlays/pelican/default.nix b/overlays/pelican/default.nix
new file mode 100644
index 00000000..5f60b8f7
--- /dev/null
+++ b/overlays/pelican/default.nix
@@ -0,0 +1,6 @@
1self: super: {
2 pelican = with self.python3Packages;
3 pelican.overrideAttrs(old: self.mylibs.fetchedGithub ./pelican.json // {
4 propagatedBuildInputs = old.propagatedBuildInputs ++ [ pyyaml ];
5 });
6}
diff --git a/overlays/pelican/pelican.json b/overlays/pelican/pelican.json
new file mode 100644
index 00000000..d8f4425e
--- /dev/null
+++ b/overlays/pelican/pelican.json
@@ -0,0 +1,15 @@
1{
2 "tag": "4.0.1",
3 "meta": {
4 "name": "pelican",
5 "url": "https://github.com/getpelican/pelican",
6 "branch": "refs/tags/4.0.1"
7 },
8 "github": {
9 "owner": "getpelican",
10 "repo": "pelican",
11 "rev": "24d6efa9fda4ad45649ddf88c1c596193d589bf8",
12 "sha256": "09fcwnnfln0cl5v0qpxzrllj27znrg6dbhaksxrl0192c3mbyjvl",
13 "fetchSubmodules": true
14 }
15}
diff --git a/overlays/profanity/default.nix b/overlays/profanity/default.nix
new file mode 100644
index 00000000..33861f1b
--- /dev/null
+++ b/overlays/profanity/default.nix
@@ -0,0 +1,9 @@
1self: super: {
2 profanity = (super.profanity.override {
3 notifySupport = true;
4 inherit (self) libnotify gpgme gdk_pixbuf;
5 python = self.python3;
6 }).overrideAttrs (old: rec {
7 configureFlags = old.configureFlags ++ [ "--enable-plugins" ];
8 });
9}
diff --git a/overlays/python-packages/buildbot.nix b/overlays/python-packages/buildbot.nix
new file mode 100644
index 00000000..ccf2f6a7
--- /dev/null
+++ b/overlays/python-packages/buildbot.nix
@@ -0,0 +1,8 @@
1self: super: {
2 pythonOverrides = self.buildPythonOverrides (pyself: pysuper: {
3 buildbot-plugins = pysuper.buildbot-plugins // {
4 buildslist = self.python3PackagesPlus.buildbot-plugins.buildslist;
5 };
6 buildbot-full = pysuper.buildbot-full.withPlugins [ pyself.buildbot-plugins.buildslist ];
7 }) super.pythonOverrides;
8}
diff --git a/overlays/python-packages/default.nix b/overlays/python-packages/default.nix
new file mode 100644
index 00000000..8a9949e6
--- /dev/null
+++ b/overlays/python-packages/default.nix
@@ -0,0 +1,28 @@
1let
2 fromMyPythonPackages = name: self: super: {
3 pythonOverrides = self.buildPythonOverrides (pyself: pysuper: {
4 "${name}" = self."${pyself.python.pname}PackagesPlus"."${name}";
5 }) super.pythonOverrides;
6 };
7in
8{
9 # https://github.com/NixOS/nixpkgs/issues/44426
10 # needs to come before all other in alphabetical order (or make use of
11 # lib.mkBefore)
12 __pythonOverlayFix = self: super: let
13 pyNames = [ "python3" "python36" "python37" ];
14 overriddenPython = name: [
15 { inherit name; value = super.${name}.override { packageOverrides = self.pythonOverrides; }; }
16 { name = "${name}Packages"; value = self.recurseIntoAttrs self.${name}.pkgs; }
17 ];
18 overriddenPythons = builtins.concatLists (map overriddenPython pyNames);
19 in {
20 pythonOverrides = pyself: pysuper: {};
21 buildPythonOverrides = newOverrides: currentOverrides: super.lib.composeExtensions newOverrides currentOverrides;
22 } // super.lib.attrsets.listToAttrs overriddenPythons;
23
24
25 apprise = fromMyPythonPackages "apprise";
26 buildbot = import ./buildbot.nix;
27 wokkel = fromMyPythonPackages "wokkel";
28}
diff --git a/overlays/sc-im/default.nix b/overlays/sc-im/default.nix
new file mode 100644
index 00000000..f7286552
--- /dev/null
+++ b/overlays/sc-im/default.nix
@@ -0,0 +1,9 @@
1self: super: {
2 sc-im = super.sc-im.overrideAttrs (old: {
3 buildPhase = ''
4 cd src
5 sed -i Makefile -e 's@\...name.info@.local/state/$(name)info@'
6 cd ..
7 '' + old.buildPhase;
8 });
9}
diff --git a/overlays/shaarli/default.nix b/overlays/shaarli/default.nix
new file mode 100644
index 00000000..c2fb9cce
--- /dev/null
+++ b/overlays/shaarli/default.nix
@@ -0,0 +1,10 @@
1self: super: {
2 shaarli = varDir: super.shaarli.overrideAttrs (old: {
3 patchPhase = "";
4 patches = (old.patches or []) ++ [ ./shaarli_ldap.patch ];
5 installPhase = (old.installPhase or "") + ''
6 cp .htaccess $out/
7 ln -sf ${varDir}/{cache,pagecache,tmp,data} $out/
8 '';
9 });
10}
diff --git a/overlays/shaarli/shaarli_ldap.patch b/overlays/shaarli/shaarli_ldap.patch
new file mode 100644
index 00000000..9c7315a1
--- /dev/null
+++ b/overlays/shaarli/shaarli_ldap.patch
@@ -0,0 +1,420 @@
1commit bc82ebfd779b8641dadd6787f51639ea9105c3e8
2Author: Ismaël Bouya <ismael.bouya@normalesup.org>
3Date: Sun Feb 3 20:58:18 2019 +0100
4
5 Add ldap connection
6
7diff --git a/.htaccess b/.htaccess
8index 4c00427..5acd708 100644
9--- a/.htaccess
10+++ b/.htaccess
11@@ -6,10 +6,23 @@ RewriteEngine On
12 # Prevent accessing subdirectories not managed by SCM
13 RewriteRule ^(.git|doxygen|vendor) - [F]
14
15+RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
16+RewriteRule ^(.*) - [E=BASE:%1]
17+
18+RewriteCond %{ENV:REDIRECT_BASE} (.+)
19+RewriteRule .* - [E=BASE:%1]
20+
21 # Forward the "Authorization" HTTP header
22 RewriteCond %{HTTP:Authorization} ^(.*)
23 RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
24
25+RewriteCond %{REQUEST_FILENAME} !-f
26+RewriteCond %{REQUEST_FILENAME} !-d
27+RewriteRule ^((?!api/)[^/]*)/?(.*)$ $2?%{QUERY_STRING} [E=USERSPACE:$1]
28+
29+RewriteCond %{ENV:REDIRECT_USERSPACE} (.+)
30+RewriteRule .* - [E=USERSPACE:%1]
31+
32 # REST API
33 RewriteCond %{REQUEST_FILENAME} !-f
34 RewriteCond %{REQUEST_FILENAME} !-d
35diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php
36index 911873a..f21a1ef 100644
37--- a/application/ApplicationUtils.php
38+++ b/application/ApplicationUtils.php
39@@ -191,6 +191,9 @@ public static function checkResourcePermissions($conf)
40 $conf->get('resource.page_cache'),
41 $conf->get('resource.raintpl_tmp'),
42 ) as $path) {
43+ if (! is_dir($path)) {
44+ mkdir($path, 0755, true);
45+ }
46 if (! is_readable(realpath($path))) {
47 $errors[] = '"'.$path.'" '. t('directory is not readable');
48 }
49diff --git a/application/config/ConfigManager.php b/application/config/ConfigManager.php
50index 32aaea4..99efc15 100644
51--- a/application/config/ConfigManager.php
52+++ b/application/config/ConfigManager.php
53@@ -21,6 +21,11 @@ class ConfigManager
54
55 public static $DEFAULT_PLUGINS = array('qrcode');
56
57+ /**
58+ * @var string User space.
59+ */
60+ protected $userSpace;
61+
62 /**
63 * @var string Config folder.
64 */
65@@ -41,12 +46,36 @@ class ConfigManager
66 *
67 * @param string $configFile Configuration file path without extension.
68 */
69- public function __construct($configFile = 'data/config')
70+ public function __construct($configFile = null, $userSpace = null)
71 {
72- $this->configFile = $configFile;
73+ $this->userSpace = $this->findLDAPUser($userSpace);
74+ if ($configFile !== null) {
75+ $this->configFile = $configFile;
76+ } else {
77+ $this->configFile = ($this->userSpace === null) ? 'data/config' : 'data/' . $this->userSpace . '/config';
78+ }
79 $this->initialize();
80 }
81
82+ public function findLDAPUser($login, $password = null) {
83+ $connect = ldap_connect(getenv('SHAARLI_LDAP_HOST'));
84+ ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
85+ if (!$connect || !ldap_bind($connect, getenv('SHAARLI_LDAP_DN'), getenv('SHAARLI_LDAP_PASSWORD'))) {
86+ return false;
87+ }
88+
89+ $search_query = str_replace('%login%', ldap_escape($login), getenv('SHAARLI_LDAP_FILTER'));
90+
91+ $search = ldap_search($connect, getenv('SHAARLI_LDAP_BASE'), $search_query);
92+ $info = ldap_get_entries($connect, $search);
93+
94+ if (ldap_count_entries($connect, $search) == 1 && (is_null($password) || ldap_bind($connect, $info[0]["dn"], $password))) {
95+ return $login;
96+ } else {
97+ return null;
98+ }
99+ }
100+
101 /**
102 * Reset the ConfigManager instance.
103 */
104@@ -269,6 +298,16 @@ public function getConfigFileExt()
105 return $this->configFile . $this->configIO->getExtension();
106 }
107
108+ /**
109+ * Get the current userspace.
110+ *
111+ * @return mixed User space.
112+ */
113+ public function getUserSpace()
114+ {
115+ return $this->userSpace;
116+ }
117+
118 /**
119 * Recursive function which find asked setting in the loaded config.
120 *
121@@ -342,19 +381,31 @@ protected static function removeConfig($settings, &$conf)
122 */
123 protected function setDefaultValues()
124 {
125- $this->setEmpty('resource.data_dir', 'data');
126- $this->setEmpty('resource.config', 'data/config.php');
127- $this->setEmpty('resource.datastore', 'data/datastore.php');
128- $this->setEmpty('resource.ban_file', 'data/ipbans.php');
129- $this->setEmpty('resource.updates', 'data/updates.txt');
130- $this->setEmpty('resource.log', 'data/log.txt');
131- $this->setEmpty('resource.update_check', 'data/lastupdatecheck.txt');
132- $this->setEmpty('resource.history', 'data/history.php');
133+ if ($this->userSpace === null) {
134+ $data = 'data';
135+ $tmp = 'tmp';
136+ $cache = 'cache';
137+ $pagecache = 'pagecache';
138+ } else {
139+ $data = 'data/' . ($this->userSpace);
140+ $tmp = 'tmp/' . ($this->userSpace);
141+ $cache = 'cache/' . ($this->userSpace);
142+ $pagecache = 'pagecache/' . ($this->userSpace);
143+ }
144+
145+ $this->setEmpty('resource.data_dir', $data);
146+ $this->setEmpty('resource.config', $data . '/config.php');
147+ $this->setEmpty('resource.datastore', $data . '/datastore.php');
148+ $this->setEmpty('resource.ban_file', $data . '/ipbans.php');
149+ $this->setEmpty('resource.updates', $data . '/updates.txt');
150+ $this->setEmpty('resource.log', $data . '/log.txt');
151+ $this->setEmpty('resource.update_check', $data . '/lastupdatecheck.txt');
152+ $this->setEmpty('resource.history', $data . '/history.php');
153 $this->setEmpty('resource.raintpl_tpl', 'tpl/');
154 $this->setEmpty('resource.theme', 'default');
155- $this->setEmpty('resource.raintpl_tmp', 'tmp/');
156- $this->setEmpty('resource.thumbnails_cache', 'cache');
157- $this->setEmpty('resource.page_cache', 'pagecache');
158+ $this->setEmpty('resource.raintpl_tmp', $tmp);
159+ $this->setEmpty('resource.thumbnails_cache', $cache);
160+ $this->setEmpty('resource.page_cache', $pagecache);
161
162 $this->setEmpty('security.ban_after', 4);
163 $this->setEmpty('security.ban_duration', 1800);
164diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php
165index d6784d6..bdfaca7 100644
166--- a/application/security/LoginManager.php
167+++ b/application/security/LoginManager.php
168@@ -32,6 +32,9 @@ class LoginManager
169 /** @var string User sign-in token depending on remote IP and credentials */
170 protected $staySignedInToken = '';
171
172+ protected $lastErrorReason = '';
173+ protected $lastErrorIsBanishable = false;
174+
175 /**
176 * Constructor
177 *
178@@ -83,7 +86,7 @@ public function getStaySignedInToken()
179 */
180 public function checkLoginState($cookie, $clientIpId)
181 {
182- if (! $this->configManager->exists('credentials.login')) {
183+ if (! $this->configManager->exists('credentials.login') || (isset($_SESSION['username']) && $_SESSION['username'] && $this->configManager->get('credentials.login') !== $_SESSION['username'])) {
184 // Shaarli is not configured yet
185 $this->isLoggedIn = false;
186 return;
187@@ -133,20 +136,40 @@ public function isLoggedIn()
188 */
189 public function checkCredentials($remoteIp, $clientIpId, $login, $password)
190 {
191- $hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
192+ $this->lastErrorIsBanishable = false;
193+
194+ if ($this->configManager->getUserSpace() !== null && $this->configManager->getUserSpace() !== $login) {
195+ logm($this->configManager->get('resource.log'),
196+ $remoteIp,
197+ 'Trying to login to wrong user space');
198+ $this->lastErrorReason = 'You’re trying to access the wrong account.';
199+ return false;
200+ }
201
202- if ($login != $this->configManager->get('credentials.login')
203- || $hash != $this->configManager->get('credentials.hash')
204- ) {
205+ logm($this->configManager->get('resource.log'),
206+ $remoteIp,
207+ 'Trying LDAP connection');
208+ $result = $this->configManager->findLDAPUser($login, $password);
209+ if ($result === false) {
210 logm(
211 $this->configManager->get('resource.log'),
212 $remoteIp,
213- 'Login failed for user ' . $login
214+ 'Impossible to connect to LDAP'
215 );
216+ $this->lastErrorReason = 'Server error.';
217+ return false;
218+ } else if (is_null($result)) {
219+ logm(
220+ $this->configManager->get('resource.log'),
221+ $remoteIp,
222+ 'Login failed for user ' . $login
223+ );
224+ $this->lastErrorIsBanishable = true;
225+ $this->lastErrorReason = 'Wrong login/password.';
226 return false;
227 }
228
229- $this->sessionManager->storeLoginInfo($clientIpId);
230+ $this->sessionManager->storeLoginInfo($clientIpId, $login);
231 logm(
232 $this->configManager->get('resource.log'),
233 $remoteIp,
234@@ -187,6 +210,10 @@ protected function writeBanFile()
235 */
236 public function handleFailedLogin($server)
237 {
238+ if (!$this->lastErrorIsBanishable) {
239+ return $this->lastErrorReason ?: 'Error during login.';
240+ };
241+
242 $ip = $server['REMOTE_ADDR'];
243 $trusted = $this->configManager->get('security.trusted_proxies', []);
244
245@@ -215,6 +242,7 @@ public function handleFailedLogin($server)
246 );
247 }
248 $this->writeBanFile();
249+ return $this->lastErrorReason ?: 'Error during login.';
250 }
251
252 /**
253diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php
254index b8b8ab8..5eb4aac 100644
255--- a/application/security/SessionManager.php
256+++ b/application/security/SessionManager.php
257@@ -111,10 +111,10 @@ public static function checkId($sessionId)
258 *
259 * @param string $clientIpId Client IP address identifier
260 */
261- public function storeLoginInfo($clientIpId)
262+ public function storeLoginInfo($clientIpId, $login = null)
263 {
264 $this->session['ip'] = $clientIpId;
265- $this->session['username'] = $this->conf->get('credentials.login');
266+ $this->session['username'] = $login ?: $this->conf->get('credentials.login');
267 $this->extendTimeValidityBy(self::$SHORT_TIMEOUT);
268 }
269
270diff --git a/index.php b/index.php
271index 4b86a3e..85376e8 100644
272--- a/index.php
273+++ b/index.php
274@@ -121,7 +121,27 @@
275 $_COOKIE['shaarli'] = session_id();
276 }
277
278-$conf = new ConfigManager();
279+$folderBase = getenv("BASE");
280+
281+if (getenv("USERSPACE")) {
282+ if (isset($_GET["do"]) && $_GET["do"] == "login") {
283+ header("Location: $folderBase/?do=login");
284+ exit;
285+ }
286+ $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', getenv("USERSPACE"));
287+} else if (isset($_SESSION["username"]) && $_SESSION["username"]) {
288+ header("Location: " . $folderBase . "/" . $_SESSION["username"] . "?");
289+ exit;
290+} else if (!isset($_GET["do"]) || $_GET["do"] != "login") {
291+ header("Location: $folderBase/?do=login");
292+ exit;
293+}
294+
295+if (isset($userspace)) {
296+ $conf = new ConfigManager(null, $userspace);
297+} else {
298+ $conf = new ConfigManager();
299+}
300 $sessionManager = new SessionManager($_SESSION, $conf);
301 $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager);
302 $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']);
303@@ -175,7 +195,7 @@
304 }
305
306 // Display the installation form if no existing config is found
307- install($conf, $sessionManager, $loginManager);
308+ install($conf, $sessionManager, $loginManager, $userspace);
309 }
310
311 $loginManager->checkLoginState($_COOKIE, $clientIpId);
312@@ -205,6 +225,7 @@ function isLoggedIn()
313 && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password'])
314 ) {
315 $loginManager->handleSuccessfulLogin($_SERVER);
316+ $userspace = $_POST['login'];
317
318 $cookiedir = '';
319 if (dirname($_SERVER['SCRIPT_NAME']) != '/') {
320@@ -241,25 +262,25 @@ function isLoggedIn()
321 $uri .= '&'.$param.'='.urlencode($_GET[$param]);
322 }
323 }
324- header('Location: '. $uri);
325+ header('Location: '. $userspace . $uri);
326 exit;
327 }
328
329 if (isset($_GET['edit_link'])) {
330- header('Location: ?edit_link='. escape($_GET['edit_link']));
331+ header('Location: ' . $userspace . '?edit_link='. escape($_GET['edit_link']));
332 exit;
333 }
334
335 if (isset($_POST['returnurl'])) {
336 // Prevent loops over login screen.
337 if (strpos($_POST['returnurl'], 'do=login') === false) {
338- header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
339+ header('Location: ' . generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
340 exit;
341 }
342 }
343- header('Location: ?'); exit;
344+ header('Location: '. $userspace . '?'); exit;
345 } else {
346- $loginManager->handleFailedLogin($_SERVER);
347+ $errorReason = $loginManager->handleFailedLogin($_SERVER);
348 $redir = '&username='. urlencode($_POST['login']);
349 if (isset($_GET['post'])) {
350 $redir .= '&post=' . urlencode($_GET['post']);
351@@ -270,7 +291,7 @@ function isLoggedIn()
352 }
353 }
354 // Redirect to login screen.
355- echo '<script>alert("'. t("Wrong login/password.") .'");document.location=\'?do=login'.$redir.'\';</script>';
356+ echo '<script>alert("'. t($errorReason) .'");document.location=\'?do=login'.$redir.'\';</script>';
357 exit;
358 }
359 }
360@@ -1719,7 +1740,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager)
361 * @param SessionManager $sessionManager SessionManager instance
362 * @param LoginManager $loginManager LoginManager instance
363 */
364-function install($conf, $sessionManager, $loginManager) {
365+function install($conf, $sessionManager, $loginManager, $userspace) {
366 // On free.fr host, make sure the /sessions directory exists, otherwise login will not work.
367 if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705);
368
369@@ -1755,7 +1776,7 @@ function install($conf, $sessionManager, $loginManager) {
370 }
371
372
373- if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
374+ if (true)
375 {
376 $tz = 'UTC';
377 if (!empty($_POST['continent']) && !empty($_POST['city'])
378@@ -1764,15 +1785,15 @@ function install($conf, $sessionManager, $loginManager) {
379 $tz = $_POST['continent'].'/'.$_POST['city'];
380 }
381 $conf->set('general.timezone', $tz);
382- $login = $_POST['setlogin'];
383- $conf->set('credentials.login', $login);
384+ $conf->set('credentials.login', $userspace);
385 $salt = sha1(uniqid('', true) .'_'. mt_rand());
386 $conf->set('credentials.salt', $salt);
387- $conf->set('credentials.hash', sha1($_POST['setpassword'] . $login . $salt));
388+ $hash = sha1(uniqid('', true) .'_'. mt_rand());
389+ $conf->set('credentials.hash', $hash);
390 if (!empty($_POST['title'])) {
391 $conf->set('general.title', escape($_POST['title']));
392 } else {
393- $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER)));
394+ $conf->set('general.title', ucwords(str_replace("_", " ", $userspace)));
395 }
396 $conf->set('translation.language', escape($_POST['language']));
397 $conf->set('updates.check_updates', !empty($_POST['updateCheck']));
398@@ -1841,7 +1862,12 @@ function install($conf, $sessionManager, $loginManager) {
399 $app = new \Slim\App($container);
400
401 // REST API routes
402-$app->group('/api/v1', function() {
403+if (isset($userspace)) {
404+ $mountpoint = '/' . $userspace . '/api/v1';
405+} else {
406+ $mountpoint = '/api/v1';
407+}
408+$app->group($mountpoint, function() {
409 $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo');
410 $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks');
411 $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink');
412@@ -1860,7 +1886,7 @@ function install($conf, $sessionManager, $loginManager) {
413 $response = $app->run(true);
414 // Hack to make Slim and Shaarli router work together:
415 // If a Slim route isn't found and NOT API call, we call renderPage().
416-if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) {
417+if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], $mountpoint) === false) {
418 // We use UTF-8 for proper international characters handling.
419 header('Content-Type: text/html; charset=utf-8');
420 renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager);
diff --git a/overlays/slrn/default.nix b/overlays/slrn/default.nix
new file mode 100644
index 00000000..6caef550
--- /dev/null
+++ b/overlays/slrn/default.nix
@@ -0,0 +1,11 @@
1self: super: {
2 slrn = super.slrn.overrideAttrs (old: rec {
3 version = "1.0.3a";
4 name = "slrn-${version}";
5 src = self.fetchurl {
6 url = "http://www.jedsoft.org/releases/slrn/slrn-${version}.tar.bz2";
7 sha256 = "1b1d9iikr60w0vq86y9a0l4gjl0jxhdznlrdp3r405i097as9a1v";
8 };
9 configureFlags = old.configureFlags ++ [ "--with-slrnpull" ];
10 });
11}
diff --git a/overlays/taskwarrior/default.nix b/overlays/taskwarrior/default.nix
new file mode 100644
index 00000000..64ea6900
--- /dev/null
+++ b/overlays/taskwarrior/default.nix
@@ -0,0 +1,13 @@
1self: super:
2{
3 taskwarrior = super.taskwarrior.overrideAttrs (old: {
4 postInstall = ''${old.postInstall}
5 mkdir -p "$out/share/vim/vimfiles/ftdetect"
6 mkdir -p "$out/share/vim/vimfiles/syntax"
7 ln -s "../../../../share/doc/task/scripts/vim/ftdetect/task.vim" "$out/share/vim/vimfiles/ftdetect/"
8 ln -s "../../../../share/doc/task/scripts/vim/syntax/taskrc.vim" "$out/share/vim/vimfiles/syntax/"
9 ln -s "../../../../share/doc/task/scripts/vim/syntax/taskdata.vim" "$out/share/vim/vimfiles/syntax/"
10 ln -s "../../../../share/doc/task/scripts/vim/syntax/taskedit.vim" "$out/share/vim/vimfiles/syntax/"
11 '';
12 });
13}
diff --git a/overlays/vit/default.nix b/overlays/vit/default.nix
new file mode 100644
index 00000000..46242840
--- /dev/null
+++ b/overlays/vit/default.nix
@@ -0,0 +1,8 @@
1self: super:
2{
3 vit = (super.vit.override { inherit (self) taskwarrior; }).overrideAttrs (old:
4 self.mylibs.fetchedGithub ./vit.json // {
5 buildInputs = old.buildInputs ++ (with self.perlPackages; [ TryTiny TextCharWidth ]);
6 }
7 );
8}
diff --git a/overlays/vit/vit.json b/overlays/vit/vit.json
new file mode 100644
index 00000000..d062f685
--- /dev/null
+++ b/overlays/vit/vit.json
@@ -0,0 +1,15 @@
1{
2 "tag": "dbacada-1.3",
3 "meta": {
4 "name": "vit",
5 "url": "https://github.com/scottkosty/vit",
6 "branch": "1.3"
7 },
8 "github": {
9 "owner": "scottkosty",
10 "repo": "vit",
11 "rev": "dbacada5867b238fdf35dbf00a3ca0daf7703038",
12 "sha256": "1wlk62cv6dc0dqv8265xcx2l7ydzg40xf6l4qbrf6h5156ncc90l",
13 "fetchSubmodules": true
14 }
15}
diff --git a/overlays/weboob/default.nix b/overlays/weboob/default.nix
new file mode 100644
index 00000000..d0a15a7d
--- /dev/null
+++ b/overlays/weboob/default.nix
@@ -0,0 +1,15 @@
1self: super: {
2 weboob = (self.pythonPackages.weboob.overridePythonAttrs {
3 setupPyBuildFlags = [ "--no-qt" "--xdg" ];
4 }).overrideAttrs (old: rec {
5 version = "1.5";
6 src = self.fetchurl {
7 url = "https://git.weboob.org/weboob/weboob/-/archive/${version}/${old.pname}-${version}.tar.gz";
8 sha256 = "0l6q5nm5g0zn6gmf809059kddrbds27wgygxsfkqja9blks5vq7z";
9 };
10 postInstall = ''${old.postInstall or ""}
11 mkdir -p $out/share/bash-completion/completions/
12 cp tools/weboob_bash_completion $out/share/bash-completion/completions/weboob
13 '';
14 });
15}
diff --git a/overlays/weechat/default.nix b/overlays/weechat/default.nix
new file mode 100644
index 00000000..17faa0ec
--- /dev/null
+++ b/overlays/weechat/default.nix
@@ -0,0 +1,14 @@
1self: super: {
2 weechat = super.weechat.override {
3 configure = { availablePlugins, ... }: {
4 plugins = with self; with availablePlugins; [
5 # Make sure websocket_client is not 0.55.0, it provokes
6 # regular crashes
7 (python.withPackages (ps: with ps; assert websocket_client.version == "0.54.0"; [websocket_client emoji]))
8 perl
9 ruby
10 ];
11 };
12 };
13
14}
diff --git a/overlays/ympd/default.nix b/overlays/ympd/default.nix
new file mode 100644
index 00000000..dda17aa7
--- /dev/null
+++ b/overlays/ympd/default.nix
@@ -0,0 +1,5 @@
1self: super: {
2 ympd = super.ympd.overrideAttrs(old: self.mylibs.fetchedGithub ./ympd.json // {
3 patches = (old.patches or []) ++ [ ./ympd-password-env.patch ];
4 });
5}
diff --git a/overlays/ympd/ympd-password-env.patch b/overlays/ympd/ympd-password-env.patch
new file mode 100644
index 00000000..2bbe1886
--- /dev/null
+++ b/overlays/ympd/ympd-password-env.patch
@@ -0,0 +1,23 @@
1diff --git a/src/ympd.c b/src/ympd.c
2index 3aed7e6..b3b6fda 100644
3--- a/src/ympd.c
4+++ b/src/ympd.c
5@@ -71,6 +71,7 @@ int main(int argc, char **argv)
6 char *run_as_user = NULL;
7 char const *error_msg = NULL;
8 char *webport = "8080";
9+ const char *s;
10
11 atexit(bye);
12 #ifdef WITH_DYNAMIC_ASSETS
13@@ -92,6 +93,10 @@ int main(int argc, char **argv)
14 {0, 0, 0, 0 }
15 };
16
17+ if ((s = getenv("MPD_PASSWORD")) != NULL) {
18+ mpd.password = strdup(s);
19+ }
20+
21 while((n = getopt_long(argc, argv, "h:p:w:u:vm:",
22 long_options, &option_index)) != -1) {
23 switch (n) {
diff --git a/overlays/ympd/ympd.json b/overlays/ympd/ympd.json
new file mode 100644
index 00000000..51f06d5d
--- /dev/null
+++ b/overlays/ympd/ympd.json
@@ -0,0 +1,15 @@
1{
2 "tag": "612f8fc-master",
3 "meta": {
4 "name": "ympd",
5 "url": "https://github.com/notandy/ympd",
6 "branch": "master"
7 },
8 "github": {
9 "owner": "notandy",
10 "repo": "ympd",
11 "rev": "612f8fc0b2c47fc89d403e4a044541c6b2b238c8",
12 "sha256": "01hnj10zl103mrn82vyd42fvq7w5az3jf1qz18889zv67kn73ll9",
13 "fetchSubmodules": true
14 }
15}