Materia.Grantsを使って実行権限チェックを行う


このハンズオンは
[Materiaを導入してログイン認証してみる](https://qiita.com/tuchiro/private/ee6fdf487665b9789540)
の続きです。

# 権限チェックpipeラインと管理者用ルーティングを追加する


```elixir:/Users/tsuchiro/code/samples/materia_sample/lib/materia_sample_web/router.ex

〜中略〜

  pipeline :grant_check do
    repo = Application.get_env(:materia, :repo)
    plug Materia.Plug.GrantChecker, repo: repo
  end

〜中略〜

  scope "/api/ops", MateriaWeb do
    pipe_through [ :api, :guardian_auth, :grant_check]

    resources "/grants", GrantController, except: [:new, :edit]
    resources "/mail-templates", MailTemplateController, except: [:new, :edit]

    resources "/users", UserController, except: [:edit, :new]
    resources "/organizations", OrganizationController, except: [:new, :edit]

  end

〜中略〜

```

権限のデーターは[Materiaを導入してログイン認証してみる](https://qiita.com/tuchiro/private/ee6fdf487665b9789540)を実施していれば導入済み。

```
Accounts.create_grant(%{ role: "anybody", method: "ANY", request_path: "/api/ops/users" })
Accounts.create_grant(%{ role: "admin", method: "ANY", request_path: "/api/ops/grants" })
Accounts.create_grant(%{ role: "operator", method: "GET", request_path: "/api/ops/grants" })
Accounts.create_grant(%{ role: "anybody", method: "ANY", request_path: "/api/ops/organizations" })
Accounts.create_grant(%{ role: "anybody", method: "ANY", request_path: "/api/ops/mail-templates" })
```


#　起動して確認する

```
> iex -S mix
```

#### オペレーター権限のユーザーでログインする

- Request

```
POST http://localhost:4000/api/sign-in HTTP/1.1
Content-Type: application/json

{
    "email": "fugafuga@example.com", 
    "password": "fugafuga"
  }
```

#### 権限がないのでエラーになる

- Request

```
GET http://localhost:4000/api/ops/users HTTP/1.1
Content-Type: application/json
Authorization: Bearer fugafuga
```

- Respose

```
HTTP/1.1 401 Unauthorized
server: Cowboy
date: Fri, 14 Dec 2018 09:52:23 GMT
content-length: 22
cache-control: max-age=0, private, must-revalidate

{"message":"no grant"}

```

#### 管理者権限のユーザーでログインする

- Request

```
POST http://localhost:4000/api/sign-in HTTP/1.1
Content-Type: application/json

{
    "email": "hogehoge@example.com", 
    "password": "hogehoge"
  }
```

#### ユーザー一覧を取得できる


- Request

```
POST http://localhost:4000/api/sign-in HTTP/1.1
Content-Type: application/json

{
    "email": "hogehoge@example.com", 
    "password": "hogehoge"
  }
```

- Response

```
HTTP/1.1 200 OK
server: Cowboy
date: Fri, 14 Dec 2018 09:57:42 GMT
content-length: 1193
content-type: application/json; charset=utf-8
cache-control: max-age=0, private, must-revalidate

[{
  "status": 1,
  "role": "operator",
  "phone_number": null,
  "organization": null,
  "name": "fugafuga",
  "lock_version": 1,
  "id": 2,
  "icon_img_url": null,
  "external_user_id": null,
  "email": "fugafuga@example.com",
  "descriptions": null,
  "back_ground_img_url": null,
  "addresses": []
}, {
  "status": 1,
  "role": "admin",
  "phone_number": null,
  "organization": {
    "users": [],
    "status": 1,
    "profile_img_url": "https://hogehoge.com/prof_img.jpg",
    "phone_number": null,
    "one_line_message": "let's do this.",
    "name": "hogehoge.inc",
    "lock_version": 1,
    "id": 1,
    "hp_url": "https://hogehoge.inc",
    "back_ground_img_url": "https://hogehoge.com/ib_img.jpg",
    "addresses": []
  },
  "name": "hogehoge",
  "lock_version": 2,
  "id": 1,
  "icon_img_url": null,
  "external_user_id": null,
  "email": "hogehoge@example.com",
  "descriptions": null,
  "back_ground_img_url": null,
  "addresses": [{
    "zip_code": "810-ZZZZ",
    "user": [],
    "subject": "living",
    "organization": [],
    "longitude": null,
    "lock_version": 0,
    "location": "福岡県",
    "latitude": null,
    "id": 1,
    "address2": "港 x-x-xx",
    "address1": "福岡市中央区"
  }, {
    "zip_code": "810-ZZZZ",
    "user": [],
    "subject": "billing",
    "organization": [],
    "longitude": null,
    "lock_version": 0,
    "location": "福岡県",
    "latitude": null,
    "id": 2,
    "address2": "大名 x-x-xx",
    "address1": "福岡市中央区"
  }]
}]
```