Compare commits
2 Commits
c5f28a9c15
...
cf60f1140c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf60f1140c | ||
|
|
21ad6931b7 |
@@ -54,4 +54,8 @@ config :phoenix, :json_library, Jason
|
||||
|
||||
# Import environment specific config. This must remain at the bottom
|
||||
# of this file so it overrides the configuration defined above.
|
||||
|
||||
config :wax_, origin: "http://localhost:4000", rp_id: :auto
|
||||
config :boruta, Boruta.Oauth, repo: SsoBsn.Repo, issuer: "http://localhost:4000/", contexts: [ resource_owners: SsoBsnWeb.ResourceOwners ]
|
||||
|
||||
import_config "#{config_env()}.exs"
|
||||
|
||||
@@ -26,7 +26,6 @@ config :sso_bsn, SsoBsnWeb.Endpoint,
|
||||
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
|
||||
]
|
||||
|
||||
config :sso_bsn, :session_domain, "localhost"
|
||||
|
||||
# ## SSL Support
|
||||
#
|
||||
@@ -77,5 +76,6 @@ config :phoenix, :plug_init_mode, :runtime
|
||||
# Include HEEx debug annotations as HTML comments in rendered markup
|
||||
config :phoenix_live_view, :debug_heex_annotations, true
|
||||
|
||||
config :wax_, origin: "http://localhost:4000", rp_id: :auto
|
||||
config :boruta, Boruta.Oauth, repo: SsoBsn.Repo, issuer: "http://localhost:4000/", contexts: [ resource_owners: SsoBsnWeb.ResourceOwners ]
|
||||
config :wax_, origin: "http://localhost:4000"
|
||||
config :boruta, Boruta.Oauth, issuer: "http://localhost:4000/"
|
||||
config :sso_bsn, :session_domain, "localhost"
|
||||
|
||||
@@ -16,7 +16,7 @@ import Config
|
||||
#
|
||||
# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
|
||||
# script that automatically sets the env var above.
|
||||
if System.get_env("PHX_SERVER") do
|
||||
if System.get_env("SERVER") do
|
||||
config :sso_bsn, SsoBsnWeb.Endpoint, server: true
|
||||
end
|
||||
|
||||
@@ -44,20 +44,20 @@ if config_env() == :prod do
|
||||
You can generate one by calling: mix phx.gen.secret
|
||||
"""
|
||||
|
||||
host = System.get_env("PHX_HOST") || "example.com"
|
||||
port = String.to_integer(System.get_env("PORT") || "4000")
|
||||
host = System.get_env("SSO_BSN_HOST") || raise "SSO_BSN_HOST must be set to the external host of the service"
|
||||
|
||||
config :wax_, origin: "https://#{host}/"
|
||||
config :boruta, Boruta.Oauth, issuer: "https://#{host}/"
|
||||
|
||||
config :sso_bsn, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
|
||||
|
||||
config :sso_bsn, :session_domain, System.get_env("SESSION_DOMAIN") # A nil value will allow browser default of no subdomains, current domain
|
||||
|
||||
config :sso_bsn, SsoBsnWeb.Endpoint,
|
||||
url: [host: host, port: 443, scheme: "https"],
|
||||
http: [
|
||||
# Enable IPv6 and bind on all interfaces.
|
||||
# Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
|
||||
# See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html
|
||||
# for details about using IPv6 vs IPv4 and loopback vs public addresses.
|
||||
ip: {0, 0, 0, 0, 0, 0, 0, 0},
|
||||
port: port
|
||||
ip: {:local, System.get_env("BIND_UNIX")},
|
||||
port: 0
|
||||
],
|
||||
secret_key_base: secret_key_base
|
||||
|
||||
|
||||
@@ -14,8 +14,9 @@ mixRelease rec {
|
||||
mixFodDeps = fetchMixDeps {
|
||||
pname = "mix-deps-${pname}";
|
||||
inherit version src;
|
||||
sha256 = "sha256-hQlMy0e1Kv2zBXYCiNHYlIO0N00wuIW8B+ZlsEMTSy0=";
|
||||
sha256 = "sha256-p74p7Dpi1xzddD+dygKF5cSLDATNKRXziKPNQgIhRPc=";
|
||||
};
|
||||
|
||||
ELIXIR_MAKE_CACHE_DIR = "/tmp/.elixir-make-cache";
|
||||
meta.mainProgram = "sso_bsn";
|
||||
}
|
||||
|
||||
85
flake.nix
85
flake.nix
@@ -23,5 +23,90 @@
|
||||
inherit self;
|
||||
};
|
||||
});
|
||||
|
||||
nixosModules = {
|
||||
default = { lib, pkgs, config, ... }: let
|
||||
sso-bsn = self.packages.${pkgs.system}.default;
|
||||
gen-secret = pkgs.writeShellScript "gen-secret" ''
|
||||
mkdir -p $1
|
||||
(umask 077; [ -f $1/$2 ] || ${pkgs.coreutils}/bin/head -c 128 /dev/urandom | ${pkgs.coreutils}/bin/base64 -w0 > $1/$2)
|
||||
'';
|
||||
secret = var: dir: file: ''
|
||||
${gen-secret} "${dir}" "${file}"
|
||||
${var}=$(${pkgs.coreutils}/bin/cat "${dir}/${file}")
|
||||
'';
|
||||
script = pkgs.writeShellScriptBin "sso-bsn" ''
|
||||
${secret "RELEASE_COOKIE" "/run/sso-bsn" "cookie"} ${lib.getExe sso-bsn} "$@"
|
||||
'';
|
||||
cfg = config.services.bluepython508.sso-bsn;
|
||||
in {
|
||||
options.services.bluepython508.sso-bsn = {
|
||||
enable = lib.mkEnableOption "sso-bsn";
|
||||
host = lib.mkOption { type = lib.types.str; };
|
||||
session-domain = lib.mkOption { type = with lib.types; nullOr str; };
|
||||
};
|
||||
options.services.nginx.virtualHosts = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: {
|
||||
options.sso.enable = lib.mkEnableOption "SSO BSN";
|
||||
config.extraConfig = lib.mkIf config.sso.enable ''
|
||||
auth_request /__auth_sso_validate;
|
||||
proxy_set_header X-Auth-Username $auth_resp_username;
|
||||
|
||||
location = /__auth_sso_validate {
|
||||
internal;
|
||||
proxy_pass https://${cfg.host}/whoami;
|
||||
proxy_pass_request_body off; # no need to send the POST body
|
||||
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
auth_request_set $auth_resp_username $upstream_http_x_auth_username;
|
||||
}
|
||||
|
||||
error_page 401 = @error401;
|
||||
|
||||
location @error401 {
|
||||
return 302 url=https://${cfg.host}/user/log_in?next=$http_host$request_uri;
|
||||
}
|
||||
'';
|
||||
}));
|
||||
};
|
||||
config.environment.systemPackages = lib.mkIf cfg.enable [ script ];
|
||||
config.systemd.services.sso-bsn = lib.mkIf cfg.enable {
|
||||
description = "sso-bsn";
|
||||
environment = {
|
||||
SERVER = "true";
|
||||
DATABASE_PATH = "/var/lib/sso-bsn/db.sqlite";
|
||||
BIND_UNIX = "/run/sso-bsn/sock";
|
||||
SSO_BSN_HOST = cfg.host;
|
||||
SESSION_DOMAIN = cfg.session-domain;
|
||||
};
|
||||
script = ''
|
||||
${secret "SECRET_KEY_BASE" "/var/lib/sso-bsn" "secret-key-base"}
|
||||
SECRET_KEY_BASE="$SECRET_KEY_BASE" ${lib.getExe script} start
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
ProtectHome = true;
|
||||
PrivateUsers = true;
|
||||
StateDirectory = "sso-bsn";
|
||||
};
|
||||
};
|
||||
config.services.nginx.virtualHosts = lib.mkIf cfg.enable {
|
||||
${cfg.host} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://unix:/run/sso-bsn/sock:/";
|
||||
recommendedProxySettings = true;
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,12 +24,17 @@ defmodule SsoBsnWeb.UserSessionController do
|
||||
end
|
||||
|
||||
def check_auth(conn, _params) do
|
||||
user = conn.assigns[:current_user]
|
||||
if user = conn.assigns[:current_user] do
|
||||
conn
|
||||
|> put_resp_header("X-Auth-Username", user.username)
|
||||
|> json(%{
|
||||
username: user.username
|
||||
})
|
||||
else
|
||||
conn
|
||||
|> put_status(:unauthorized)
|
||||
|> text("Unauthorized")
|
||||
end
|
||||
end
|
||||
|
||||
def redirect_next(conn, %{ "next" => next }) do
|
||||
|
||||
@@ -75,7 +75,7 @@ defmodule SsoBsnWeb.Router do
|
||||
end
|
||||
|
||||
scope "/", SsoBsnWeb do
|
||||
pipe_through [:api, :fetch_session, :fetch_current_user, :require_authenticated_user]
|
||||
pipe_through [:api, :fetch_session, :fetch_current_user]
|
||||
|
||||
get "/whoami", UserSessionController, :check_auth
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user