summaryrefslogtreecommitdiff
path: root/test/elixir/lib/step/user.ex
blob: 49ef0feae54309de9f07524639ee41788e99219f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
defmodule Couch.Test.Setup.Step.User do
  @moduledoc """
  Step to create user with given list of roles.
  The :server_admin is a special role which is used to put user
  into `admins` section of a config instead of a database.

  Example
    setup
      |> Setup.Step.User.new(:admin, roles: [:server_admin])
    ...
      |> Setup.run
    ...

    user = setup |> Setup.get(:admin) |> Step.User.name()
  """

  alias Couch.Test.Setup
  alias Couch.Test.Utils

  import ExUnit.Callbacks, only: [on_exit: 1]

  defstruct [:roles, :name, :password, :users_db]

  import ExUnit.Assertions, only: [assert: 1, assert: 2]

  import Utils

  @admin {:user_ctx, user_ctx(roles: ["_admin"])}

  def new(setup, id, roles: roles) do
    setup |> Setup.step(id, %__MODULE__{roles: roles || []})
  end

  def setup(_setup, %__MODULE__{roles: roles} = step) do
    users_db = IO.chardata_to_string(
      :config.get('chttpd_auth', 'authentication_db', '_users'))
    if not Utils.db_exists?(users_db) do
      on_exit fn ->
        :fabric.delete_db(users_db, [@admin])
      end
      res = :fabric.create_db(users_db, [@admin])
      assert res in [:ok, :accepted], "Cannot create `users` database #{users_db}"
    end

    if :server_admin in roles do
      name = Utils.random_name("admin")
      pass = Utils.random_password()
      :config.set(
        'admins', String.to_charlist(name), String.to_charlist(pass), false)
      %{step |
        name: name,
        password: pass,
        users_db: users_db
      }
    else
      name = Utils.random_name("admin")
      pass = Utils.random_password()
      doc_id = "org.couchdb.user:#{name}"
      user_doc = :couch_doc.from_json_obj(%{
        _id: doc_id,
        name: name,
        type: "user",
        roles: roles,
        password: pass
      })
      res = :fabric.update_doc(users_db, user_doc, [@admin])
      assert res in [:ok, :accepted], "Cannot create user document"
      %{step |
        name: name,
        password: pass,
        users_db: users_db,
        roles: roles
      }
    end
  end

  def teardown(_setup, %__MODULE__{name: name, users_db: users_db, roles: roles} = _step) do
    if :server_admin in roles do
      :config.delete("admins", String.to_charlist(name), false)
    else
      doc_id = "org.couchdb.user:#{name}"
      assert {:ok, doc_info(revs: [rev | _])} = :fabric.get_doc_info(users_db, doc_id, [])
      doc = :couch_doc.from_json_obj(%{
        _id: doc_id,
        _rev: rev,
        _deleted: true
      })
      assert {:ok, _resp} = :fabric.update_doc(users_db, doc, [@admin])
    end
    :ok
  end

  def name(%__MODULE__{name: name}) do
    name
  end
  def password(%__MODULE__{password: pass}) do
    pass
  end
  def credentials(%__MODULE__{name: name, password: pass}) do
    {name, pass}
  end

end