mirror of
https://github.com/mirego/accent.git
synced 2024-09-11 10:55:28 +03:00
Fix slack and gitlab login
This commit is contained in:
parent
d04e302e74
commit
69b6d1cf0f
@ -1,10 +1,7 @@
|
||||
import * as path from 'path';
|
||||
|
||||
// Types
|
||||
import {DocumentPath} from '../types/document-path';
|
||||
import {Project} from '../types/project';
|
||||
import Document from './document';
|
||||
import {DocumentConfig} from '../types/document-config';
|
||||
import {fetchFromRevisions} from './revision-slug-fetcher';
|
||||
|
||||
export default class DocumentPathsFetcher {
|
||||
|
@ -10,7 +10,7 @@ export default class DocumentExportFormatter extends Base {
|
||||
chalk.green('↓'),
|
||||
chalk.bold.white(path),
|
||||
chalk.gray.dim(documentPath),
|
||||
chalk.gray.dim(`→ ${language}`),
|
||||
chalk.gray.dim(`→ ${language}`)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,10 @@ providers =
|
||||
|
||||
providers =
|
||||
if get_env("SLACK_CLIENT_ID"),
|
||||
do: [{:slack, {Ueberauth.Strategy.Slack, [team: get_env("SLACK_TEAM_ID")]}} | providers],
|
||||
do: [
|
||||
{:slack, {Ueberauth.Strategy.Slack, [default_user_scope: "users:read", team: get_env("SLACK_TEAM_ID")]}}
|
||||
| providers
|
||||
],
|
||||
else: providers
|
||||
|
||||
providers =
|
||||
@ -74,7 +77,9 @@ providers =
|
||||
else: providers
|
||||
|
||||
providers =
|
||||
if get_env("MICROSOFT_CLIENT_ID"), do: [{:microsoft, {Ueberauth.Strategy.Microsoft, []}} | providers], else: providers
|
||||
if get_env("MICROSOFT_CLIENT_ID"),
|
||||
do: [{:microsoft, {Ueberauth.Strategy.Microsoft, [prompt: "select_account"]}} | providers],
|
||||
else: providers
|
||||
|
||||
providers = if get_env("AUTH0_CLIENT_ID"), do: [{:auth0, {Ueberauth.Strategy.Auth0, []}} | providers], else: providers
|
||||
|
||||
|
@ -25,7 +25,7 @@ defmodule Accent.UserRemote.Authenticator do
|
||||
defp map_user(info, provider) do
|
||||
%User{
|
||||
provider: to_string(provider),
|
||||
fullname: info.name,
|
||||
fullname: normalize_name(info.name),
|
||||
picture_url: normalize_picture_url(info.image, provider),
|
||||
email: normalize_email(info.email),
|
||||
uid: normalize_email(info.email)
|
||||
@ -35,6 +35,12 @@ defmodule Accent.UserRemote.Authenticator do
|
||||
defp normalize_picture_url("https://lh3.googleusercontent.com/a/default-user" <> _, :google), do: nil
|
||||
defp normalize_picture_url(url, _provider), do: url
|
||||
|
||||
defp normalize_name(nil), do: nil
|
||||
|
||||
defp normalize_name(name) do
|
||||
String.trim(name)
|
||||
end
|
||||
|
||||
defp normalize_email(email) do
|
||||
String.downcase(email)
|
||||
end
|
||||
|
@ -29,6 +29,7 @@ defmodule Accent.Endpoint do
|
||||
plug(Phoenix.CodeReloader)
|
||||
end
|
||||
|
||||
plug(Plug.Session, store: :cookie, key: "accent", signing_salt: "accent-signing-salt-used-for-callback-auth")
|
||||
plug(Plug.RequestId)
|
||||
plug(Plug.Logger)
|
||||
|
||||
|
@ -2,8 +2,13 @@ defmodule Accent.AuthController do
|
||||
use Phoenix.Controller
|
||||
|
||||
alias Accent.UserRemote.Authenticator
|
||||
alias Ueberauth.Strategy.Helpers
|
||||
|
||||
plug :ueberauth
|
||||
plug(Ueberauth, base_path: "/auth")
|
||||
|
||||
def request(conn, _params) do
|
||||
render(conn, "request.html", callback_url: Helpers.callback_url(conn))
|
||||
end
|
||||
|
||||
def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _) do
|
||||
case Authenticator.authenticate(auth) do
|
||||
@ -18,8 +23,4 @@ defmodule Accent.AuthController do
|
||||
def callback(conn, _) do
|
||||
redirect(conn, to: "/")
|
||||
end
|
||||
|
||||
def ueberauth(conn, _) do
|
||||
Ueberauth.call(conn, Ueberauth.init())
|
||||
end
|
||||
end
|
||||
|
@ -30,6 +30,8 @@ defmodule Accent.Router do
|
||||
|
||||
pipeline :browser do
|
||||
plug :accepts, ~w(json html)
|
||||
plug :fetch_session
|
||||
plug(:protect_from_forgery)
|
||||
plug :put_secure_browser_headers, %{"x-frame-options" => ""}
|
||||
end
|
||||
|
||||
|
10
mix.exs
10
mix.exs
@ -78,15 +78,13 @@ defmodule Accent.Mixfile do
|
||||
{:xml_builder, "~> 2.0"},
|
||||
|
||||
# Auth
|
||||
{:oauth2, "~> 2.0", override: true},
|
||||
{:ueberauth, "~> 0.6.0"},
|
||||
{:ueberauth, "~> 0.10"},
|
||||
{:oauth2, "~> 2.0"},
|
||||
{:ueberauth_microsoft, "~> 0.21"},
|
||||
{:ueberauth_google, "~> 0.6"},
|
||||
{:ueberauth_github, "~> 0.7"},
|
||||
{:ueberauth_gitlab_strategy, "~> 0.3"},
|
||||
{:ueberauth_slack, github: "ueberauth/ueberauth_slack", ref: "525594c870f959ab"},
|
||||
{:ueberauth_discord, "~> 0.5"},
|
||||
{:ueberauth_microsoft, "~> 0.7"},
|
||||
{:ueberauth_auth0, "~> 0.8"},
|
||||
{:ueberauth_auth0, "~> 2.0"},
|
||||
|
||||
# Errors
|
||||
{:sentry, "~> 7.0"},
|
||||
|
20
mix.lock
20
mix.lock
@ -23,14 +23,14 @@
|
||||
"dataloader": {:hex, :dataloader, "2.0.0", "49b42d60b9bb06d761a71d7b034c4b34787957e713d4fae15387a25fcd639112", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:opentelemetry_process_propagator, "~> 0.2.1", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "09d61781b76ce216e395cdbc883ff00d00f46a503e215c22722dba82507dfef0"},
|
||||
"db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.4.0", "6b698401c16de79e8596b73dca63762255e70e4bbe26423530e173917220d5fc", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "c7ecaa1da27debae488ab09d9827ec58a0161c7821972b6d2cb26c1614648849"},
|
||||
"ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"},
|
||||
"ecto_dev_logger": {:hex, :ecto_dev_logger, "0.9.0", "cb631469ac1940e97655d6fce85905b792ac9250ab18b19c664978b79f8dad59", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2e8bc98b4ae4fcc7108896eef7da5a109afad829f4fb2eb46d677fdc9101c2d5"},
|
||||
"ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.13", "9947637f82b92dcec93d44ad09ba24d1990bd7ca69e1c68981fb3b6f8bd18829", [:mix], [{:ecto_sql, "~> 3.7", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "0f2288e6163f6aacd7e59545a56adc8df7d2079d18be7d3d6159d10f4dffc396"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.10.2", "6b98b46534b5c2f8b8b5f03f126e75e2a73c64f3c071149d32987a5378b0fdbd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "68c018debca57cb9235e3889affdaec7a10616a4e3a80c99fa1d01fdafaa9007"},
|
||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||
"erlsom": {:hex, :erlsom, "1.5.1", "c8fe2babd33ff0846403f6522328b8ab676f896b793634cfe7ef181c05316c03", [:rebar3], [], "hexpm", "7965485494c5844dd127656ac40f141aadfa174839ec1be1074e7edf5b4239eb"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.17.0", "279f124dba347903bb654bc40745c493ae265d45040001b4899ea1edf88078c7", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "08b638d114387a888f9cb8d65f2a0021ec04c3e447b793efa7c1e734aba93004"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.17.1", "83fa7906ef23aa7fc8ad7ee469c357a63b1b3d55dd701ff5b9ce1f72442b2874", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95bc6fda953e84c60f14da4a198880336205464e75383ec0f570180567985ae0"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "1.2.0", "9cfc75c72a8821588b9b9fe947ae5ab2aed95a052b81237e0928633a13276fd3", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "5ee0375680bca8f20c4d85f58c2894441443a743355430ff33a783fe03296779"},
|
||||
"gettext": {:hex, :gettext, "0.20.0", "75ad71de05f2ef56991dbae224d35c68b098dd0e26918def5bb45591d5c8d429", [:mix], [], "hexpm", "1c03b177435e93a47441d7f681a7040bd2a816ece9e2666d1c9001035121eb3d"},
|
||||
@ -86,14 +86,14 @@
|
||||
"tesla": {:hex, :tesla, "1.7.0", "a62dda2f80d4f8a925eb7b8c5b78c461e0eb996672719fe1a63b26321a5f8b4e", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "2e64f01ebfdb026209b47bc651a0e65203fcff4ae79c11efb73c4852b00dc313"},
|
||||
"timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"},
|
||||
"tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"},
|
||||
"ueberauth_auth0": {:hex, :ueberauth_auth0, "0.8.1", "75a116461963be163fce755904b7ad2b84d8acfd799410f3ef7713e06d048594", [:mix], [{:oauth2, "~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "cb98340a5849b102f0eb02ddd68ba5af83bc6efe3a2fd068ce6e299a1c17f7f0"},
|
||||
"ueberauth_discord": {:hex, :ueberauth_discord, "0.6.0", "d6ec040e4195c4138b9a959c79024ab4c213ba1aed9fc08099ecff141a6486da", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6.3", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "c5ea960191c1d6c3a974947cae4d57efa565a9a0796b8e82bee45fac7ae2fabc"},
|
||||
"ueberauth_github": {:hex, :ueberauth_github, "0.8.0", "2216c8cdacee0de6245b422fb397921b64a29416526985304e345dab6a799d17", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "b65ccc001a7b0719ba069452f3333d68891f4613ae787a340cce31e2a43307a3"},
|
||||
"ueberauth_gitlab_strategy": {:hex, :ueberauth_gitlab_strategy, "0.3.1", "9598ba4cdb1d059b13e8d6603dbd903b7965b059f31bc43c91d727277365cd39", [:mix], [{:oauth2, "~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.4", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "15f65b46b922e760e21af30fbe4e0c22c86d045ad0c636c067c2852358d0d9cd"},
|
||||
"ueberauth_google": {:hex, :ueberauth_google, "0.10.0", "ae00e7228207be977d5cdd0a562e39961851cea74f513aab6446cb51468f283c", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6.3", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "148e2575fd24a29b8bcaa44f9d3d1a38550a74ceed645f5059d4516b93992650"},
|
||||
"ueberauth_microsoft": {:hex, :ueberauth_microsoft, "0.12.0", "c0df56d0ac77d765212ed0e33581524cc4e5cf1b63fa70d2193fcf0b72e133f3", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "405717f65211484f7bbd0521a1990b8a7169b417db7bcb9a1cdb8ecab7d1934d"},
|
||||
"ueberauth_slack": {:git, "https://github.com/ueberauth/ueberauth_slack.git", "525594c870f959aba67acc759d5c1a588ee75e9e", [ref: "525594c870f959ab"]},
|
||||
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},
|
||||
"ueberauth_auth0": {:hex, :ueberauth_auth0, "2.1.0", "0632d5844049fa2f26823f15e1120aa32f27df6f27ce515a4b04641736594bf4", [:mix], [{:oauth2, "~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "8d3b30fa27c95c9e82c30c4afb016251405706d2e9627e603c3c9787fd1314fc"},
|
||||
"ueberauth_discord": {:hex, :ueberauth_discord, "0.7.0", "463f6dfe1ed10a76739331ce8e1dd3600ab611f10524dd828eb3aa50e76e9d43", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "d6f98ef91abb4ddceada4b7acba470e0e68c4d2de9735ff2f24172a8e19896b4"},
|
||||
"ueberauth_github": {:hex, :ueberauth_github, "0.8.3", "1c478629b4c1dae446c68834b69194ad5cead3b6c67c913db6fdf64f37f0328f", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "ae0ab2879c32cfa51d7287a48219b262bfdab0b7ec6629f24160564247493cc6"},
|
||||
"ueberauth_gitlab_strategy": {:hex, :ueberauth_gitlab_strategy, "0.4.0", "96605d304ebb87ce508eccbeb1f94da9ea1c9da20d8913771b6cf24a6cc6c633", [:mix], [{:oauth2, "~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "e86e2e794bb063c07c05a6b1301b73f2be3ba9308d8f47ecc4d510ef9226091e"},
|
||||
"ueberauth_google": {:hex, :ueberauth_google, "0.10.3", "eb1d3973578105e884861facff641e6c03209d621532f988d071dd6d7a46f73b", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.10.0", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "2462ca9652acc936e0738691869d024e3e262f83ba9f6b4e874b961812290038"},
|
||||
"ueberauth_microsoft": {:hex, :ueberauth_microsoft, "0.21.0", "a86eedaf3e3d3535f4b9cf3196099e543cce29b3cd6dedd6f77f84dba1e948b7", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "52880ac872f4d60bcf5a0c3866373e06b1df4d386b1637e81e4fff06e868124d"},
|
||||
"ueberauth_slack": {:hex, :ueberauth_slack, "0.7.0", "91dfd089371a6c5a21a505b3e3e140cced95d4cdc7b73afb5337bcf5f3c91a00", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:oauth2, "~> 1.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "5cba654352596f74a9e2547a19a3aab56634f2a0b928e93cd659ac7d05bf790e"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"vega_lite": {:hex, :vega_lite, "0.1.8", "7f6119126ecaf4bc2c1854084370d7091424f5cce4795fbac044eee9963f0752", [:mix], [{:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "6c8a9271f850612dd8a90de8d1ebd433590ed07ffef76fc2397c240dc04d3fdc"},
|
||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||
|
231
vendor/ueberauth_gitlab_strategy/lib/ueberauth/strategy/gitlab.ex
vendored
Normal file
231
vendor/ueberauth_gitlab_strategy/lib/ueberauth/strategy/gitlab.ex
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
defmodule Ueberauth.Strategy.Gitlab do
|
||||
@moduledoc """
|
||||
Provides an Ueberauth strategy for authenticating with Gitlab.
|
||||
|
||||
### Setup
|
||||
|
||||
Create an application in Gitlab for you to use.
|
||||
|
||||
Register a new application at: [your gitlab developer page](https://gitlab.com/settings/developers) and get the `client_id` and `client_secret`.
|
||||
|
||||
Include the provider in your configuration for Ueberauth
|
||||
|
||||
config :ueberauth, Ueberauth,
|
||||
providers: [
|
||||
gitlab: { Ueberauth.Strategy.Gitlab, [] }
|
||||
]
|
||||
|
||||
Then include the configuration for gitlab.
|
||||
|
||||
config :ueberauth, Ueberauth.Strategy.Gitlab.OAuth,
|
||||
client_id: System.get_env("GITLAB_CLIENT_ID"),
|
||||
client_secret: System.get_env("GITLAB_CLIENT_SECRET")
|
||||
|
||||
If you haven't already, create a pipeline and setup routes for your callback handler
|
||||
|
||||
pipeline :auth do
|
||||
Ueberauth.plug "/auth"
|
||||
end
|
||||
|
||||
scope "/auth" do
|
||||
pipe_through [:browser, :auth]
|
||||
|
||||
get "/:provider/callback", AuthController, :callback
|
||||
end
|
||||
|
||||
|
||||
Create an endpoint for the callback where you will handle the `Ueberauth.Auth` struct
|
||||
|
||||
defmodule MyApp.AuthController do
|
||||
use MyApp.Web, :controller
|
||||
|
||||
def callback_phase(%{ assigns: %{ ueberauth_failure: fails } } = conn, _params) do
|
||||
# do things with the failure
|
||||
end
|
||||
|
||||
def callback_phase(%{ assigns: %{ ueberauth_auth: auth } } = conn, params) do
|
||||
# do things with the auth
|
||||
end
|
||||
end
|
||||
|
||||
You can edit the behaviour of the Strategy by including some options when you register your provider.
|
||||
|
||||
To set the `uid_field`
|
||||
|
||||
config :ueberauth, Ueberauth,
|
||||
providers: [
|
||||
gitlab: { Ueberauth.Strategy.Gitlab, [uid_field: :email] }
|
||||
]
|
||||
|
||||
Default is `:id`
|
||||
|
||||
To set the default 'scopes' (permissions):
|
||||
|
||||
config :ueberauth, Ueberauth,
|
||||
providers: [
|
||||
gitlab: { Ueberauth.Strategy.Gitlab, [default_scope: "api read_user read_registry", api_version: "v4"] }
|
||||
]
|
||||
|
||||
Default is "api read_user read_registry"
|
||||
"""
|
||||
use Ueberauth.Strategy,
|
||||
uid_field: :id,
|
||||
default_scope: "api read_user read_registry",
|
||||
send_redirect_uri: true,
|
||||
oauth2_module: Ueberauth.Strategy.Gitlab.OAuth
|
||||
|
||||
alias Ueberauth.Auth.Info
|
||||
alias Ueberauth.Auth.Credentials
|
||||
alias Ueberauth.Auth.Extra
|
||||
|
||||
@doc """
|
||||
Handles the initial redirect to the gitlab authentication page.
|
||||
|
||||
To customize the scope (permissions) that are requested by gitlab include them as part of your url:
|
||||
|
||||
"/auth/gitlab?scope=api read_user read_registry"
|
||||
"""
|
||||
def handle_request!(conn) do
|
||||
opts =
|
||||
[]
|
||||
|> with_scopes(conn)
|
||||
|> with_state_param(conn)
|
||||
|> with_redirect_uri(conn)
|
||||
|
||||
module = option(conn, :oauth2_module)
|
||||
redirect!(conn, apply(module, :authorize_url!, [opts]))
|
||||
end
|
||||
|
||||
@doc """
|
||||
Handles the callback from Gitlab. When there is a failure from Gitlab the failure is included in the
|
||||
`ueberauth_failure` struct. Otherwise the information returned from Gitlab is returned in the `Ueberauth.Auth` struct.
|
||||
"""
|
||||
def handle_callback!(%Plug.Conn{params: %{"code" => code}} = conn) do
|
||||
module = option(conn, :oauth2_module)
|
||||
token = apply(module, :get_token!, [[code: code]])
|
||||
|
||||
if token.access_token == nil do
|
||||
set_errors!(conn, [
|
||||
error(token.other_params["error"], token.other_params["error_description"])
|
||||
])
|
||||
else
|
||||
fetch_user(conn, token)
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def handle_callback!(conn) do
|
||||
set_errors!(conn, [error("missing_code", "No code received")])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Cleans up the private area of the connection used for passing the raw Gitlab response around during the callback.
|
||||
"""
|
||||
def handle_cleanup!(conn) do
|
||||
conn
|
||||
|> put_private(:gitlab_user, nil)
|
||||
|> put_private(:gitlab_token, nil)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Fetches the uid field from the Gitlab response. This defaults to the option `uid_field` which in-turn defaults to `id`
|
||||
"""
|
||||
def uid(conn) do
|
||||
user =
|
||||
conn
|
||||
|> option(:uid_field)
|
||||
|> to_string
|
||||
|
||||
conn.private.gitlab_user[user]
|
||||
end
|
||||
|
||||
@doc """
|
||||
Includes the credentials from the Gitlab response.
|
||||
"""
|
||||
def credentials(conn) do
|
||||
token = conn.private.gitlab_token
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
%Credentials{
|
||||
token: token.access_token,
|
||||
refresh_token: token.refresh_token,
|
||||
expires_at: token.expires_at,
|
||||
token_type: token.token_type,
|
||||
expires: !!token.expires_at,
|
||||
scopes: scopes
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Fetches the fields to populate the info section of the `Ueberauth.Auth` struct.
|
||||
"""
|
||||
def info(conn) do
|
||||
user = conn.private.gitlab_user
|
||||
|
||||
%Info{
|
||||
name: user["name"],
|
||||
nickname: user["username"],
|
||||
email: user["email"],
|
||||
location: user["location"],
|
||||
image: user["avatar_url"],
|
||||
urls: %{
|
||||
web_url: user["web_url"],
|
||||
website_url: user["website_url"]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Stores the raw information (including the token) obtained from the Gitlab callback.
|
||||
"""
|
||||
def extra(conn) do
|
||||
%Extra{
|
||||
raw_info: %{
|
||||
token: conn.private.gitlab_token,
|
||||
user: conn.private.gitlab_user
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp fetch_user(conn, token) do
|
||||
conn = put_private(conn, :gitlab_token, token)
|
||||
api_ver = option(conn, :api_ver) || "v4"
|
||||
|
||||
case Ueberauth.Strategy.Gitlab.OAuth.get(token, "/api/#{api_ver}/user") do
|
||||
{:ok, %OAuth2.Response{status_code: 401, body: _body}} ->
|
||||
set_errors!(conn, [error("token", "unauthorized")])
|
||||
|
||||
{:ok, %OAuth2.Response{status_code: status_code, body: user}}
|
||||
when status_code in 200..399 ->
|
||||
put_private(conn, :gitlab_user, user)
|
||||
|
||||
{:error, %OAuth2.Error{reason: reason}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
|
||||
{:error, %OAuth2.Response{body: %{"message" => reason}}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
|
||||
{:error, _} ->
|
||||
set_errors!(conn, [error("OAuth2", "uknown error")])
|
||||
end
|
||||
end
|
||||
|
||||
defp option(conn, key) do
|
||||
Keyword.get(options(conn) || [], key, Keyword.get(default_options(), key))
|
||||
end
|
||||
|
||||
defp with_scopes(opts, conn) do
|
||||
scopes = conn.params["scope"] || option(conn, :default_scope)
|
||||
|
||||
opts |> Keyword.put(:scope, scopes)
|
||||
end
|
||||
|
||||
defp with_redirect_uri(opts, conn) do
|
||||
if option(conn, :send_redirect_uri) do
|
||||
opts |> Keyword.put(:redirect_uri, callback_url(conn))
|
||||
else
|
||||
opts
|
||||
end
|
||||
end
|
||||
end
|
105
vendor/ueberauth_gitlab_strategy/lib/ueberauth/strategy/gitlab/oauth.ex
vendored
Normal file
105
vendor/ueberauth_gitlab_strategy/lib/ueberauth/strategy/gitlab/oauth.ex
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
defmodule Ueberauth.Strategy.Gitlab.OAuth do
|
||||
@moduledoc """
|
||||
An implementation of OAuth2 for gitlab.
|
||||
|
||||
To add your `client_id` and `client_secret` include these values in your configuration.
|
||||
|
||||
config :ueberauth, Ueberauth.Strategy.Gitlab.OAuth,
|
||||
client_id: System.get_env("GITLAB_CLIENT_ID"),
|
||||
client_secret: System.get_env("GITLAB_CLIENT_SECRET")
|
||||
"""
|
||||
use OAuth2.Strategy
|
||||
|
||||
@defaults [
|
||||
strategy: __MODULE__,
|
||||
site: "https://gitlab.com",
|
||||
authorize_url: "https://gitlab.com/oauth/authorize",
|
||||
token_url: "https://gitlab.com/oauth/token",
|
||||
api_version: "v4",
|
||||
token_method: :post
|
||||
]
|
||||
|
||||
@doc """
|
||||
Construct a client for requests to Gitlab.
|
||||
|
||||
Optionally include any OAuth2 options here to be merged with the defaults.
|
||||
|
||||
Ueberauth.Strategy.Gitlab.OAuth.client(redirect_uri: "http://localhost:4000/auth/gitlab/callback")
|
||||
|
||||
This will be setup automatically for you in `Ueberauth.Strategy.Gitlab`.
|
||||
These options are only useful for usage outside the normal callback phase of Ueberauth.
|
||||
"""
|
||||
def client(opts \\ []) do
|
||||
config =
|
||||
:ueberauth
|
||||
|> Application.fetch_env!(Ueberauth.Strategy.Gitlab.OAuth)
|
||||
|> check_config_key_exists(:client_id)
|
||||
|> check_config_key_exists(:client_secret)
|
||||
|
||||
client_opts =
|
||||
@defaults
|
||||
|> Keyword.merge(config)
|
||||
|> Keyword.merge(opts)
|
||||
|
||||
json_library = Ueberauth.json_library()
|
||||
|
||||
OAuth2.Client.new(client_opts)
|
||||
|> OAuth2.Client.put_serializer("application/json", json_library)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Provides the authorize url for the request phase of Ueberauth. No need to call this usually.
|
||||
"""
|
||||
def authorize_url!(params \\ [], opts \\ []) do
|
||||
opts
|
||||
|> client
|
||||
|> OAuth2.Client.authorize_url!(params)
|
||||
end
|
||||
|
||||
def get(token, url, headers \\ [], opts \\ []) do
|
||||
[token: token]
|
||||
|> client
|
||||
|> put_param("access_token", token)
|
||||
|> OAuth2.Client.get(url, headers, opts)
|
||||
end
|
||||
|
||||
def get_token!(params \\ [], options \\ []) do
|
||||
headers = Keyword.get(options, :headers, [])
|
||||
options = Keyword.get(options, :options, [])
|
||||
client_options = Keyword.get(options, :client_options, [])
|
||||
client = OAuth2.Client.get_token!(client(client_options), params, headers, options)
|
||||
client.token
|
||||
end
|
||||
|
||||
# Strategy Callbacks
|
||||
|
||||
def authorize_url(client, params) do
|
||||
client
|
||||
|> put_param("response_type", "code")
|
||||
|> put_param("redirect_uri", client().redirect_uri)
|
||||
|
||||
OAuth2.Strategy.AuthCode.authorize_url(client, params)
|
||||
end
|
||||
|
||||
def get_token(client, params, headers) do
|
||||
client
|
||||
|> put_param("client_id", client().client_id)
|
||||
|> put_param("client_secret", client().client_secret)
|
||||
|> put_param("grant_type", "authorization_code")
|
||||
|> put_param("redirect_uri", client().redirect_uri)
|
||||
|> put_header("Accept", "application/json")
|
||||
|> OAuth2.Strategy.AuthCode.get_token(params, headers)
|
||||
end
|
||||
|
||||
defp check_config_key_exists(config, key) when is_list(config) do
|
||||
unless Keyword.has_key?(config, key) do
|
||||
raise "#{inspect(key)} missing from config :ueberauth, Ueberauth.Strategy.Gitlab"
|
||||
end
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
defp check_config_key_exists(_, _) do
|
||||
raise "Config :ueberauth, Ueberauth.Strategy.Gitlab is not a keyword list, as expected"
|
||||
end
|
||||
end
|
374
vendor/ueberauth_slack/lib/ueberauth/strategy/slack.ex
vendored
Normal file
374
vendor/ueberauth_slack/lib/ueberauth/strategy/slack.ex
vendored
Normal file
@ -0,0 +1,374 @@
|
||||
defmodule Ueberauth.Strategy.Slack do
|
||||
@moduledoc """
|
||||
Implements an ÜeberauthSlack strategy for authentication with Slack V2 OAuth API.
|
||||
|
||||
When configuring the strategy in the Üeberauth providers, you can specify some defaults.
|
||||
|
||||
* `uid_field` - The field to use as the UID field. This can be any populated field in the info struct. Default `:email`
|
||||
* `default_scope` - The scope to request by default from slack (permissions). Default "users:read"
|
||||
* `default_users_scope` - The scope to request by default from slack (permissions). Default "users:read"
|
||||
* `oauth2_module` - The OAuth2 module to use. Default Ueberauth.Strategy.Slack.OAuth
|
||||
|
||||
```elixir
|
||||
|
||||
config :ueberauth, Ueberauth,
|
||||
providers: [
|
||||
slack: { Ueberauth.Strategy.Slack, [uid_field: :nickname, default_scope: "users:read,users:write"] }
|
||||
]
|
||||
```
|
||||
"""
|
||||
use Ueberauth.Strategy,
|
||||
uid_field: :email,
|
||||
default_scope: "users:read",
|
||||
default_user_scope: "",
|
||||
oauth2_module: Ueberauth.Strategy.Slack.OAuth
|
||||
|
||||
alias Ueberauth.Auth.Info
|
||||
alias Ueberauth.Auth.Credentials
|
||||
alias Ueberauth.Auth.Extra
|
||||
|
||||
# When handling the request just redirect to Slack
|
||||
@doc false
|
||||
def handle_request!(conn) do
|
||||
scopes = conn.params["scope"] || option(conn, :default_scope)
|
||||
user_scopes = conn.params["user_scope"] || option(conn, :default_user_scope)
|
||||
team = option(conn, :team)
|
||||
|
||||
opts = [scope: scopes, user_scope: user_scopes]
|
||||
opts = with_state_param(opts, conn)
|
||||
opts = if team, do: Keyword.put(opts, :team, team), else: opts
|
||||
|
||||
callback_url = callback_url(conn)
|
||||
|
||||
callback_url =
|
||||
if String.ends_with?(callback_url, "?"),
|
||||
do: String.slice(callback_url, 0..-2),
|
||||
else: callback_url
|
||||
|
||||
opts = Keyword.put(opts, :redirect_uri, callback_url)
|
||||
module = option(conn, :oauth2_module)
|
||||
|
||||
redirect!(conn, apply(module, :authorize_url!, [opts]))
|
||||
end
|
||||
|
||||
# When handling the callback, if there was no errors we need to
|
||||
# make two calls. The first, to fetch the slack auth is so that we can get hold of
|
||||
# the user id so we can make a query to fetch the user info.
|
||||
# So that it is available later to build the auth struct, we put it in the private section of the conn.
|
||||
@doc false
|
||||
def handle_callback!(%Plug.Conn{params: %{"code" => code}} = conn) do
|
||||
module = option(conn, :oauth2_module)
|
||||
params = [code: code]
|
||||
redirect_uri = get_redirect_uri(conn)
|
||||
|
||||
options = %{
|
||||
options: [
|
||||
client_options: [redirect_uri: redirect_uri]
|
||||
]
|
||||
}
|
||||
|
||||
case apply(module, :get_token!, [params, options]) do
|
||||
{%{access_token: nil}, %{access_token: nil} = user_token} ->
|
||||
set_errors!(conn, [
|
||||
error(user_token.other_params["error"], user_token.other_params["error_description"])
|
||||
])
|
||||
|
||||
{bot_token, %{access_token: nil}} ->
|
||||
handle_token(conn, bot_token)
|
||||
|> store_bot_token(bot_token)
|
||||
|
||||
{bot_token, user_token} ->
|
||||
handle_token(conn, user_token)
|
||||
|> store_bot_token(bot_token)
|
||||
end
|
||||
end
|
||||
|
||||
# If we don't match code, then we have an issue
|
||||
@doc false
|
||||
def handle_callback!(conn) do
|
||||
set_errors!(conn, [error("missing_code", "No code received")])
|
||||
end
|
||||
|
||||
defp handle_token(conn, token) do
|
||||
conn
|
||||
|> store_token(token)
|
||||
|> fetch_auth(token)
|
||||
|> fetch_identity(token)
|
||||
|> fetch_user(token)
|
||||
|> fetch_team(token)
|
||||
end
|
||||
|
||||
# We store the token for use later when fetching the slack auth and user and constructing the auth struct.
|
||||
@doc false
|
||||
defp store_token(conn, token) do
|
||||
put_private(conn, :slack_token, token)
|
||||
end
|
||||
|
||||
defp store_bot_token(conn, token) do
|
||||
put_private(conn, :slack_bot_token, token)
|
||||
end
|
||||
|
||||
# Remove the temporary storage in the conn for our data. Run after the auth struct has been built.
|
||||
@doc false
|
||||
def handle_cleanup!(conn) do
|
||||
conn
|
||||
|> put_private(:slack_auth, nil)
|
||||
|> put_private(:slack_identity, nil)
|
||||
|> put_private(:slack_user, nil)
|
||||
|> put_private(:slack_token, nil)
|
||||
|> put_private(:slack_bot_token, nil)
|
||||
end
|
||||
|
||||
# The structure of the requests is such that it is difficult to provide cusomization for the uid field.
|
||||
# instead, we allow selecting any field from the info struct
|
||||
@doc false
|
||||
def uid(conn) do
|
||||
Map.get(info(conn), option(conn, :uid_field))
|
||||
end
|
||||
|
||||
@doc false
|
||||
def credentials(conn) do
|
||||
token = conn.private.slack_token
|
||||
bot_token = conn.private.slack_bot_token
|
||||
auth = conn.private[:slack_auth]
|
||||
identity = conn.private[:slack_identity]
|
||||
user = conn.private[:slack_user]
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
%Credentials{
|
||||
token: token.access_token,
|
||||
refresh_token: token.refresh_token,
|
||||
expires_at: token.expires_at,
|
||||
token_type: token.token_type,
|
||||
expires: !!token.expires_at,
|
||||
scopes: scopes,
|
||||
other:
|
||||
Map.merge(
|
||||
%{
|
||||
user: get_in(auth, ["user"]),
|
||||
user_id: get_in(auth, ["user_id"]) || get_in(identity, ["user", "id"]),
|
||||
team: get_in(auth, ["team"]) || get_in(identity, ["team", "name"]),
|
||||
team_id: get_in(auth, ["team_id"]) || get_in(identity, ["team", "id"]),
|
||||
team_domain: get_in(identity, ["team", "domain"]),
|
||||
team_url: get_in(auth, ["url"]),
|
||||
bot_token: bot_token.access_token
|
||||
},
|
||||
user_credentials(user)
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def info(conn) do
|
||||
user = conn.private[:slack_user]
|
||||
auth = conn.private[:slack_auth]
|
||||
identity = conn.private[:slack_identity]
|
||||
|
||||
profile = get_in(user, ["profile"]) || get_in(identity, ["user"]) || %{}
|
||||
|
||||
image_urls =
|
||||
profile
|
||||
|> Map.keys()
|
||||
|> Enum.filter(&(&1 =~ ~r/^image_/))
|
||||
|> Enum.into(%{}, &{&1, profile[&1]})
|
||||
|
||||
team_image_urls =
|
||||
(identity || %{})
|
||||
|> Map.get("team", %{})
|
||||
|> Enum.filter(fn {key, _value} -> key =~ ~r/^image_/ end)
|
||||
|> Enum.into(%{}, fn {key, value} -> {"team_#{key}", value} end)
|
||||
|
||||
%Info{
|
||||
name: name_from_user(user) || get_in(identity, ["user", "name"]),
|
||||
nickname: get_in(user, ["name"]),
|
||||
email: get_in(profile, ["email"]),
|
||||
image: get_in(profile, ["image_48"]),
|
||||
urls:
|
||||
image_urls
|
||||
|> Map.merge(team_image_urls)
|
||||
|> Map.merge(%{
|
||||
team_url: get_in(auth, ["url"])
|
||||
})
|
||||
}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def extra(conn) do
|
||||
%Extra{
|
||||
raw_info: %{
|
||||
auth: conn.private[:slack_auth],
|
||||
identity: conn.private[:slack_identity],
|
||||
token: conn.private[:slack_token],
|
||||
bot_token: conn.private[:slack_bot_token],
|
||||
user: conn.private[:slack_user],
|
||||
team: conn.private[:slack_team]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp user_credentials(nil), do: %{}
|
||||
|
||||
defp user_credentials(user) do
|
||||
%{
|
||||
has_2fa: user["has_2fa"],
|
||||
is_admin: user["is_admin"],
|
||||
is_owner: user["is_owner"],
|
||||
is_primary_owner: user["is_primary_owner"],
|
||||
is_restricted: user["is_restricted"],
|
||||
is_ultra_restricted: user["is_ultra_restricted"]
|
||||
}
|
||||
end
|
||||
|
||||
# Before we can fetch the user, we first need to fetch the auth to find out what the user id is.
|
||||
defp fetch_auth(conn, token) do
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
case Ueberauth.Strategy.Slack.OAuth.get(token, "/auth.test") do
|
||||
{:ok, %OAuth2.Response{status_code: 401, body: _body}} ->
|
||||
set_errors!(conn, [error("token", "unauthorized")])
|
||||
|
||||
{:ok, %OAuth2.Response{status_code: status_code, body: auth}}
|
||||
when status_code in 200..399 ->
|
||||
cond do
|
||||
auth["ok"] ->
|
||||
put_private(conn, :slack_auth, auth)
|
||||
|
||||
auth["error"] == "invalid_auth" && Enum.member?(scopes, "identity.basic") ->
|
||||
# If the token has only the "identity.basic" scope then it may error
|
||||
# at the "auth.test" endpoint but still succeed at the
|
||||
# "identity.basic" endpoint.
|
||||
# In this case we rely on fetch_identity to set the error if the
|
||||
# token is invalid.
|
||||
conn
|
||||
|
||||
true ->
|
||||
set_errors!(conn, [error(auth["error"], auth["error"])])
|
||||
end
|
||||
|
||||
{:error, %OAuth2.Error{reason: reason}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch_identity(conn, token) do
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
case "identity.basic" in scopes do
|
||||
false ->
|
||||
conn
|
||||
|
||||
true ->
|
||||
case Ueberauth.Strategy.Slack.OAuth.get(token, "/users.identity") do
|
||||
{:ok, %OAuth2.Response{status_code: 401, body: _body}} ->
|
||||
set_errors!(conn, [error("token", "unauthorized")])
|
||||
|
||||
{:ok, %OAuth2.Response{status_code: status_code, body: identity}}
|
||||
when status_code in 200..399 ->
|
||||
if identity["ok"] do
|
||||
put_private(conn, :slack_identity, identity)
|
||||
else
|
||||
set_errors!(conn, [error(identity["error"], identity["error"])])
|
||||
end
|
||||
|
||||
{:error, %OAuth2.Error{reason: reason}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# If the call to fetch the auth fails, we're going to have failures already in place.
|
||||
# If this happens don't try and fetch the user and just let it fail.
|
||||
defp fetch_user(%Plug.Conn{assigns: %{ueberauth_failure: _fails}} = conn, _), do: conn
|
||||
|
||||
# Given the auth and token we can now fetch the user.
|
||||
defp fetch_user(conn, token) do
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
case "users:read" in scopes do
|
||||
false ->
|
||||
conn
|
||||
|
||||
true ->
|
||||
auth = conn.private.slack_auth
|
||||
|
||||
case Ueberauth.Strategy.Slack.OAuth.get(token, "/users.info", %{user: auth["user_id"]}) do
|
||||
{:ok, %OAuth2.Response{status_code: 401, body: _body}} ->
|
||||
set_errors!(conn, [error("token", "unauthorized")])
|
||||
|
||||
{:ok, %OAuth2.Response{status_code: status_code, body: user}}
|
||||
when status_code in 200..399 ->
|
||||
if user["ok"] do
|
||||
put_private(conn, :slack_user, user["user"])
|
||||
else
|
||||
set_errors!(conn, [error(user["error"], user["error"])])
|
||||
end
|
||||
|
||||
{:error, %OAuth2.Error{reason: reason}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch_team(%Plug.Conn{assigns: %{ueberauth_failure: _fails}} = conn, _), do: conn
|
||||
|
||||
defp fetch_team(conn, token) do
|
||||
scope_string = token.other_params["scope"] || ""
|
||||
scopes = String.split(scope_string, ",")
|
||||
|
||||
case "team:read" in scopes do
|
||||
false ->
|
||||
conn
|
||||
|
||||
true ->
|
||||
case Ueberauth.Strategy.Slack.OAuth.get(token, "/team.info") do
|
||||
{:ok, %OAuth2.Response{status_code: 401, body: _body}} ->
|
||||
set_errors!(conn, [error("token", "unauthorized")])
|
||||
|
||||
{:ok, %OAuth2.Response{status_code: status_code, body: team}}
|
||||
when status_code in 200..399 ->
|
||||
if team["ok"] do
|
||||
put_private(conn, :slack_team, team["team"])
|
||||
else
|
||||
set_errors!(conn, [error(team["error"], team["error"])])
|
||||
end
|
||||
|
||||
{:error, %OAuth2.Error{reason: reason}} ->
|
||||
set_errors!(conn, [error("OAuth2", reason)])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch the name to use. We try to start with the most specific name avaialble and
|
||||
# fallback to the least.
|
||||
defp name_from_user(nil), do: nil
|
||||
|
||||
defp name_from_user(user) do
|
||||
[
|
||||
user["profile"]["real_name_normalized"],
|
||||
user["profile"]["real_name"],
|
||||
user["real_name"],
|
||||
user["name"]
|
||||
]
|
||||
|> Enum.reject(&(&1 == "" || &1 == nil))
|
||||
|> List.first()
|
||||
end
|
||||
|
||||
defp option(conn, key) do
|
||||
Keyword.get(options(conn), key, Keyword.get(default_options(), key))
|
||||
end
|
||||
|
||||
defp get_redirect_uri(%Plug.Conn{} = conn) do
|
||||
config = Application.get_env(:ueberauth, Ueberauth)
|
||||
redirect_uri = Keyword.get(config, :redirect_uri)
|
||||
|
||||
if is_nil(redirect_uri) do
|
||||
callback_url(conn)
|
||||
else
|
||||
redirect_uri
|
||||
end
|
||||
end
|
||||
end
|
104
vendor/ueberauth_slack/lib/ueberauth/strategy/slack/oauth.ex
vendored
Normal file
104
vendor/ueberauth_slack/lib/ueberauth/strategy/slack/oauth.ex
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
defmodule Ueberauth.Strategy.Slack.OAuth do
|
||||
@moduledoc """
|
||||
An implementation of OAuth2 for Slack OAuth V2 API.
|
||||
To add your `client_id` and `client_secret` include these values in your configuration.
|
||||
config :ueberauth, Ueberauth.Strategy.Slack.OAuth,
|
||||
client_id: System.get_env("SLACK_CLIENT_ID"),
|
||||
client_secret: System.get_env("SLACK_CLIENT_SECRET")
|
||||
The JSON serializer used is the same as `Ueberauth` so if you need to
|
||||
customize it, you can configure it in the `Ueberauth` configuration:
|
||||
config :ueberauth, Ueberauth,
|
||||
json_library: Poison # Defaults to Jason
|
||||
"""
|
||||
use OAuth2.Strategy
|
||||
|
||||
@defaults [
|
||||
strategy: __MODULE__,
|
||||
site: "https://slack.com/api",
|
||||
authorize_url: "https://slack.com/oauth/v2/authorize",
|
||||
token_url: "https://slack.com/api/oauth.v2.access"
|
||||
]
|
||||
|
||||
def client(opts \\ []) do
|
||||
slack_config = Application.get_env(:ueberauth, Ueberauth.Strategy.Slack.OAuth)
|
||||
|
||||
client_opts =
|
||||
@defaults
|
||||
|> Keyword.merge(slack_config)
|
||||
|> Keyword.merge(opts)
|
||||
|
||||
json_library = Ueberauth.json_library()
|
||||
|
||||
client_opts
|
||||
|> OAuth2.Client.new()
|
||||
|> OAuth2.Client.put_serializer("application/json", json_library)
|
||||
end
|
||||
|
||||
def get(token, url, params \\ %{}, headers \\ [], opts \\ []) do
|
||||
url =
|
||||
[token: token]
|
||||
|> client()
|
||||
|> to_url(url, params)
|
||||
|
||||
headers = [{"authorization", "Bearer #{token.access_token}"}] ++ headers
|
||||
OAuth2.Client.get(client(), url, headers, opts)
|
||||
end
|
||||
|
||||
def authorize_url!(params \\ [], opts \\ []) do
|
||||
opts
|
||||
|> client
|
||||
|> OAuth2.Client.authorize_url!(params)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns two tokens from Slack API, a "bot token" and a "user token"
|
||||
"""
|
||||
@spec get_token!(list(), map()) :: {%OAuth2.AccessToken{} | nil, %OAuth2.AccessToken{} | nil}
|
||||
def get_token!(params \\ [], options \\ %{}) do
|
||||
headers = Map.get(options, :headers, [])
|
||||
options = Map.get(options, :options, [])
|
||||
client_options = Keyword.get(options, :client_options, [])
|
||||
|
||||
client = OAuth2.Client.get_token!(client(client_options), params, headers, options)
|
||||
|
||||
split_token(client.token)
|
||||
end
|
||||
|
||||
defp split_token(nil), do: {nil, nil}
|
||||
|
||||
defp split_token(token) do
|
||||
{token, OAuth2.AccessToken.new(token.other_params["authed_user"])}
|
||||
end
|
||||
|
||||
# Strategy Callbacks
|
||||
|
||||
def authorize_url(client, params) do
|
||||
OAuth2.Strategy.AuthCode.authorize_url(client, params)
|
||||
end
|
||||
|
||||
def get_token(client, params, headers) do
|
||||
client
|
||||
|> put_param("client_secret", client.client_secret)
|
||||
|> put_header("Accept", "application/json")
|
||||
|> OAuth2.Strategy.AuthCode.get_token(params, headers)
|
||||
end
|
||||
|
||||
defp endpoint("/" <> _path = endpoint, client), do: client.site <> endpoint
|
||||
defp endpoint(endpoint, _client), do: endpoint
|
||||
|
||||
defp to_url(client, endpoint, params) do
|
||||
client_endpoint =
|
||||
client
|
||||
|> Map.get(endpoint, endpoint)
|
||||
|> endpoint(client)
|
||||
|
||||
final_endpoint =
|
||||
if params do
|
||||
client_endpoint <> "?" <> URI.encode_query(params)
|
||||
else
|
||||
client_endpoint
|
||||
end
|
||||
|
||||
final_endpoint
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user