2018年4月17日火曜日

LogicFlow でパスワード文字列を生成する

とある理由でアカウント登録をするような LogicFlow を作成していたのですが、その際に初期パスワードをどうしたものだか、という課題がありました。Azure Functions でも使えばさっくりいけるのですが、そこを LogicFlow でやってみることにしました。

今回作成したものは Github にて公開しています。デプロイ用ボタンも設置してあるので、自分の環境にデプロイして試してみてください。

実際にパスワードを生成するにあたり、注意するのは「利用可能な文字」についてです。Azure Active Directory の場合、英語の大文字小文字、数字、そして一部記号が利用可能になっています。この中からランダムに文字を選択する必要があります。

CreatePassFlow

LogicFlow 全体としては、このような感じで作成しました。非常に力業です(

image

最初に生成結果を設定する変数と、必要な桁数(今回は8~16文字としています)を算出します。ここでポイントが「配列の要素数=必要な桁数」となるよう、range 関数を使っているところです。理由は後述します。

image

次に利用可能な文字を、種類ごとにまとめて設定します。この時、0~9 な数字文字列を設定する際、そのままだと「数値」として認識されてしまうので、string 関数で明示的に文字列としておきます。

image

それらをもとに、1文字ずつパスワードとなる文字列を抽出していきます。どの文字種を使うかをランダムにして、Switch にて分岐させます。

image

それぞれのケースの中で、最初に設定した利用可能な文字列から、1文字抽出を行います。大体次のように指定してあげれば OK です。

substring(outputs('抽出元文字列'),rand(0,length(outputs('抽出元文字列'))),1)

抽出対象となる文字列から、0 から抽出対象文字列の桁数までの間でランダムに位置を決め、1文字抽出しています。このような書き方をすると、利用可能な文字が増えたとしても、ここを修正する必要はありません。

image

最後に抽出した結果を結合して、生成結果としています。

全体的にこのように単純な処理を組み合わせたものですが、LogicFlow 上で行うにあたって一点だけ注意がありました。最初のところで必要桁数を配列変数に設定していましたが、これは ForEach ループでなくてはいけない理由があるためです。

もう一つのループ、Do-Until を利用するとした場合、カウンタとして利用する変数に桁数を設定、ループの中で 1 ずつ減算していく形を思い浮かべると思います。ところが、LogicFlow の Do-Until ループは「非同期で並列動作」するものです。何が起きるかというと、複数同時に処理が動きカウンタの値が正しく減算されない、という挙動になります。マルチスレッドの挙動そのものです。さらに Do-Until ループでは、シーケンシャルに動作させるというオプションがありません。必ずマルチで動作します。

2018/04/18 修正

私の勘違いで、Do-Until はシーケンシャルに動作していました・・・

このような事情があり、ForEach で繰り返すために桁数を配列で表現するやり方を採用しました。なお、生成したパスワードが複雑さの要件を満たしているかのチェックは行っていませんので、呼び出し元で判定する必要があります。

0 件のコメント:

コメントを投稿