Реєстрація і авторизація (частина 2)
   
   створимо /web/views/session_view.ex
   
   defmodule Blog.SessionView do
  use Blog.Web, :view
  use Blog.Web, :controller
  
end
   тут 
   
use Blog.Web, :controller
   означає що десь в шаблоні ми хочемо викликати функцію з контроллера (конкретно тут, здається, воно зайве,, крім того - є інший, напевно кращий спосіб це зробити -- прописати модуль-функції у модулі \web\web.ex)
   
   створимо Session модуль (web/models/session.ex)
   
   
defmodule Blog.Session do
  #use Blog.Web, :model
  alias Blog.User
  def login(params, repo) do
    user = repo.get_by(User, email: String.downcase(params["email"]))
    case authenticate(user, params["password"]) do
      true -> {:ok, user}
      _    -> :error
    end
  end
  defp authenticate(user, password) do
    case user do
      nil -> false
      _   -> Comeonin.Bcrypt.checkpw(password, user.crypted_password)
    end
  end
  
  def current_user(conn) do
    id = Plug.Conn.get_session(conn, :uid)
    if id, do: Blog.Repo.get(User, id)
  end
  
  #def logged_in?(conn), do: !!current_user(conn)
  def logged_in?(session_user) do
    case session_user do
      nil -> false
      _   -> true
    end
  end
  
end
   
   зробимо функції з контроллера доступними у view
   для цього допишемо у \web\web.ex в функцію view наступне
   
import Blog.Session, only: [current_user: 1, logged_in?: 1]
   
   тепер ми можемо дописати провірку у шаблоні \web\template\layout\app.html.eex --
   на предмет того, залогінений користувач чи ні, показувати йому посилання на реєстрацію чи на вихід
   
   зверху пропишемо 
   
<% sess_user = current_user(@conn) %>
   і нижче власне саму перевірку
   
<%= if logged_in?(sess_user) do %>
     <span><%= sess_user.email %></span>
     <span><%= link "Logout", to: session_path(@conn, :delete), method: :delete %></span>
    <% else %>
     <span><%= link "Login",    to: "/login" %></span>
     <span><%= link "Register", to: registration_path(@conn, :new) %></span>
    <% end %>
   
   щоб передати дані нижче по шаблону - пропишемо
   
<%= render @view_module, @view_template, Map.put(assigns, :sess_user, sess_user) %>
   
   
   зміни до написаного раніше --
   написання постів -
   додав перевірку(пост може видаляти, писати, редагувати лише адмін)
   
   для того щоб працювала така переадресація-заглушка
   
put_status(conn, 403)
   |> render(Blog.ErrorView, "403.html", %{})
   потрібно додати функцію в модуль \web\views\error_view.ex
   
def render("403.html", _assigns) do
    "Access forbidden"
  end
   
   
   загалом код для функціоналу цих змін ми уже написали, а про таблицю бд - забули
   
   
   додамо новий стовпчик у таблицю users
   для цього згенеруємо міграцію
   
$ mix ecto.gen.migration add_fields_to_users
   
   знайдемо де вона згенерувалася і відредагуємо
   (\blog\priv\repo\migrations\xxxxxxxxx_add_fields_to_users.exs)
   
   
defmodule Blog.Repo.Migrations.AddFieldsToUsers do
  use Ecto.Migration
  def change do
    alter table(:users) do
      add :type, :smallint, null: false, default: 1
    end
  end
  
end
  
  застосуємо зміни
  
  
  у результаті у нас зявиться ще один стовпчик -- отакий получиться дамп якщо зробимо його зараз
  
DROP TABLE "public"."users";
CREATE TABLE "public"."users" (
"id" int4 DEFAULT nextval('users_id_seq'::regclass) NOT NULL,
"email" varchar(255),
"crypted_password" varchar(255),
"inserted_at" timestamp(6) NOT NULL,
"updated_at" timestamp(6) NOT NULL,
"type" int2 DEFAULT 1 NOT NULL
)
WITH (OIDS=FALSE);
  
  для тесту додамо ще один стовпчик
  
  
$ mix ecto.gen.migration add_test_to_users
   
   
defmodule Blog.Repo.Migrations.AddTestToUsers do
  use Ecto.Migration
  def change do
    alter table(:users) do
      add :test, :bigint, default: 1
    end
  end
  
end
   
   застосуємо зміни
  
  
  у результаті у нас зявиться ще один стовпчик -- отакий получиться дамп якщо зробимо його зараз
  
  
DROP TABLE "public"."users";
CREATE TABLE "public"."users" (
"id" int4 DEFAULT nextval('users_id_seq'::regclass) NOT NULL,
"email" varchar(255),
"crypted_password" varchar(255),
"inserted_at" timestamp(6) NOT NULL,
"updated_at" timestamp(6) NOT NULL,
"type" int2 DEFAULT 1 NOT NULL,
"test" int8 DEFAULT 1
)
WITH (OIDS=FALSE);
   
   тепер видалимо цей тестовий стовпчик
   
   
$ mix ecto.gen.migration del_test_to_users
   
   
defmodule Blog.Repo.Migrations.DelTestToUsers do
  use Ecto.Migration
  def change do
    alter table(:users) do
      remove :test
    end
  end
  
end
   
   застосуємо зміни
  
  
   очікуваний результат
   
DROP TABLE "public"."users";
CREATE TABLE "public"."users" (
"id" int4 DEFAULT nextval('users_id_seq'::regclass) NOT NULL,
"email" varchar(255),
"crypted_password" varchar(255),
"inserted_at" timestamp(6) NOT NULL,
"updated_at" timestamp(6) NOT NULL,
"type" int2 DEFAULT 1 NOT NULL
)
WITH (OIDS=FALSE);
   
   зробимо користувача з id 1 адміном
   
    
$ mix ecto.gen.migration make_adm
   
   
defmodule Blog.Repo.Migrations.MakeAdm do
  use Ecto.Migration
  def change do
    #Blog.Repo.update_all("users", set: [type: 1])
    
    %Blog.User{id: 1}
     |> Ecto.Changeset.change(type: 9)
     |> Blog.Repo.update
    
  end
  
end
  
  застосуємо зміни
  
  
  ще трошки про зміни написано раніше --
  у роутері (\web\router.ex) було вирішено зробити такі зміни
  
#resources "/posts", PostController do
  #  post "/comment", PostController, :add_comment
  #end
  
  resources "/posts", PostController
  post "/posts/:post_id/comment", PostController, :add_comment
  щоб позбутися "неапетитного" шляху post_post_path (його ви можете побачити у web\templates\post\show.html.eex) та для більшої прозорості
  
  такс, наче нічого важливо не забув,
  а решту дрібних зміни ви можете подивитись на гітхабі 
  
  загалом отакий комміт получився -- https://github.com/221V/mini-blog/commi … b170189dc9
  
  за матеріалами -
   http://nithinbekal.com/posts/phoenix-authentication/
   http://meatherly.github.io/2015/05/11/p … ntication/
   http://www.phoenixframework.org/docs/
   https://hexdocs.pm/phoenix/Phoenix.html
   https://hexdocs.pm/ecto/Ecto.html
   https://hexdocs.pm/phoenix_html/Phoenix.HTML.html
   та з допомогою Neb0 -
   http://www.cyberforum.ru/blogs/12078/
  
   Дякую за увагу 
   
   далі буде... (напевно наступне - оцінка постів, лайки комментів, рейтинги якісь [роздуми у спостеріганні структури пікабу,хабра,анекдот.ру,різних блогів,...] )
(+ поправлю ще реєстрацію і написання коментарі -- а то зараз просто база для спамера получається 
)