Metadata-Version: 2.4
Name: unicornidm
Version: 3.21.3
Summary: ID Management tool
License-Expression: GPL-2.0-or-later
License-File: LICENSE
Author: KAWAI Shun
Author-email: shun@osstech.co.jp
Maintainer: KAWAI Shun
Maintainer-email: shun@osstech.co.jp
Requires-Python: >=3.12
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: Django (>=4.0.6,<5.0.0)
Requires-Dist: PyMySQL[rsa] (>=1.0.2,<2.0.0)
Requires-Dist: SQLAlchemy (>=1.4.15,<2.0.0)
Requires-Dist: click (>=8.0.1,<9.0.0)
Requires-Dist: django-mongoengine (>=0.5.4,<0.6.0)
Requires-Dist: furl (>=2.1.2,<3.0.0)
Requires-Dist: google-auth (>=1.30.1,<2.0.0)
Requires-Dist: netaddr (>=0.8.0,<0.9.0)
Requires-Dist: ordered-set (>=4.0.2,<5.0.0)
Requires-Dist: passlib (>=1.7.4,<2.0.0)
Requires-Dist: psycopg2 (>=2.8.6,<3.0.0)
Requires-Dist: pymongo (==3.13.0)
Requires-Dist: python-dateutil (>=2.8.1,<3.0.0)
Requires-Dist: python-ldap (>=3.4.2,<4.0.0)
Requires-Dist: requests (>=2.25.1,<3.0.0)
Requires-Dist: tzlocal (>=2.1,<3.0)
Requires-Dist: uWSGI (>=2.0.19,<3.0.0)
Project-URL: Documentation, https://www.osstech.co.jp/download/updates/docs/unicornidm3/
Project-URL: Homepage, https://www.osstech.co.jp/product/unicorn/
Description-Content-Type: text/markdown

# Unicorn ID Manager 開発

[![pipeline status](https://gitlab.osstech.co.jp/source/unicornidm/badges/develop/pipeline.svg)](https://gitlab.osstech.co.jp/source/unicornidm/commits/develop)
[![coverage report](https://gitlab.osstech.co.jp/source/unicornidm/badges/develop/coverage.svg)](https://gitlab.osstech.co.jp/source/unicornidm/commits/develop)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)

## 開発に必要なソフトウェア、パッケージ

 * Python (with devel) >= 3.4
 * Docker >= 1.10.0
 * docker-compose >= 1.6.0
 * npm
 * openssl （ UnicornIDM のサーバー自己証明書を作るために必要）
 * (python3-venv)（Ubuntuのみで必要な deb パッケージ）
 * (nodejs-legacy) （Debian, Ubuntuのみで必要な deb パッケージ）
 * (libldap2-dev) (python-libldapのビルド時に必要 debパッケージ)
 * (libpq-dev) (psycopg2のビルド時に必要 debパッケージ)




## コーディング規約

### Python

flake8 に従っている。
独自ルールは[設定ファイル .flake8](.flake8)参照。

### Javascript

`es201x/`ディレクトリにあるコードは
[![JavaScript Style Guide](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard) に従っている。
独自ルールは[package.json](package.json)に`standard`キーの中参照。

### HTML

まだ存在しない。
設定してくれる人募集中。

## 開発/テスト環境

この節の作業はこの`README.md`があるディレクトリで行うこと。

ここに書くことは基本的に`Makefile`や`docker-compose.yml`などのファイルを読んで
`*requirements.txt`や`package.json`などで宣言されているライブラリや
その他使用ソフトウェアについて理解すれば分かることですが、
開発参加開始時からそれらを読むのは辛いと思うので
ここで概要を説明します。

### 環境作成方法

Ubuntu を使っている人は docker 内の DNS サーバーが社内サーバーを見るように設定を変更してください (c.f. https://gitlab.osstech.co.jp/rpm/openldap/merge_requests/2 )。
設定ファイルは docker のバージョンが 17.12.0~ce の場合は`/etc/docker/daemon.json`になります（以下）。

```console
# cat /etc/docker/daemon.json
{
    "dns": ["10.0.0.4", "10.0.0.8"]
}
# systemctl reload docker.service
```

`make build-env`すれば必要な Python, Javascript ライブラリがインストールされるようになっています（同時に docker image も作成される）。
それをやると`node_modules`, `idmenv`というディレクトリが手元にできると思います。
前者は Javascript のライブラリのインストール先、後者は Python ライブラリのインストール先です。

開発を始める前に`source idmenv/bin/activate`して`idmenv`仮想環境をセットアップしてください。
仮想環境から離れるときには`deactivate`を実行してください。
詳しくは[venv](https://docs.python.jp/3/library/venv.html)参照。


### UnicornIDM を動かしてみるには

#### 準備

1. パスワードファイルを作成してください。詳しくは後述。
2. 静的アセット (Javascript, CSS, 画像など）の準備のために、`make legacy-assets`を適時実行し、それに加えて別端末で`npm run start`を走らせておいてください。

#### 実行

`make run`や`docker-compose up -d`とやると手元で UnicornIDM をブラウザから触れる (url: `https://localhost/unicornidm/admin`) 。
初期状態で登録されている管理者の名前は **test-admin** 、パスワードは **secret** 。

詳しくは docker の勉強をすると良い。

#### 自動テスト

##### on docker

`make test`で自動テストが走る。

`make test T="hoge"`と`T`オプションを指定すると、指定した文字列が`pytest`のオプションとして渡される。
例えば`make test T="--lf"`とすると前回のテストで失敗したテストだけが実行される（`--lf`は`--last-failed`の略）。
ただし、[`-m`オプション、`-k`オプションを指定するとき](https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests)
にはそれぞれ`m="not slow"`、`k="MyClass and not method"`と書くこと。以下は例。

```console
$ # slow マークのついていないテストだけ走らせコードカバレッジを出力する
$ make test m="not slow" T="--cov unicornidm"
```

その他の使用可能なオプションを調べるには[`pytest`のドキュメント](https://docs.pytest.org/en/latest/contents.html)か、
`pytest`をインストールした venv 仮想環境で`pytest --help`を実行する。

デフォルトで`pytest`に渡されている他のオプションについては`docker/unicornidm/tox.ini`参照。

##### 手元

`docker-compose up -d`で必要なコンテナを起動する（これで立ち上げたコンテナは開発中ずっと走らせておけばよい）。
これをしない場合、以下のコマンドが何も出力せずに止まったままになります。

`pytest` で自動テストが走る。

`pytest -m "not slow"` で遅いテストを実行しなくなる（pytest の[カスタムマーク](https://docs.pytest.org/en/latest/example/markers.html)を使っている）。

pytest については`pytest --help` やトップディレクトリの`tox.ini`参照。


#### UIDM のログの場所

`main`コンテナの`/path/to/log/`ディレクトリに色々ある。
例えば`docker-compose exec main bash`で`main`コンテナに入れる。

自動テスト (`make test`) 時のログは大抵は`test`コンテナの`/path/to/log/`ディレクトリにあるが、
`unicornidm-tool`のテストだけは`main`コンテナにログがある。

#### 設定の変更

`docker/unicornidm/etc/`ディレクトリ以下のファイルを編集すると UIDM の設定がそれに合わせて変わります。
docker の環境なら uWSGI, MongoDB に関する設定以外は自動で反映されると思いますが、されてなさそうだったらコンテナを再起動してください。

#### ソースコードに加えた変更を実行中のテスト環境に反映させたいとき

デバッグ環境では uWSGI の`py-auto-reload`オプションを設定しているので自動反映されるはず。

反映されてなさそうだったらコンテナを再起動すればよい（以下）。

```console
docker-compose restart main
```

### パスワードファイル等の生成について

`docker/unicornidm/etc/secrets/`ディレクトリに docker で UnicornIDM を動かすために必要な機密情報ファイルを置く必要があります。

2017年5月段階ではレポジトリに既にあるファイルの他に以下のファイルが必要です。

 * `azure-password` - 後述
 * `google-json-key` - 後述

中身に何を書くかはメイン開発者に訊いてください。

以下のファイルも必要ですが、これらは`make`で自動生成されます。

 * `cert.pem`
 * `key.pem`

これらのファイルのパーミッションは`0444`にしておいてください。
アクセス制限をかけると docker からこれらのファイルが読めなくなってしまいます（2017年5月現在）。

#### G Suite, Azure Active Directory の API 利用のための credential 生成について

docker の環境から OSSTech の G Suite（旧 Google Apps）, Azure Active Directory にアクセスするために、認証用のデータを取得、生成する必要がある。
これらは、 https://www.osstech.co.jp/download/updates/docs/unicornidm3/preparebackend.html を参考にして作成する必要があります。

生成した認証用データを以下に配置してください。

 * `docker/unicornidm/etc/secrets/azure-password`
 * `docker/unicornidm/etc/secrets/google-json-key`

Azure AD の情報は https://trac.osstech.co.jp/wiki/office365 にあり、 G Suite の情報は https://trac.osstech.co.jp/wiki/TechGoogleApps にあります。
これらの情報をもとに、上のページの「各バックエンドを利用するための準備」を参考にして、 API 利用アカウントを作成してください。
ただし、Azure ADに関しては独自のアプリケーションを追加せずに代わりに *unicornidm-test* を使ってください。 （つまりキーだけ追加し、キー値を保存する）

上記ファイルはなくさないように他のディレクトリにもコピーを取っておくことを推奨します。

本節は、悩んでも仕方がない部分ですので、わからないことがあればすぐに聞いてください。




## git/GitLab

### コミット時の注意

`unicornidm/_locale/ja/LC_MESSAGES/django.po`は必要なときだけコミットに含めてください。
つまり適時`git chechout HEAD unicornidm/_locale/ja/LC_MESSAGES/django.po`してからコミットしてください。

このファイルはテストを実行したりする度に django によって書き換えられるのですが、
無意味な書き換えの場合が多いです。

### 開発フロー

Unicorn ID Manager の開発は GitHub フローを採用しています。
具体的には以下の流れでのフローを想定しています。

1. 機能追加やバグ修正に関する Issue を GitLab に投稿
2. 開発者が自分か他の開発者に Issue をアサイン
3. アサインされた Issue に基づく feature ブランチを develop から作成
4. 開発
5. feature ブランチを GitLab に Push
6. FIXME: 自動でテストを走らせたい
7. develop ブランチに Merge Request (Pull Request)
8. 誰かにレビューしてもらう (Review)
9. develop ブランチにマージ (Merge)
10. ~~次期リリースの目処が立ち次第、 develop ブランチから master ブランチに Merge Request (Pull Request)~~
11. ~~master ブランチにマージ (Merge)~~

### ブランチ命名ルール

* `master`
    - 使ってない
* `develop`
    - 開発安定版。次期リリースブランチ
* `$(issue number)-$(label)--feature-topic-name`
    - 開発機能・ストーリーごとのブランチ
    - `develop`の`HEAD`をベースに作成し、完了後に`develop`に Pull Request
    - `$(label)`は基本的に GitLab のラベル名を与えてください。
    - GitLab 上でイシューとして登録されているものには`101-`などと先頭に付けてください。イシューに挙がっていないものには付けなくていいです。

# パッケージング

## バージョニング

Semver (Semantic Versioning) と呼ばれているやつをやっているつもりだけど、メジャーバージョンのアップは開発者だけで決めないで（マーケティング的に影響がでかいので）。

正式版のパッケージを作る手順は以下です。

1. rpm SPEC ファイルとドキュメントの変更経歴を書く
1. 上記2つをコミットして、git の *annotated* tag を打つ。
1. `build-cent7`でリリース作業をやる。

リリース前のパッケージを作る手順は以下です。

1. `build-cent7`でリリース作業をやる。正式リリースでないことを示すリリース番号が自動で付く。

## リリース作業

[RELEASE_FLOW.md](https://gitlab.osstech.co.jp/source/unicornidm/-/blob/modifyREADME.md/RELEASE_FLOW.md)

## MongoDBについて

Unicorn ID Manager の内部DBとしてMongoDBを利用しています。
MongoDBの中には主に以下のデータが保存されています。

* Unicorn ID Manager の管理ユーザーの情報
* Unicorn ID Manager の管理ロールの情報
* 自動生成されたパスワード
* ユーザーデータのキャッシュ
* グループデータのキャッシュ
* Unicorn ID Manager の操作ログ
* パスワードリセット機能利用時のURL

MongoDBの中身を直接確認、編集する場合はMongoShellを利用します。
Unicorn ID Manager サーバーで自身のMongoDBにログインするには下記のコマンドを実行してください。

```
# /opt/osstech/libexec/unicornidm/mongo -u unicornidm -p `cat /opt/osstech/var/lib/unicornidm/db.password` --authenticationDatabase admin unicornidm
```

`/opt/osstech/var/lib/unicornidm/db.password` は初回起動時に自動生成されるため、最低一度は正常に起動する必要があることに注意してください。
MongoDBのサービスは `osstech-unicornidm` と同時に起動するので、上記コマンドを実行するためには `osstech-unicornidm` が起動している必要があります。

MongoShllにログインした後は `show collections` でコレクション一覧が見れます。

```
> show collections
__admins__
__passwords__.target1
__passwords__.target2
__roles__
__user_login__.target1
cache.sessions
target1.User
target1.Group
target2.User
targets.target1.operations
targets.target1.submissions
targets.target2.operations
targets.target2.submissions
```

コレクションを指定する際、基本的には `db.<コレクション名>` で指定できますが、
`__admins__` のようなコレクションを `db.__admins__` と選択すると `TypeError` になってしまいます。
その場合は、`db.getCollection('__admins__')` と指定するようにしてください。

それぞれコレクションの中身を確認するときは `find()` を利用します。
例えば、`target1`というターゲットの操作ログを一覧したい場合は下記のコマンドを実施してください。

```
> db.targets.target1.submissions.find()
```

`find()`は引数に辞書型で検索クエリを指定できます。
例えば正常終了した操作ログのみを検索する場合は下記のコマンドを実施してください。

```
> db.targets.target1.submissions.find({"status": "completed"})
```

`find()`に指定出来る検索クエリは[公式ドキュメント](https://docs.mongodb.com/manual/reference/method/db.collection.find/)を確認してください。


# Unicorn ID Manager の特徴

Unicorn ID Manager は次の特徴を持つ ID 管理システムです。

* データストア (メタデータ) を自前で持たない
* テキストベースの設定
* ユーザー自身によるパスワード変更 UI
* ユーザー自身によるパスワードリセット UI
* ユーザー自身による属性変更 UI
* ロールベースのアクセス制御
* スケーラブルな連携先バックエンド

## データストア (メタデータ) を自前で持たない

Unicorn ID Manager は自身でメタデータを保持しません。
これにより、 Unicorn ID Manager に対するコストをかける必要が
ないことを意味します。

## テキストベースの設定

Unicorn ID Manager はテキストベースで設定を行います。
これにより、デプロイを容易にします。

## ユーザー自身によるパスワード変更 UI

Unicorn ID Manager はユーザー自身がパスワードを変更するための UI
を備えています。これにより、複数の連携先システムとのパスワード同期を
実現します。

## ユーザー自身によるパスワードリセット UI

ユーザー自身によるパスワード変更の際、ユーザーは現在のパスワードの入力を
求められます。そのため、現在のパスワードを忘れてしまった場合パスワード変
更ができません。

そこで、 Unicorn ID Manager は設定によりユーザー自身による
パスワードリセットを許可するための機能を備えました。これにより、
管理者への問い合わせを減らすことが可能となります。パスワードリセットは
ユーザーが自分のユーザー名と登録済みのメールアドレスを入力し、
そのメールアドレス宛に届く特別な URL からアクセスすることで
パスワードリセットを行います。

## ユーザー自身による属性変更 UI

Unicorn ID Manager は設定によりユーザー自身で一部の属性の変更を許可する
機能を備えています。これにより、ユーザー自身で任意に属性を変更可能になるため、
管理者の負担を軽減することができます。たとえば、ユーザーにメールアドレス
と姓を任意に変えさせたい場合に有用です。設定で指定されていない属性につい
てはユーザー自身が属性を変更することはできません。

## ロールベースのアクセス制御

Unicorn ID Manager には複数の管理者を登録可能です。これらの管理者には
ロールという権限一式をまとめた情報が割り当てられています。
管理者はこのロールで許可された操作しか行うことができません。これにより、
管理者に権限を委譲することが可能です。

## 様々な ID管理レポジトリへの統一的インターフェース

Unicorn ID Manager は以下の連携先バックエンドをサポートしています。

* LDAP
* Active Directory Domain Controller
* RDBMS (PostgreSQL, MySQL)
* G Suite （旧 Google Apps）
* Microsoft Azure Active Directory

ここにあるもの以外の連携先についても追加可能です。
別の連携先バックエンドが必要になりましたら私達にお問い合わせください。


