From b30af0cd09e0f6996b36866376b8ce11e214e879 Mon Sep 17 00:00:00 2001 From: Mitchell Gerber Date: Tue, 16 Jan 2018 21:48:46 -0600 Subject: [PATCH] server - support for admin/mod users --- config/config.secret.exs.template | 11 +++++- lib/myapp/data/thread.ex | 4 +-- lib/myapp/data/user.ex | 34 +++++++++++++++++-- lib/myapp_web/controllers/user_controller.ex | 13 +++++++ lib/myapp_web/router.ex | 1 + .../migrations/20180101200459_create_user.exs | 4 +++ priv/repo/seeds.exs | 15 ++++++++ 7 files changed, 77 insertions(+), 5 deletions(-) diff --git a/config/config.secret.exs.template b/config/config.secret.exs.template index 28b56d3..0a9d139 100644 --- a/config/config.secret.exs.template +++ b/config/config.secret.exs.template @@ -4,4 +4,13 @@ use Mix.Config config :myapp, bnet_client_id: "", bnet_client_secret: "", - bnet_redirect_uri: "" + bnet_redirect_uri: "", + + # admin login credentials for site + admin_accounts: [%{ + "username" => "", + "password" => "", + "character_name" => "", + "character_avatar" => "", + "permissions" => "" + }] diff --git a/lib/myapp/data/thread.ex b/lib/myapp/data/thread.ex index f3d7ef7..8d57628 100644 --- a/lib/myapp/data/thread.ex +++ b/lib/myapp/data/thread.ex @@ -60,8 +60,8 @@ defmodule MyApp.Data.Thread do :title, :view_count, :reply_count, - user: [:id, :battletag, :character_guild, :character_name, :character_class, :character_realm, :character_avatar], - last_reply: [:id, :battletag, :character_guild, :character_name, :character_class, :character_realm, :character_avatar], + user: [:id, :battletag, :character_guild, :character_name, :character_class, :character_realm, :character_avatar, :permissions], + last_reply: [:id, :battletag, :character_guild, :character_name, :character_class, :character_realm, :character_avatar, :permissions], ]), where: [category_id: ^category_id], preload: [:user, :last_reply] diff --git a/lib/myapp/data/user.ex b/lib/myapp/data/user.ex index 0508480..b0bf98e 100644 --- a/lib/myapp/data/user.ex +++ b/lib/myapp/data/user.ex @@ -15,6 +15,10 @@ defmodule MyApp.Data.User do field :character_class, :string field :character_realm, :string field :character_avatar, :string + + # for admin purposes + field :username, :string + field :password, :string timestamps(type: :utc_datetime) end @@ -60,7 +64,7 @@ defmodule MyApp.Data.User do output = cond do is_nil(user) -> - insert_user(params) + insert_battlenet_user(params) true -> if Map.get(user, :battletag) != Map.get(params, "battletag") do update_battletag(user, params) @@ -81,7 +85,7 @@ defmodule MyApp.Data.User do {:ok, Map.merge(user, %{access_token: access_token})} end - defp insert_user(params) do + defp insert_battlenet_user(params) do changeset(%Data.User{}, params) |> Repo.insert |> Data.Util.process_insert_or_update @@ -100,4 +104,30 @@ defmodule MyApp.Data.User do defp filter_values({:error, error}), do: {:error, error} defp filter_values({:ok, user}), do: {:ok, Map.take(user, [:id, :permissions, :battle_net_id, :battletag])} + def insert_admin_user(params) do + params = params + |> Map.put("password", Comeonin.Argon2.hashpwsalt(Map.get(params, "password"))) + + %Data.User{} + |> cast(params, [:username, :password, :permissions, :character_name, :character_avatar]) + |> Repo.insert + end + + def login(params) do + user = Repo.get_by(Data.User, username: Map.get(params, "username")) + + if user do + case Comeonin.Argon2.checkpw(Map.get(params, "password"), user.password) do + false -> {:error, "invalid login"} + _ -> + user = user + |> Map.from_struct + |> Map.drop([:password, :__meta__]) + {:ok, user} + end + else + {:error, "invalid login"} + end + end + end diff --git a/lib/myapp_web/controllers/user_controller.ex b/lib/myapp_web/controllers/user_controller.ex index c5d11ce..68ef267 100644 --- a/lib/myapp_web/controllers/user_controller.ex +++ b/lib/myapp_web/controllers/user_controller.ex @@ -7,6 +7,19 @@ defmodule MyAppWeb.UserController do # https://us.battle.net/oauth/authorize?redirect_uri=https://localhost/api/battlenet/authorize&scope=wow.profile&client_id=vxqv32fddxsy6cmk6259amtymbuzmfrq&response_type=code + # this is for auth with username/password - currently only for admin + def login(conn, params) do + {output, status} = params + |> Data.User.login + |> Auth.Token.add_token_and_map_claims + |> Response.put_resp + + conn + |> put_status(status) + |> Response.json(output) + end + + # this is for authorization with battlenet @spec authorize(map, map) :: any def authorize(conn, %{"code" => code}) when not is_nil(code) do diff --git a/lib/myapp_web/router.ex b/lib/myapp_web/router.ex index dfad1f6..a964c70 100644 --- a/lib/myapp_web/router.ex +++ b/lib/myapp_web/router.ex @@ -24,6 +24,7 @@ defmodule MyAppWeb.Router do scope "/user" do post "/authorize", UserController, :authorize + post "/login", UserController, :login pipe_through [:user_auth] get "/characters", UserController, :characters diff --git a/priv/repo/migrations/20180101200459_create_user.exs b/priv/repo/migrations/20180101200459_create_user.exs index f11fa48..9f9da95 100644 --- a/priv/repo/migrations/20180101200459_create_user.exs +++ b/priv/repo/migrations/20180101200459_create_user.exs @@ -11,6 +11,10 @@ defmodule MyApp.Repo.Migrations.CreateUser do add :character_class, :string add :character_realm, :string add :character_avatar, :string + + # for admin purposes + add :username, :string + add :password, :string timestamps() end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 5987d8b..0c8fa58 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -194,3 +194,18 @@ Enum.each(Category.get_seed(), fn(cat) -> end end) end) + +# insert admin user +accounts = Application.get_env(:myapp, :admin_accounts) + +Enum.each(accounts, fn (user) -> + Repo.transaction(fn -> + exists = Repo.get_by(Data.User, %{username: Map.get(user, "username")}) != nil + + if !exists do + MyApp.Data.User.insert_admin_user(user) + end + + end) +end) +