OmniAICreator/Qiita-1.07M huggingface dataset:
macでdnsmasq

# やりたいこと
/etc/hostsにワイルドカードが書けないので、同じような挙動を実現したい。
`*.example.com 192.168.0.1`
をやりたい

# Homebrewでインストール
`brew install dnsmasq`

# 設定
`/usr/local/etc/dnsmasq.conf`
に下記を追加
`address=/example.com/192.168.0.1`

```
sudo mkdir -p /etc/resolver
cd /etc/resolver/
sudo vi example.com
中身↓
nameserver 127.0.0.1
```

`scutil --dns`
で、

```
resolver #8
  domain   : example.com
  nameserver[0] : 127.0.0.1
  flags    : Request A records, Request AAAA records
  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)
```
があればOK
Nuxt(Vue)で、ある位置までスクロールしたらclassを付与、そしてヘッダー追従

## ある位置までスクロールしたらclassを付与したい

よくある「ある位置までスクロールしたらヘッダー追従」で、classを付与してcssの`position:fixed`でスタイル調整する方法です。

`<template>`には以下内容を記載

```vue:template
<header id="header" :class="{ '-fixed': scrollY > 900 }">
  <logo />
  <nav>
    <ul class="list">
      <li><n-link to="/">メニュー</n-link></li>
      <li><n-link to="/">メニュー</n-link></li>
      <li><n-link to="/">メニュー</n-link></li>
      <li><n-link to="/">メニュー</n-link></li>
    </ul>
  </nav>
  <button class="nav-btn">
    <span class="nav-ico"></span>
  </button>
</header>
```

`<script>`には以下内容を挿入
※必要な部分のみ記載してます

```js:script
export default {
  data() {
    return {
      // 座標を指定
      scrollY: 0
    }
  },
  mounted() {
    window.addEventListener('scroll', this.handleScroll)
  },
  methods: {
    handleScroll() {
      this.scrollY = window.scrollY
    }
  }
}
```

```vue:template
<header id="header" :class="{ '-fixed': scrollY > 900 }">
```
`:class="{ '-fixed': scrollY > 900 }`で、

```text:
スクロール値が900以上になったらclass'-fixed'を付与してね
```

って指示してます。

あとは、付与されたclassに対してスタイル調整するだけです。
個人的にはわかりやすいのでcssでやってしまってます。

もっと上手な書き方あったら教えてください😃

## 参考にさせていただいた記事
[【Vue.js】スクロールでDOM操作する（消えるタイトル編）](https://qiita.com/su_mi1228/items/e03cec84773e00f5942b)

## スペシャルサンクス
当社の社長
Vue.jsの404リダイレクト

## やりたかったこと。

- Vue.jsで404ページへのリダイレクト
- 404ページは静的HTML
- レスポンスコードも404

## 結果。
出来ませんでした...
（Vue.jsのv2）

## 妥協後の設定。
“レスポンスコードも404” は諦めました。
純粋にJavaScriptで404用のhtmlにリダイレクトするように...
リダイレクトになるので、ブラウザのアドレスバーが404用のhtmlに変わるのもダサい気もしましたが、諦めました。

###### 1. routerの設定
静的HTMLに遷移させるので、リダイレクト先のcomponentなどは不要。

```javascript
// 404
{
  name: 'FileNotFound',
  path: '*'
}
```

###### 2. router.beforeEachの設定
routerのredirectだとVue内の遷移になるので、router.beforeEachで指定する。
この時、nextだとredirectと同じになるので、window.locationを使用する。

```javascript
router.beforeEach((to, from, next) => {
  if (to.name === 'FileNotFound') {
    window.location = '/err/404.html'
    return
  }
```

###### 3. Apacheの設定
window.locationで遷移したページの場合は、404エラーに書き換える。

## 所感
アドレスバーはアクセスした時のURLのままが良かった...
VSCodeのver1.40アップデートでのフォントとその設定について


※2019/11/12時点
頂いたコメントと追加で調べた内容を追記しました。
@lunatea さん、ありがとうございました！
追記した結果、内容がほぼ別ものになったのでタイトルも変更しました。

※2019/11/08時点
ひとまずな回避方法メモになります。
根本的には未解決です。何かあれば、また追記する予定です。

# 結論

- monospaceがメイリオからMSゴシックになったよ
- フォント設定の正しい書き方
- (オマケ)源ノ角ゴシックCode JP Nが使えないのはまた別問題だったよ

**リリースノート：2019年10月（バージョン1.40）**
https://code.visualstudio.com/updates/v1_40


以上です。
個別に説明します。

## monospaceがメイリオからMSゴシックになったよ

Ver1.40からmonospaceで設定されているフォントが、メイリオからMSゴシックに変更されたようです。
理由の方は調べてみましたが、ちょっと分かりませんでした。

そもそもmonospaceとは何ぞや？という話だと、
>等幅フォント（とうはばフォント、とうふくフォント、英: monospaced font）は、
>グリフ幅を固定された幅（モノスペース）で実装したフォント。
https://ja.wikipedia.org/wiki/%E7%AD%89%E5%B9%85%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88



## VSCodeフォント設定の書き方

こんな感じで、設定したいフォントとそのweightを指定しましょう。
先頭のフォントが優先して表示されるので、英語だけは違うフォントにしたい場合は下の書き方で出来ます。

```json:settings.json
 "editor.fontFamily": "源ノ角ゴシック Code JP",
 "editor.fontWeight": "300",
```
```json:settings.json
 "editor.fontFamily": "Consolas , Meiryo",
 "editor.fontWeight": "300",
```

fontFamilyにサイズ名(HeavyとかNormalとか)追加するとweightも指定できるので、
わざわざfontWeightで指定する必要はないかもしれません。

コメントからの引用になりますが、サイズ名とWeightの値の対応は以下のようになってます。
>例えばRegularとNormalとMediumをインストールしている場合は
>fontWeightが300でReguler、400(もしくはNormal)でNormal、500でMediumに変わります。
>インストールされていない太さには基本的には変わりません(例外はあり)。

個人的には、複数のフォントを使っている場合やそのWeightが無い場合を考えると
別で指定した方が管理しやすいかな、と。

あと、自分が今までフォント名自体を間違えていいたので、そちらの回避方法も。
フォント名を正しく知る方法です。
https://qiita.com/Actlam/items/f246d3f2c69387c867b3

一覧にファミリ名が表示されていない場合は、上の「表示」->「詳細表示の設定」で「ファミリ」にチェックを入れれば、
後ろの方に表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492877/005d9b0d-b094-317a-e4f7-964269a476e3.png)


## (オマケ)源ノ角ゴシックCode JP Nが使えない問題

ここの記事とコメントで、使えないという報告がありました。
結構前からだったそうで…。
https://qiita.com/dev100kg/items/bcae2fc210326eda0ca3

ただ、出来ないのはfontFamilyでWeight名まで含めた"源ノ角ゴシックCode JP N"を設定したパターンです。
Weightを上記のsettings.jsonのように設定すれば、Normal・Regularのどちらでも表示されたので、
源ノ角ゴシック Code JP使いの方は、fontFamily・fontWeightの個別設定推奨です。
DockerというものにPythonというものを入れるまで

#dockerって名前かっこいいですよね

[前回](https://qiita.com/han-aru/items/624f08baa91b4854d69a)はMacにdockerというものを入れて起動するまでをやってみました
今度はそのdockerにPythonを入れてみようと思います

色々としらべましたが、
#まず`イメージ`という単語を覚えるところからです
Python一式データをイメージと呼ぶようです

[今回はここ](https://qiita.com/po3rin/items/45ba92e482efcf883325)を参考に進めていきました
**ありがとうございました！**

```bash:これだけです、こんなに簡単だったの？あの検索した時間を返して！
docker pull python
```

私の場合`sudo`は書かなくても良かったです
また`python:3.6`のバージョンもいりませんでした
バージョンを書かずに実行すると勝手にlastedと書かれて
最新をダウンロードしてくれるらしいです

一通り[今回はここ](https://qiita.com/po3rin/items/45ba92e482efcf883325)を参考に順調進めていけましたが、最後にわからなかったとこ…

#`再びコンテナ起動`の箇所

```bash:あれ？再起動ができない
docker exec -it pytest /bin/bash
```
これを書くと
こう言われる…

```bash:なにこれ？
Error response from daemon: Container 英語と数字の羅列 is not running
```

#なんかぁ、起動してないんだって

>
いや、だから再起動してるのに…？？？

色々調べてみたり書いたりしてみたら
エラーの文字で`start it first`との記述が…

#試しに`docker start pytest`と書いて実行してみる

…なんか起動したっぽい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/4f2d75a8-c621-0af1-6b9c-6e937624ed67.png)
vscodeのdocker拡張機能の見え方が
さっきまで□だったのが再生？ の▷になったし
__タピオカ飲みたい__


#改めて`docker exec -it pytest /bin/bash`を実行してみる

OKでした！
###イェーイ！
rails 発展その3-2 マイページの作成

## マイページの作成
基本は:idの使用くらいで他と変わらず
userコントローラーの作成とshowアクションでビューを作成するくらいです。

```ruby:routes
  Rails.application.routes.draw do
    get     '/コントローラ名/:id'        => 'コントローラ名#show'
  end

# :idの部分には表示するユーザーページのユーザーのidが入ります。

# 例
  Rails.application.routes.draw do
    get   'users/:id'   =>  'users#show'    
  end
  # mypageのルーティング
```

```bash:ターミナル
   $ rails g controller users
```

```ruby:app/users/users_controller.rb
# ここも基本欲しいデータ(名前と持っているアイテム一覧)を引っ張ってくる仕様です。
# 又 current_user.カラム名　とすることでログインしてるユーザーのデータを引っ張ってきます。
class UsersController < ApplicationController
    def show
      @name = current_user.name
      @items = item.where(user_id: current_user.id).page(params[:page]).per(5).order("created_at DESC")
    end
  end
```

```html:app/views/users/show.html.erb
<!-- これでユーザーの名前とアイテムの一覧ができました。 -->
<div class="contents row" >
    <p><%= @name %>さんのアイテム一覧</p>
    <% @items.each do |item| %>
      <div class="content_post" style="background-image: url(<%= item.image %>);">
        <%= simple_format(item.text) %>
        <span class="name"><%= item.name %></span>
      </div>
    <% end %>
    <%= paginate(@tweets) %>
  </div>
```

ついでにマイページへのリンクがこちら

```html:マイページのリンク
   <a href="/users/<%= current_user.id %>">マイページ</a>
```
【自分備忘録】gulp4まとめ（ざっくり）

gulp3からgulp4にバージョンアップして、そのときに詰まったところやら、「そもそも書き方全然変わってるー」ってのをざっくり書きます！

## gulp.task()が非推奨になったので書き換える
gulp.task書きやすかったのにー(゜゜)


```書き換え前のgulpfile.js
gulp.task('taskA', () => {
  // 処理
})
```

```書き換え後のgulpfile.js
const taskA = callback => {
  // 処理
  callback()
}
// もしくは
const taskA = callback => {
  return 処理
}

```

### returnまたはコールバックしてあげないと、エラーが出る
returnもしくはコールバック関数で、ちゃんとタスクが完了したことをお知らせしてあげないと、

> The following tasks did not complete
> Did you forget to signal async completion?

ってな感じで、エラーが返ってきてしまうので、必ずreturnするかコールバックしてあげないといけない。

### gulpコマンドでタスクを実行させるにはもうひと手間必要
gulp4からは、コマンド実行用のタスクとコマンドで実行できないタスクと分かれるらしい。

* Public tasks（gulpfileからエクスポートされるため、gulpコマンドで実行可能）
* Private tasks（内部で使用される用。gulpコマンドで実行不可能）

詳細はこちら→[Creating Tasks](https://gulpjs.com/docs/en/getting-started/creating-tasks)
ってことで、関数として定義しただけでは、Private tasksになるので、gulpfile.jsでちゃんとexportsしてあげればOK。

```gulpfile.js
const taskA = callback => {
  // 処理を記述
  callback()
}
exports.taskA = taskA
```
これで、初めてgulpコマンドで実行可能になる。

## タスクを別ファイルに分ける
gulpfile.jsにたくさん書いていくとどんどん肥大化していくので、別ファイルに分けたい…！
そんなときは、**gulpfile.js**というディレクトリを作り、その中にindex.jsを作成。
あとは、タスクを書いたjsファイルをぽこぽこ増やせばOK。

```
project
 ├ gulpfile.js［ディレクトリ］
 │   ├ tasks［ディレクトリ］
 │   │   ├ taskA.js 
 │   │   └ taskB.js 
 │   └ index.js
 ├ node_modules［ディレクトリ］
 └ package.json
```

ちなみに自分は、`gulpfile.js`ディレクトリの中にさらに`task`ディレクトリを作って、その中にタスク書いたjsを入れてる感じで作ってます。

```/gulpfile.js/taskA.js
const taskA = callback => {
  // 処理を記述
  callback()
}
exports.taskA = taskA
```

```/gulpfile.js/index.js
const { taskA } = require('./taskA')
exports.taskA = taskA
```

公式ドキュメントにも載ってるー。
[JavaScript and Gulpfiles](https://gulpjs.com/docs/en/getting-started/javascript-and-gulpfiles#splitting-a-gulpfile)


## タスクを直列／並列に処理する
複数のタスクを実行させるとき、順番通りに実行したいか、並列で実行させたいかってのがあるはず。
gulp3のときは`run-sequence`ってnode_moduleを利用してたけど、gulp4からはデフォルトでそのメソッドが入っているそうな

### gulp.series()
タスクを直列処理するメソッド。

```js
const gulp = require('gulp')
const { taskA } = require('./taskA')
const { taskB } = require('./taskB')

exports.default = gulp.series(taskA, taskB)
```

`gulp default`コマンドを実行すると、taskAが実行、それが終わるとtaskBが実行される。

### gulp.parallel()
タスクを並列処理するメソッド。

```js
const gulp = require('gulp')
const { taskA } = require('./taskA')
const { taskB } = require('./taskB')

exports.default = gulp.parallel(taskA, taskB)
```
`gulp default`コマンドを実行すると、taskAとtaskBが同時に実行される。

### seriesとparallelの合わせ技
もちろん合わせることも可能！

```js
const gulp = require('gulp')
const { taskA } = require('./taskA')
const { taskB } = require('./taskB')
const { taskC } = require('./taskC')

exports.default = gulp.series(
  taskA,
  gulp.parallel(taskB, taskC)
)
```
この場合、`gulp default`コマンドを実行すると、taskAが実行された後、taskBとtaskCが同時に実行される。

## まとめ
どうなんだろう…慣れれば結構書きやすいのかな(゜゜)
タスクを別ファイルで管理するのも、今まではモジュール追加しないとできなかったけど、それがgulpだけでできるのは良さそう。
あと、プライベートタスクとパブリックタスクって分かれてるのは、不用意にコマンド叩くことを防げるので良いかもしれないって思った(゜゜)

## 参考になりました、ありがとうございます

* [gulp公式ドキュメント](https://gulpjs.com/docs/en/api/concepts)
* [gulp4再入門 gulpfileの分割とnodeモジュールの利用](https://qiita.com/masato_makino/items/ad11058e1a8a009abbdf)
jira-pythonライブラリで作成したJIRAチケットのURL取得

#はじめに
https://qiita.com/mu-naka/items/9ad7f509e697e83c2987
↑以前書いたPythonのコードで、「JIRAチケットを作成する」処理を書いていたのですが、その後続処理にSlack通知を追加することになりました。
Slack通知内容に新規に作成したJIRAチケットURLを含めたかったのですが、URLの取得方法がドキュメントを探しても見つけるのに難儀した（見つかっていない）ため備忘録として書きます。もっといい方法があれば教えて下さい。
公式ドキュメントはこちら↓
https://jira.readthedocs.io/en/master/index.html

python上でJIRAライブラリを利用する方法については前回の記事で書いているのでそちらを参照してください。
本記事のpythonのバージョンは3.7です。

#おさらい
### ログイン
JIRAを操作する上でまずはログインする必要があるのでログインします。

```python:test.py
# JIRA Login
try:
    jira = JIRA(options = {'server': os.environ["JIRAのURL※１"]}, basic_auth = (JIRAのユーザーID, JIRAのパスワード))
except JIRAError as e:
    return { "status" : "JIRA Login Failed." }
```

※1　チケット詳細ページのURLが仮に
https://jira.hoge.com/jira/browse/HOGE-001
だった場合は
https://jira.hoge.com/jira
を入力

### チケット作成
```python:test.py
# Create New Issue
newIssue = jira.create_issue(
    project = 'プロジェクト名※２',
    summary = '要約（チケットタイトル）',
    description = 'チケットの説明',
    issuetype = {'name':'タスク'}
    )
```

※2　チケット詳細ページのURLが仮に
https://jira.hoge.com/jira/browse/HOGE-001
だった場合は「HOGE」を入力

#本題
チケット作成時のcreate_issue()の返り値がnewIssueに入っています。
このnewIssueの中身を見てみると

```python:test.py
from pprint import pprint
# （中略）
    pprint(vars(newIssue))
```

```text:log
{'_base_url': '{server}/rest/{rest_path}/{rest_api_version}/{path}',
 '_options': {'agile_rest_api_version': '1.0',
              'agile_rest_path': 'greenhopper',
              'async': False,
              'async_workers': 5,
              'auth_url': '/rest/auth/1/session',
              'check_update': False,
              'client_cert': None,
              'context_path': '/jira',
              'headers': {'Cache-Control': 'no-cache',
                          'Content-Type': 'application/json',
                          'X-Atlassian-Token': 'no-check'},
              'resilient': True,
              'rest_api_version': '2',
              'rest_path': 'api',
              'server': 'https://jira.hoge.com/jira',
              'verify': True},
 '_resource': 'issue/{0}',
 '_session': <jira.resilientsession.ResilientSession object at 0x7fa801472dd0>,
 'expand': 'renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations',
 'fields': <class 'jira.resources.PropertyHolder'>,
 'id': '12345',
 'key': 'HOGE-001',
 'raw': {
〜以下略〜
```
非常にボリュームがあるので省略していますが、そのままURLとして使えるパラメータはありませんでした。
しかしチケットのURLには`https://[JIRAサーバのベースURL]/browse/[チケットキー]`の規則があるので、以下のコードで生成できます。

```python:test.py

ticketUrl = newIssue._options.server + '/browse/' + newIssue.key
```

#おまけ
SlackへはIncoming Webhookを利用し、以下のコードで通知を飛ばします。

```python:test.py
requests.post('webhookのURL', data = json.dumps({
    'text': ticketUrl,
    'username': u'通知ユーザー名',
    'icon_emoji': u':bow:',
    'link_names': 1
    }))
```

諸々パラメータの値はサンプルと異なりますがこれで作成したチケットのURLをSlack通知内容に含めることができました。
<img width="390" alt="スクリーンショット 2019-11-08 15.22.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/f2114df7-bbd6-576a-f516-645f3d3f1719.png">
snapを使って、Rocket.Chatを構築する

# 前提

- VirtualBox
- Debian10
- Redmine4.0.5インストール済み

# 目的

- Rocket.ChatをインストールしてRedmineの更新でRocket.Chatに通知を送る

## Nat設定

- VirtualBox上のNAT設定で3000をHost->Guestに通す

## snapのインストール

```shell:command
sudo apt install snapd
```
```shell:操作コマンド
# 検索
sudo snap find [スナップ名]
# インストール
sudo snap install [スナップ名]
# アンインストール
sudo snap remove [スナップ名]
# インストール済のSnapを一覧表示
snap list
# アップデート
sudo snap refresh [スナップ名]
```

## Rocket.Chatのインストール

```shell:command
sudo snap install rocketchat-server
```

```shell:操作コマンド
# snapのRocket.Chatを起動する
systemctl start snap.rocketchat-server.rocketchat-server.service

# MongoDBのサービス確認（状態が表示されたらCtrl+Cで抜ける）
systemctl status snap.rocketchat-server.rocketchat-mongo.service
^C
# Rocket.Chatのサービス確認
systemctl status snap.rocketchat-server.rocketchat-server.service
```

http://[host]:3000/にアクセスして
Rocket.Chatのログイン画面が表示されればOK
![rocketchat.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526027/10dd563f-d57e-6a18-a0a4-2a2809170968.png)
Ubuntu18.04 インストール後の設定

## apt.conf プロキシ設定

```/etc/apt/apt.conf
Acquire::http::Proxy "http://proxy:port";
Acquire::https::Proxy "http://proxy:port";
```
sudo apt-get update しておく
## wget プロキシ設定

```/etc/wgetrc.
http_proxy = http://proxy:port/
https_proxy = http://proxy:port/
```
## nVIDIA ドライバのインストール
runではなくdeb localファイルを選択すると下記のnouveauとか必要なかった。
https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal

```
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb
sudo apt-key add /var/cuda-repo-10-2-local-10.2.89-440.33.01/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda
```

これで問題なし。



※注意　下記は古い情報（2020/12/24）必要なし

## ~~nVIDIA ドライバのインストール~~ （必要なし）
- ビルドツールをインストール

```/etc/wgetrc
sudo apt install build-essential
```

- nVIDIAからドライバ（runファイル）をダウンロード
- NVIDIA-Linux-x86_64-418.88.run (19/11現在)
- nouveauの無効化

```/etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
```
```
sudo update-initramfs -u
```
- 再起動
- 端末にログイン後、Ctrl+Alt+F3にてCUI環境に移動
- sudo service lightdm stop でディスプレイマネージャを停止
- sudo bash NVIDIA_....run でインストール
- すべてデフォルトの値でOK
- 再起動後、nvidia-smiでステータスを確認

## ~~cuda tool kit のインストール~~ （必要なし）
- cuda_10.1.243_418.87.00_linux.run
- 端末にログイン後、Ctrl+Alt+F3にてCUI環境に移動
- sudo service lightdm stop でディスプレイマネージャを停止
- sudo bash cuda_....run でインストール
- [CUIインストール画面] driver 418.87 はインストール対象から外し、toolkitのみ選択
- 再起動後、下記を追記

```~/.bashrc
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda:$LD_LIBRARY_PATH
```
- source ~/.bashrc
- nvcc -V　でcudaのバージョンが表示されらば完了
Docker for Windows on Proxy

#DockerのProxy環境を整えます。

タスクバーのDocker常駐アイコンから、Settingsを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45915/d60e405c-676a-b92f-6246-289fdd160a2a.png)

Proxyタブを選択して、Manual proxy configurationを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45915/fa70c7af-c8d9-eb96-a874-97ddc4fbc7f0.png)


当初コンテナーにはvimが入っていないので困惑しました。
docker exec でコンテナーに接続して、apt-getを利用する場合
直接、環境変数を入力してからapt-getを行ってください。

```
export http_proxy="http://proxy.co.jp:8080/"
apt-get update
apt-get vim
```
arachniの結果について

# 結果出力方法
arachniのスキャンが終わったら.afrが作成されます。
`bin/arachni_reporter --reporter=html ファイル名.afr`
とすることでzipが作成され、解凍するとhtmlが入っています。

# htmlについて
IssuesとSitemapを確認しましょう。

## Summary
結果のサマリーです。
特に見なくていいです。

## Issues
チェックで引っかかった脆弱性に関する情報が書いてあります。
主にここを見ます。

- TrustedとUntrusted
この区分はよくわかりませんが、両方確認してください。

  - High, Medium, Low, Informational
脆弱性の危険レベルです。
Highはやばい脆弱性ですので、確実に修正しましょう。
Mediumはなるべく対応しましょう。
Low, Informationalは内容を確認してできるものは対応してください。

## Plugin results
arachni内のプラグインの結果だそうです。
気にしなくていいです。

## Sitemap
チェックしたURLの一覧です。
チェックしたかったURLが含まれているか確認してください。
また、サイト全体を一気にやった場合は網羅されているか確認してください。

## Configuration
arachni実行時のパラメータ一覧です。
どんなチェックをしたか確認できます。

# Issuesについて

![3bd868ea61e83bde871b2cefa85e4f86.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529893/c26e7b05-f804-20be-45ed-5a557ef285be.jpeg)

- Vector information
- Affected page

これらをクリックすると、どのページにどのようなパラメータを入れて、どうなったのかがわかりますので、確認して該当箇所を修正してください。

# トークン入れてるのにCSRFが出るんだけど
token入れてるなら大丈夫だと思いますので、スルーでいいです。
cakephpでもよく出ます。

# X-Frame-Options
危険度はLowですが、IPAのチェックシートにもあるので、クリックジャッキング対策として記述するようにしたほうが良いと思います。
「吾輩は猫である」SentencePiece on Colab

# 吾輩は猫である SentencePiece 

今更ですが、Colabで日本語SentencePieceをやるサンプルが見当たらないので、作ってみました。手元にPython環境がなくても[気軽にColabで試せます](https://github.com/vochicong/ai-memo/blob/master/SentencePiece_JA_wagahaiwa_nekodearu.ipynb)。SentencePiece初心者に役に立てば幸いです。

自然言語処理において、文章を形態素解析したり、トークン化したりする作業が欠かせない。
ここでは夏目漱石の「吾輩は猫である」を[SentencePiece](https://github.com/google/sentencepiece/blob/6065c4a24f89401899595e14af826632d876587c/src/unigram_model_trainer_test.cc)でトークン化してみましょう。

## インストール

```bash
pip install sentencepiece
```

## データダウンロード

「吾輩は猫である」のテキストデータをダウンロード

```bash
wget https://raw.githubusercontent.com/google/sentencepiece/master/data/wagahaiwa_nekodearu.txt
```

テキストデータはこのような内容になっているはずです。
> 吾輩は猫である
夏目漱石
【テキスト中に現れる記号について】
《》：ルビ
（例）吾輩《わがはい》は猫である
......
入力：柴田卓治
校正：渡部峰子（一）、おのしげひこ（二、五）、田尻幹二（三）、高橋真也（四、七、八、十、十一）、しず（六）、瀬戸さえ子（九）
1999年9月17日公開
2015年2月3日修正
青空文庫作成ファイル：
このファイルは、インターネットの図書館、青空文庫（http://www.aozora.gr.jp/）で作られました。入力、校正、制作にあたったのは、ボランティアの皆さんです。

## SentencePiece モデルの学習

トークン化のやり方を覚えさせるために、「吾輩は猫である」のテキストを与えて、
SentencePieceに学習させます。

```python

import sentencepiece as spm

# Train sentencepiece model. Params taken from https://github.com/google/sentencepiece/blob/d4dd947fe71c4fa4ee24ad8297beee32887d8828/src/unigram_model_trainer_test.cc
spm.SentencePieceTrainer.train('--input=wagahaiwa_nekodearu.txt --model_prefix=wagahaiwa_nekodearu --vocab_size=8000 '
  '--normalization_rule_name=identity --model_type=unigram  --max_sentence_length=2048')

# makes segmenter instance and loads the model file
sp = spm.SentencePieceProcessor()
sp.load('wagahaiwa_nekodearu.model')
```

## トークン化の実施

下に定義する text をトークン化すると、 pieces に分解されることを確認しましょう。
また、IDも取得できます。

その後、piecesまたはIDから元の文章を正しく復元 (decode) できることを確認します。

```python
text = (
    "吾輩《わがはい》は猫である。"
    "名前はまだ無い。"
    "どこで生れたかとんと見当《けんとう》がつかぬ。"
    )
pieces = [
          '▁', '吾輩', '《', 'わが', 'はい', '》', 'は', '猫', 'である', '。',  
          '名前', 'はまだ', '無い', '。', 
          'どこ', 'で', '生', 'れた', 'か', 'とん', 'と', 
          '見当', '《', 'けん', 'とう', '》', 'が', 'つか', 'ぬ', '。']
ids = [135, 449, 4, 2388, 143, 3, 16, 184, 35, 5, 679, 1950, 2578, 5, 281, 18, 
       157, 1020, 17, 424, 14, 2401, 4, 302, 236, 3, 13, 277, 152, 5]  

# encode
assert sp.encode_as_pieces(text) == pieces
assert sp.encode_as_ids(text) == ids

# decode
assert sp.decode_pieces(pieces) == sp.decode_ids(ids) == text     
```

## まとめ

SentencePieceで簡単に「吾輩は猫である」のテキストをトークンに分解できました。また、バラバラに分解されたピースを使って、元の文章を再構築できました。[Colabノートブック](https://github.com/vochicong/ai-memo/blob/master/SentencePiece_JA_wagahaiwa_nekodearu.ipynb)を公開しているので、実際に動かしながら動作を確認するとより理解が深まります。
Theiaを入れてみた

iPadを使ったプログラミング環境を構築しつつあります。クラウドのサーバ（Ubuntu）にSSHでつないで。。。
iPadでもよいSSHターミナルアプリがあって:relaxed:と思いきや。。。
Webで調べながら作業しているとSSHターミナルアプリはバックグラウンドになりまして、するとiPadだと切れてしまうこともままあるわけです。:frowning2:
tmuxでセッションを維持するようにはしているのですが、いちいちログインし直すのもなぁ。。。
というわけで、ブラウザで使える、どうせならIDEを入れてしまおう、と思い立ったわけです。

# Theiaを入れてみた
Ubuntu環境でWebサーバを立てて、そこで動作するWebアプリとして使えるものはないかと探してみたのですが。。。
今のところは、[Theia] (https://theia-ide.org/)一択でした（当社調べ）。
TheiaはNode.js上で動作するアプリケーションで、[Eclipse public license](https://github.com/eclipse-theia/theia/blob/master/LICENSE)です。それでは入れてみましょう。

## いざ
手順は[こちら](https://theia-ide.org/docs/composing_applications/)に記載されています。
実はここに記載されている通りに実施して「はい終了」なのですが、ほんの少しあった、手順の中の注意点を記載します。

1. Nodeのversion 10をインストール。**version 10**です！
2. Theiaをインストールするディレクトリを作って、そこにpackage.jsonを作成します。
3. ビルド。`yarn theia build`は結構時間がかかりました。なので、

```sh
yarn theia build &
top
```
としてしばし待つのがお勧めです。
4. 完了！

## 動かし方（でも注意！）
ワークスペース（作業場所ディレクトリ）を指定できますので、何か適当に作ってそこを引数として指定します。ファイル選択はそのディレクトリが起点になりますが、上位に移動できますので、あくまでも便利というだけです。例えばこんな感じ。

```sh
yarn theia start ~/workspace —hostname example.com —port 8080
```

これで起動したサーバにブラウザで`http://example.com:8080`などとするとTheiaが使えます。ターミナル機能もあるので、ファイル編集はもちろん、CUIの操作も可能です。**って、ちょっと待った!**
このままでは認証とか特にありませんので、導入したサーバが外部からアクセス可能だったら、**ログイン操作なしで誰でも**使えてしまいます！
そこで、Apacheにリバースプロキシを設定して、TheiaをApache経由でアクセスするように配置します（他にも方法はありそうですが、単に私の慣れている方法ということで）。

そのときのお話は[またの機会](https://qiita.com/woolk23/items/e89a6652df560a771a97)に。
電装講座(目次)

#はじめに
電装講座をまとめただけです。うん。

#記事一覧
## [QX電装講座 #1 マイコンってなんなの?](https://qiita.com/GoshBird/items/c7b7fbcf84b92292ebfa)
最初の記事で、マイコンの存在意義について説いています。
### キーワード
- マイコンとは?
- 鳥人間としての電装の立ち位置は?
- Arduino IDE

## [QX電装講座 #2 Arduinoを使ってみた](https://qiita.com/GoshBird/items/078b19db33424d098b53)
Lチカ(LEDをチカチカさせる)をやって超基本的なことを勉強します。
###キーワード
- setup
- loop
- LED
- define
- コメントアウト
- pinMode
- digitalWrite
- delay
- ブレッドボード
- ピン配置
- コンパイル/実行
- 停止方法
- 動作手順

##[電装講座 #3 センサー使ってみた](https://qiita.com/GoshBird/items/1c0ad004c7150d83f9b7)
照度センサを用いてセンサーの使い方、C言語的な条件分岐を行いました。
###キーワード
- if
- else
- データ型
    - int
    - double
    - long
- const
- Serial通信
    - Serial.begin
    - Serial.print
    - Serial.plintln
- コメントアウトの裏技

##[電装講座 #4(最終回?) サーボモーター使ってみた](https://qiita.com/GoshBird/items/994e091fda673baed806)
サーボモータを使えるようになりました。
###キーワード
- サーボモータ
- バックラッシュ
- Servo
    - .attach
    - .write
- 可変抵抗器

必要なものがあれば、これからも追加していく予定ではありますが、とりあえず今回で締めです。
pythonでMecabを使うときに品詞指定して分かち書きを楽にするクラスを書いた

mecabをpythonで使っていると品詞を指定して自由に分かち書きしたいときに色々と書き換えなきゃなので、その不便さを解消するために自前でクラスを書いたので公開します。

```python
import MeCab
import unicodedata
import re


class MecabParser():
    def __init__(self, word_classes=None, word_class_details=None):
        """
        Args:
            word_classes (list, optional): 日本語で品詞指定. Defaults to None.
            word_class_details (list, optional): 品詞の詳細の指定. Defaults to None.

        mecabの定義する品詞は以下参照
        https://taku910.github.io/mecab/posid.html
        """
        self._word_classes = word_classes
        self._word_class_details = word_class_details

    def _format_text(self, text):
        """
        MeCabに入れる前のテキストの整形
        """
        text = re.sub(r'http(s)?://[\w/:%#\$&\?\(\)~\.=\+\-…]+', "", text)
        text = re.sub(r'[ -/:-@\[-~_]', "", text)  # 半角記号
        text = re.sub(r'[︰-＠]', "", text)  # 全角記号
        text = re.sub(r'\d', "", text)  # 数字
        text = re.sub('\n', " ", text)  # 改行文字
        text = re.sub('\r', " ", text)  # 改行文字

        return text

    def parse(self, text, is_base=False):
        text = self._format_text(text)

        # 文字コード変換処理。変換しないと濁点と半濁点が分離する。
        text = unicodedata.normalize('NFC', text)

        result = []
        tagger = MeCab.Tagger(
            '-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
        # parseToNode前に一度parseしておくとsurfaceの読み取りエラーを回避できる
        tagger.parse('')

        nodes = tagger.parseToNode(text)
        while nodes:
            wclass = nodes.feature.split(',')
            # 品詞指定のない場合はすべて分かち書き
            if not self._word_classes:
                result.append(wclass[6] if is_base else nodes.surface)
                nodes = nodes.next
                continue

            # 品詞詳細の指定の無い場合はその品詞をすべて分かち書き
            if not self._word_class_details:
                if wclass[0] in self._word_classes:
                    result.append(wclass[6] if is_base else nodes.surface)
                    nodes = nodes.next
                    continue

            # 品詞詳細指定に従って分かち書き
            if wclass[0] in self._word_classes and wclass[1] in self._word_class_details:
                result.append(wclass[6] if is_base else nodes.surface)
            nodes = nodes.next

        # 最初と最後の空白文字列の削除
        if len(result) > 0:
            result.pop(0)
            result.pop(-1)

        return result
```

自分はこれを `parser.py` というファイルに保存して使っています。
使用感は以下のような感じで、割と簡単に品詞指定で単語の分かち書きができるようになっています。

```
>>> from parser import MecabParser
>>> mp =  MecabParser(word_classes=['名詞'], word_class_details=['一般','固有名詞'])
>>> text = '今日はお腹が空いたので近所の天下一品のラーメンを食べに来ました。'
>>> mp.parse(text)
['お腹', '近所', '天下一品', 'ラーメン']
```

辞書は mecab-ipadic-neologd を使っていたり、語尾の変化した単語は原形に直してたり、事前にテキストの整形をしてたりするので、そこは使う人がお好みに改造していただければと思います。
Rails アソシエーション関連のエラー（ActiveRecord::HasManyThroughOrderError）


#該当のエラー
ActiveRecord::HasManyThroughOrderError 

Cannot have a has_many :through association 'Group#employees' which goes through 'Group#group_employees' before the through association is defined.

#実現したいこと　
社員は複数のグループに所属できて、
グループは複数の社員を持っているという風に結びつけたい。
グループに所属している社員。つまり@group.employeesを
実現したい。

#原因

エラーメッセージにある通り
HasManyThroughOrderError
文字通りの順番（Order）が原因らしい

```rb:Groupモデル
class Group < ApplicationRecord  
  has_many :group_employees
  has_many :employees, through: :group_employees
end

```

と、中間クラスとのアソシエーションを定義するコードを、先に書かないと今回のようになる。
#参考
https://qiita.com/krppppp/items/0db4184e9df553f05048
arachniのやり方

# arachniについて
http://www.arachni-scanner.com/

# インストール
ダウンロードして解凍するだけです。

# 実行環境の準備
- 数時間はほったらかしにする必要がありますので。独立した環境でやったほうがいいです。
- メール送信されないようにmailhogみたいにするか、プログラムを修正してください。
- Laravelなどフレームワークのデバッグモードをoffにしてください。
- やればわかりますが、フォームの選択肢が多かったり、ページ数が多いとその分時間がかかります。マスタデータや記事データなどを減らしてください。１〜２個で十分です。
- 外部サイトへの接続をしないようにしてください。proxy用でfile_get_contentsしている部分など

# 実行
コマンドラインもしくは、WebUIから起動します。
コマンドラインが簡単です。
コマンドオプションについては以下
https://github.com/Arachni/arachni/wiki/Command-line-user-interface

## 基本
`bin/arachni https://example.com/`
URLを指定するだけです。
localhostでは動きませんので、IPや適当なドメインで動くようにしてください。

## 推奨オプション
デフォルトではいろいろと無駄なチェックが走りますので、下記のオプションを付けると良いです。
`bin/arachni https://example.com/ --scope-exclude-pattern=tel: --scope-exclude-pattern=mailto: --platforms=linux,mysql,php,apache`

## 指定URLだけチェック
`--scope-include-pattern=campaigns`
を使う

## 同時接続数の調整
`--http-request-concurrency=5` 
テスト環境のスペックが低い場合は同時接続数を調整しないと途中でテストサイトが落ちる可能性があります。
また、Wordpressの場合重いので同時接続数を3くらいにしたほうが良いです。

## ログインが必要なページのチェック
例：
`bin/arachni https://example.com/ --plugin=autologin:url=https://example.com/users/login,parameters="id=xxxx&password=xxxx",check="ログアウト" --scope-exclude-pattern=logout`
説明：
- `--plugin=autologin`
autologinプラグインを使います。
- `:url=https://example.com/users/login`
ログインページ（ID・PW入力フォームがあるページ）のURL
- `,parameters="id=xxxx&password=xxxx"`
IDとパスワード
- `,check="ログアウト"`
ログインが成功した後の確認用文字列。ログイン後のページにしかない文字列を指定するとそれがあるかどうかでログインできたかを判断します。
- `--scope-exclude-pattern=logout`
ログアウトしないようにログアウトリンクURLを除外しましょう。

※cakephpでうまくログインできない場合がありました。その場合はプログラムを修正してログイン状態にするなどしてください。（正確に言うとログインしてもすぐセッションが切れてログアウトしてしまう状態になった。）

# 実行を中断する場合
フォアグラウンドの場合、普通にCtrl+cで終了できます。その際にそこまでのレポートも作成されます。
バックグラウンドの場合、普通にkillするとレポートが作成されないので、
`kill -INT 8341`
オプションを付けてください。

# おすすめの流れ
- まずはxssだけチェックしてみます。
`bin/arachni https://example.com/ --scope-exclude-pattern=tel: --scope-exclude-pattern=mailto: --platforms=linux,mysql,php,apache --checks=xss`
- サイト規模にもよりますが、２〜３時間で終わるようなら全体チェックをしても大丈夫です。xssを除外する場合は
`--checks=*,-xss`
- いつまでたっても終わらない場合は途中で止めてレポートのSitemapを確認してください。1回で全部のページをやろうとせずに、複数回に分けてやったりしてください。
GoでMockを用いてテストする方法

# はじめに

最近GoでMockを用いてテストを行うことが多いのですが，その手法がシンプルで使いやすいので紹介したいと思います．

# 実装

今回はDBからユーザーを全件取得して，指定したユーザーの年齢以上のユーザーのみを抜き取るという処理に対するテストを考えます．(そんなことはDB側で処理すればいいですが，いい例が思いつかなかったので悪しからず)
まずはUserのModel定義をします

```go:user.go
type User struct {
	ID   int
	Name string
	Age  int
}
```

次にDBに関する実装を行いますが，interfaceとその具体実装の2つに分けて書きます．

```go:user_db.go
type UserDB interface {
	GetAllUsers() ([]User, error)
}

type UserDBImpl struct {
}

func (db *UserDBImpl) GetAllUsers() ([]User, error) {
	// 全Userを返す処理
}
```

ここでUserDBはinterfaceで，UserDBImplはその具体的な実装をする構造体となっています．今回は全てのユーザーを取得する関数であるGetAllUsersをUserDBImplのレシーバとして定義しています．本番のサービスで用いる実際のコード(ORMを用いて実際のデータを取得してくるなど)はこのGetAllUsersに定義します．
次に，このUserDBを用いて年齢によってユーザーを絞り込む処理を実装します．

```go:user_handler.go
type UserHandler struct {
	DB UserDB
}

func (handler *UserHandler) FilterUsers(age int) ([]User, error) {
	allUsers, err := handler.DB.GetAllUsers()
	if err != nil {
		return []User{}, err
	}

	filteredUsers := []User{}
	for _, user := range allUsers {
		if user.Age >= age {
			filteredUsers = append(filteredUsers, user)
		}
	}

	return filteredUsers, nil
}

```
そんなに難しい処理は書いていないので詳細は省きますが，　重要な部分はUserHandlerがinterfaceである`UserDB` をフィールドに持っている点です．これによってUserHandlerのDBにはUserDBで実装しているメソッドと同じメソッドを実装している構造体をなんでも入れることができるようになります(UserDBImplもその1つ)．

最後に，このFilterUsersに関するテストを書いていくことにします．

```go:user_handler_test.go
import (
	"reflect"
	"testing"
)

type UserDBImplMock struct {
}

func (db *UserDBImplMock) GetAllUsers() ([]User, error) {
	users := []User{
		User{
			ID:   1,
			Name: "user1",
			Age:  10,
		},
		User{
			ID:   2,
			Name: "user2",
			Age:  25,
		},
		User{
			ID:   3,
			Name: "user3",
			Age:  16,
		},
		User{
			ID:   4,
			Name: "user4",
			Age:  33,
		},
		User{
			ID:   5,
			Name: "user5",
			Age:  18,
		},
	}

	return users, nil
}

func TestFilterUsers(t *testing.T) {
	mock := UserDBImplMock{}
	handler := UserHandler{&mock}
	input := 20
	expect := []User{
		User{
			ID:   2,
			Name: "user2",
			Age:  25,
		},
		User{
			ID:   4,
			Name: "user4",
			Age:  33,
		},
	}
	output, err := handler.FilterUsers(input)

	if err != nil {
		t.Error(err.Error())
	}

	if !reflect.DeepEqual(&output, &expect) {
		t.Errorf("output: %+v \n expect: %+v", output, expect)
	}
}
```

UserDBImplMockはUserDBのメソッドを実装したもので，こちらで実装するメソッドでは名前の通りMockデータを返すようにします．実際，GetAllUsersでは**DBから取得されると期待されるデータ**を定義し，それを返すようにしています．
実際にテストしたいメソッドである`TestFilterUsers`では，はじめにUserDBImplMockを用いてUserHandlerを初期化しています．これがUserHandlerがinterfaceをフィールドに持っていることの良い点で，これにより実際のDBを考えずともMockデータでテストができるようになるわけです．

# さいごに

Goではinterfaceに関してプログラミングを行うことで非常に簡単にMockによるtestを行うことができます．サービスのアーキテクチャによっては重宝するかと思うので，ぜひ試してみてください．
エンジニアに必要な、有名オープンソースソフトウェアライセンス（OSS License）早見表

# なぜ書いたか
IT業界と関わっていくならば、エンジニアだけでなくOSS Licenseの知識は必要不可欠となります。
**よくわからないから商用ライセンスを利用する** という判断は勿体ないし、サイト毎に意見が乱立してて答えがよくわからないので自分用のメモとしてもこちらに表を用意しました。

# OSS License比較表
***2019年11月8日時点（以降の場合、変わっている可能性があります。）***

念の為ですが、 **開示のタイミングは、頒布時** です。

|License|改変ソースの開示|静的リンクでソース開示|動的リンクでソース開示|Webサービスでソースの開示|別のライセンスを課す|特許|使用権|
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|[LGPLv2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)|:heavy_check_mark:|:heavy_check_mark:|||:x:|||
|[GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:||:x:|||
|[GPLv3](https://www.gnu.org/licenses/gpl-3.0.html)|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:||:x:|:x:|||
|[AGPL](https://www.gnu.org/licenses/agpl-3.0.html)|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:x:|||
|[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)|||||:heavy_check_mark:||:heavy_check_mark:|
|BSD|||||:heavy_check_mark:|||
|[MIT](https://opensource.org/licenses/MIT)|||||:heavy_check_mark:|||

# BSD内の比較表
ちなみに、各ライセンスの数値は、バージョンではなく、「条項」のことである。

|License|宣伝必須|GPLとの両立|
|:--:|:--:|:--:|
|[BSD-4-Clause（旧）](https://www.gnu.org/licenses/license-list.html#OriginalBSD)|:heavy_check_mark:|:x:|
|[BSD-3-Clause（修正）](https://www.gnu.org/licenses/license-list.html#ModifiedBSD)|:x: （要許可）||
|[BSD-2-Clause(Free)](https://www.gnu.org/licenses/license-list.html#FreeBSD)|||

# GPLの余談
https://www.gnu.org/licenses/gpl-faq.ja.html これを読めば事足りますが、割と迷うところについて書きます。

## プロプライエタリ・ソフトウェアとして提供する
もし、それを提供するならば、LGPLを動的リンクで利用するか、デュアルライセンスのソフトウェアを探し商用ライセンスを利用することです。

### MySQLを組み込む
https://www.mysql.com/jp/about/legal/licensing/oem/
商用ライセンスを選択しないと、頒布時にGPLでソースコードの公開義務が発生します。

### WordPressのプラグインやテーマ
厳密には拡張したPHPのみGPLライセンスにするスプリットライセンスの形を取ることができますが、100%GPLをWP創始者がお願いしています。すなわち、プラグインやテーマによってライセンスがバラバラですので、確認した上で利用しましょう。
https://ja.wordpress.org/about/license/100-percent-gpl/

## 派生物について
ソースの改訂だけでなく、静的リンク、動的リンクも含みます。LGPLライセンスの場合、動的リンクはLGPLライセンスにする必要ないです。

## Webサービスについて
Webサービスとして利用する場合、頒布とはみなされません。
プロプライエタリ・ソフトウェアではないので、自分でサービスとか作っている人もGPLライセンスだからソースコード全部開示しなくちゃいけないの？って心配は無用です。
ただし、AGPLは、ネットワークを介して提供する場合もソースコードの公開義務が発生します。どちらかというと、このライセンスはクラウドプロバイダのSaaSなどをカバーするために生まれました。比較表に追加しました。

# Apache-2.0の使用権
例えば、会社AがApache-2.0ライセンスで作られたソフトウェアが含まれる要件で特許を取ったとしても、会社Bが会社Aの特許要件に含まれるApache-2.0ライセンスのソフトウェアを権利侵害にならずに使うことができます。要は、特許を取られていても、Apache-2.0ならとりあえず安心だろう、と考えても良いでしょう。とりあえずというのは、世の中には特許トロールがいるので100%とは言い切れないからです。

# その他のライセンスについて
割愛します。要望があれば追加するかもしれません。

# この記事のライセンス
こちら文書ではありますが、MITライセンスと同様でお願いします。
なので、間違っていたら教えていただけると助かります。
Bech32の脆弱性

# はじめに

Bech32の脆弱性が発見されました。

私はメーリングリストで知りましたが、Bech32のissueで指摘されたようです。

* [bitcoin-dev]メーリングリスト<br>https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-November/017443.html

* Githubのissue<br>https://github.com/sipa/bech32/issues/51


# Bech32とは

Bitcoinのアドレスは、Base58Checkを使用していましたが、使いづらい部分を修正する為に考案された「汎用的なアドレスフォーマット」です。

以前、[BC2](https://bc-2.jp/season2/)で私が使用した資料があるので、参照ください。

https://bc-2.jp/materials/0105_Bech32.pdf

# 脆弱性

末尾が`p`である場合、その直前に`q`を入れてもエラーとならずにデコードされてしまうという問題です。

リファレンスコードで検証してみました。

```python:検証コード
hrp = "te"
data = [25]
str = bech32_encode(hrp, data)
print(hrp, data, '-->', str)

hrp, data = bech32_decode(str)
print(str, '-->', hrp, data)

str = 'te1eacsl9qp'
hrp, data = bech32_decode(str)
print(str, '-->', hrp, data)
```

検証コード結果です。

```text
te [25] --> te1eacsl9p
te1eacsl9p --> te [25]
te1eacsl9qp --> te [25, 29]
```

デコードがエラーとなるべきなのですが、なりません。

`te1eacslq9p`と`9`の前に`q`をいれると、エラーとなります。

検証コードを[Google Colaboratory](https://colab.research.google.com/github/tnakagawa/ipynb/blob/master/Bech32_weakness.ipynb)+[Github](https://github.com/tnakagawa/ipynb/blob/master/Bech32_weakness.ipynb)で確認できるようにしました。

---

**※ 2019/11/11 追記**

issueにあるBech32の文字列`ii2134hk2xmat79tp`を見てみます。
<font color=blue>ii2</font><font color=deeppink>1</font><font color=darkorange>34hk2xm</font><font color=magenta>at79tp</font>
<font color=blue>青字(ii2)は、ヒューマンリーダブルパート</font>
<font color=deeppink>ピンク(1)は、セパレータ</font>
<font color=darkorange>オレンジ(34hk2xm)は、データ</font>
<font color=magenta>紫(at79tp)は、チェックサム</font>

今回の問題は、チェックサムの末尾が`p`である場合となっています。
Bech32は、`qpzry9x8gf2tvdw0s3jn54khce6mua7l`の32文字を数値に当てはめるので、末尾が`p`という事は、`0x01`となります。

チェックサムは、データの正当性と誤り検出を行う為のものです。
演算していき最終的に`0x01`になれば、正確なデータと判断する仕組みになっています。
演算を簡単に説明すると、5bit(10進数で0~31）毎に`XOR`でチェックする仕組みです。
（※：演算内容は複雑なので、コードなどを参照してください。）
チェックサムの末尾が`p`、つまり`0x01`となる為、直前のチェックデータが`0x00`となっている必要があります。
この状態で、`q`すなわち'0x00'を`XOR`してもチェックデータが変わらない為、エラーとなりません。

`q`を追加すると、データにチェックサムのデータが追加されていきます。（最後の`0x01`は含まない）
チェックサムのデータを全部排出したあとは`0x00`が追加されていきます。

```text
ii2134hk2xmat79tp         --> ii2 [17, 21, 23, 22, 10, 6, 27]
ii2134hk2xmat79tqp        --> ii2 [17, 21, 23, 22, 10, 6, 27, 29]
ii2134hk2xmat79tqqp       --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11]
ii2134hk2xmat79tqqqp      --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11, 30]
ii2134hk2xmat79tqqqqp     --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11, 30, 5]
ii2134hk2xmat79tqqqqqp    --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11, 30, 5, 11]
ii2134hk2xmat79tqqqqqqp   --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11, 30, 5, 11, 0]
ii2134hk2xmat79tqqqqqqqp  --> ii2 [17, 21, 23, 22, 10, 6, 27, 29, 11, 30, 5, 11, 0, 0]
```

---

# さいごに

今、Bitcoinが採用している箇所については、バイト長チェックが入るので、アドレスチェックで弾かれます。
現在Bitcoinで盛り上がっている、Taprootで採用する予定となっており、問題となりそうです。
そのTaprootが採用されるタイミングか、その前に修正される模様です。

私は、Go言語のリファレンスを書いたんですが、全く気付かなかったorz
申し訳ない・・・
MacにDockerでGolang環境を作ってみる  vol.1 Dockerインストール編

DockerもGolangも初心者ですが、とりあえずDockerでGolangを使ってみようと思います。
とりあえず、動かすための環境を作ります。
参考までに環境情報を。

<ul>
<li>macOS Mojave(10.14.6)</li>
</ul>

##　１　Dockerのインストール
　Docker for Mac は、以下のURLからGUIでもインストールできます。
　
　でも、~~ちょっとめんどくさいので~~CUIでやってみたいので、CUIで入れてみます。

　ターミナルで以下のコマンド実行。
###　　１.１　Homebrew Cask の確認
　　　Homebrew Cask は Homebrew の拡張機能だそうです。
　　　まずはこれが入っているかの確認。

```
　　　　$ brew cask
```

　　　brew cask はGUIでダウンロードするような（chromeとか）を
　　　CUIで入れられるみたい。
　　　
　　　※詳しくはこちら参照
　　　https://qiita.com/swallowtail62/items/61244ea3c7d00f692823

###　　１.２　Docker for Mac のインストール

```
　　　　$ brew install docker
　　　　$ brew cask install docker    
```

　　　ちゃんとインストールできたか、確認するために、
　　　以下のコマンドでバージョンを調べます。

```
　　　　$ docker --version  
　　　　Docker version 19.03.4, build 9013bf5
```

---

そんなこんなで、無事インストールできた模様です。


# 2. Dockerの起動
　　参考記事によると、このままではインストールされただけみたいです。
　　いざ、使いたい！となると起動しないと、デスヨネ。

###　アプリ起動
　　アプリケーション＞Docker を探してぽちします。
<img width="760" alt="スクリーンショット 2019-11-08 14.11.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/79132331-8a0b-bcc7-323c-6d67d05f940d.png">

　※もちろん、CUIからでも起動できます。その場合は以下のコマンドを叩いてください。

```
　　　　$ open /Applications/Docker.app
```

###　アカウント作成　
　　　デスクトップの右上にこんなアイコンと表示が出てきます。
　　　下の方のリンクをぽちします。

<img width="819" alt="スクリーンショット 2019-11-08 14.33.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/45c9849f-a07e-0967-099f-d7fc36716ff3.png">

　　　ブラウザで別画面が開くので「SignUP」からアカウント作成してください。
　　　作成できたらまた上記の画面に戻って、ログイン情報を入力します。

<img width="737" alt="スクリーンショット 2019-11-08 16.06.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/6ae867b2-b5d7-dead-01c8-3db296cb04ed.png">

　　　で、こんな画面になったらOK。
　　　画面右上にこんな感じで、起動していることが表示されました！

<img width="669" alt="スクリーンショット 2019-11-08 16.08.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/461243be-c37f-3c86-ceed-15fee2d402f3.png">


　　　次はGolangを動かせるようにします！（多分）
　　　やりながら書いてるのでぼちぼちで。

## 参考
https://qiita.com/nemui_/items/ed753f6b2eb9960845f7
CentOS/RHELにENIを追加した際のネットワーク設定

CentOS/RHEL on EC2でENIを追加した時はそれぞれのNICに対してルーティング設定をしてあげる必要があります。

ENIの追加やIPの払い出し、EC2へのアタッチは以下のように済んでいる状態です。

| 名称      |     プライベートアドレス |    EIP    |
|:-----------------|:------------------|:------------------|
| Gateway        | 172.16.1.1/24  |  |
| ens5           | 172.16.1.10/24 | x.x.x.x|
| ens5:1         | 172.16.1.11/24 | y.y.y.y|
| ens6           | 172.16.1.20/24 | z.z.z.z|

ens5もens6も同じVPCに所属しています。


# NICの設定
ens6のDEFROUTEはnoにしないと、サーバから出て行くデフォルトのNICがens6となります。（最後にifupしたNICがデフォルトになるため）

```
vi /etc/sysconfig/network-scripts/ifcfg-ens5
-----
BOOTPROTO=dhcp
DEVICE=ens5
HWADDR=0a:25:b5:xx:yy:zz
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
GATEWAY=172.16.1.1
----

vi /etc/sysconfig/network-scripts/ifcfg-ens5:1
----
DEVICE="ens5:1"
IPADDR="172.16.1.11"
NETMASK="255.255.255.0"
----

vi /etc/sysconfig/network-scripts/ifcfg-ens6
----
BOOTPROTO=dhcp
DEVICE=ens6
HWADDR=0a:76:29:xx:yy:zz
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
DEFROUTE=no
----

```


# テーブル作成

各NIC用にテーブルを追加します。

```
vi /etc/iproute2/rt_tables
-----
100 t1
101 t2
----
```


# ルーティング設定

各NICに対してルーティングの設定をします。

```

vi /etc/sysconfig/network-scripts/route-ens5
----
# route-ens5
172.16.0.0/16 dev ens5 src 172.16.1.10 table t1
default via 172.16.1.1 dev ens5 table t1
----

vi /etc/sysconfig/network-scripts/route-ens5:1
----
# route-ens5:1
172.16.0.0/16 dev ens5:1 src 172.16.1.11 table t1
----

vi /etc/sysconfig/network-scripts/route-ens6
----
# route-ens6
172.16.0.0/16 dev ens6 src 172.16.1.20 table t2
default via 172.16.1.1 dev ens6 table t2
----

vi /etc/sysconfig/network-scripts/rule-ens5
----
# rule-ens5
table t1 from 172.16.1.10
----

vi /etc/sysconfig/network-scripts/rule-ens5:1
----
# rule-ens5:1
table t1 from 172.16.1.11
----

vi /etc/sysconfig/network-scripts/rule-ens6
----
# rule-ens6
table t2 from 172.16.1.20
----

```

# ARP関連の設定

kernelのパラメーターを修正します。

```

vi /etc/sysctl.conf
----
net.ipv4.conf.all.arp_filter = 1
net.ipv4.conf.default.arp_filter = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_announce = 2
----

```

# 反映

設定を反映させるためにOSの再起動をします。

```
reboot
```


# 確認

自分のPC等から外部からEC2への疎通確認を行います。

```
ping x.x.x.x
ping y.y.y.y
ping z.z.z.z
```

EC2から外部への疎通確認を行います。
※ping -I を使った確認だとうまくできないようなので、telnetでソースIPを指定して確認します。
参考 https://access.redhat.com/solutions/30564

```
telnet -b 172.16.1.10 外部のWEBサーバ 80
telnet -b 172.16.1.11 外部のWEBサーバ 80
telnet -b 172.16.1.20 外部のWEBサーバ 80
```
[BluePrism] 通常のスパイモードで取得できない要素を取得する(Webアプリ)

はじめに
---------

Salesforce の 「Lightning Experience」 など、割とあたらしい目のWebページで、 BluePrism を使ったスパイが上手くいかず、自動化につまずくことがあります。その際には、「UIオートメーションナビゲーター」を使うと上手くいくことがあるよ、という内容です。

通常のスパイでは上手くいかない例
---------------------------

社内にてSalseforceをBluePrismを自動化しようとした時のことです。
下画にて必須である取引先名を入力し保存ボタンを押すというフローを作成しましたが・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/58fedb0f-b882-471f-4f0b-a343209455aa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/b8a10c5c-64c3-a79b-b78c-e5f5c181d7f1.png)


実行してみると、画面表示上はデータが入力がされているように見えますが、保存ボタンを押すと、「取引先名が入力されていない」 というエラーとなってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/5d232555-0b89-ab63-8b02-499fbf7e2391.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/c48e9152-9e5b-3c3c-3488-6c03324e0c6c.png)

この取引先名はスパイモードで取得しましたが、これでは正しい要素は取得できないようです。
（実際にデータを POST するためのフォーム要素を特定できていない）

UIオートメーションナビゲーターを使ったスパイ
------------------------------------

そこで、UIオートメーションナビゲーターを使ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/77a57a33-3df0-d2a5-7acd-d3b3849f3e13.png)


これを使うと、非表示の要素を含め、ページ上の要素を全て取得することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/8e436eea-6928-8a4d-d559-f31238e208af.png)

要素 「取引先名*（編集）」 をスパイし、再度実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528676/168cf189-0933-da80-b1ff-22aa0be9e08c.png)


正しく登録できました！

まとめ
----------------
スパイモードで正常に動作しない場合はUIオートメーションナビゲーターを使ってみましょう。
#Rails マイグレーションで on_delete: :nullify を指定して、 DB に ON DELETE SET NULL の外部キー制約を追加する

# 例

```rb
class CreateBook < ActiveRecord::Migration[5.2]
  def change
    create_table :book do |t|
      t.references :user, foreign_key: { on_delete: :nullify }
    end

    # あとから追加する場合は多分こう
    # add_foreign_key "books", "users", on_update: :nullify
  end
end

```

# ON DELETE SET NULL とは

- 親のレコード = user が削除された時に、子が持っている親のID = user_id が null に更新される
- 親のレコード = user が削除された時に、子のレコード = book は削除されない


# 参考

[外部キー制約について - Qiita](https://qiita.com/SLEAZOIDS/items/d6fb9c2d131c3fdd1387)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2681








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
EC2インスタンスをCLIで素早く起動＆停止するには

AWS CLIでEC2インスタンスを起動するには `aws ec2 start-instances --instance-ids i-XXXXX` とします。

```
$ aws ec2 start-instances --instance-ids i-XXXXX
```
```
{
    "StartingInstances": [
        {
            "CurrentState": {
                "Code": 16,
                "Name": "pending"
            },
            "InstanceId": "i-XXXXX",
            "PreviousState": {
                "Code": 16,
                "Name": "stopped"
            }
        }
    ]
}
```

ただ、これだと「起動する命令を送った」だけなので、正しく起動が完了したことや、割り当てられたIPアドレスなどが分かりません。

そこで次のように、起動命令->起動待ち->インスタンス情報を表示。というのを順番に実行します。これで起動したインスタンスのグローバルIPアドレスなどをすぐに確認することができます。

```
$ aws ec2 start-instances --instance-ids i-XXXXX \
&& aws ec2 wait instance-running --instance-ids i-XXXXX; \
aws ec2 describe-instances --instance-ids i-XXXXX \
| jq '.Reservations[].Instances[] | \
{InstanceId, InstanceState: .State.Name, PublicDnsName, PublicIpAddress}'
```
```
{
    "StartingInstances": [
        {
            "CurrentState": {
                "Code": 16,
                "Name": "stopping"
            },
            "InstanceId": "i-XXXXX",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
{
  "InstanceId": "i-XXXXX",
  "InstanceState": "running",
  "PublicDnsName": "ec2-99-99-99-99.ap-northeast-1.compute.amazonaws.com",
  "PublicIpAddress": "99.99.99.99"
}
```

次に停止です。EC2インスタンスを停止するには `aws ec2 stop-instances --instance-ids i-XXXXX` とします。

```
$ aws ec2 stop-instances --instance-ids i-XXXXX
```
```
{
    "StoppingInstances": [
        {
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "InstanceId": "i-XXXXX",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
```

これも停止命令を送るだけなので、これだけだと実際に止まったことが確認できません。止めたつもりなのに止まってないと結構辛いので、これも停止待ちを入れてみます。

```
$ aws ec2 stop-instances --instance-ids i-XXXXX \
&& aws ec2 wait instance-stopped --instance-ids i-XXXXX; \
aws ec2 describe-instances --instance-ids i-XXXXX \
| jq '.Reservations[].Instances[] | {InstanceId, InstanceState: .State.Name}'
```
```
{
    "StoppingInstances": [
        {
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "InstanceId": "i-XXXXX",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
{
  "InstanceId": "i-XXXXX",
  "InstanceState": "stopped"
}
```

これで確実に止まったことが確認できます。

コマンドが長いのでALIASにしておくと便利だと思います。
OIDC Self-Issued OP (SIOP) とは

OpenID Connect Self-issued OP は自己署名 ID トークンを発行する、ユーザ個人の自己 OpenID プロバイダ。

ユーザが利用する端末やブラウザ上で動作し、自己署名 ID トークンを発行することで、

* SIOP が動作する端末の識別 (端末認証)
* 安全な端末情報の受け渡し (改ざん検出)

を実現する。

仕様👉http://openid.net/specs/openid-connect-core-1_0.html#SelfIssued

ユーザの端末でユニークな鍵ペアを生成・保存・管理する。ID トークンに公開鍵が含まれているので、改ざんされていないかを検証できる。
また、公開鍵のハッシュのようなものを識別子として扱うので、SIOP が動作する端末やブラウザの識別ができる。

SIOP の場合、ユーザの端末やブラウザが認証サーバ・リソースサーバとなり、Web アプリなどのバックエンドサーバがクライアントとなる。

## フロー
Implicit Flow と同様のフロー。
認可リクエストを受けたら、自己署名された ID トークンを返す。

なお、事前に鍵ペアの生成とバックエンドサーバへの公開鍵の登録が行われている。

1. ユーザがネイティブアプリ (SIOP) を開く
2. アプリがバックエンドサーバにアクセスする
3. バックエンドサーバはアプリに認可リクエストを送る
4. アプリはユーザを認証する
5. アプリは ID トークンを発行し、署名する
6. アプリからバックエンドサーバに ID トークンを送る
7. バックエンドサーバは ID トークンを検証し、ID トークンに含まれる情報を取得する

## ID トークン
* iss (発行者) は https://self-issued.me
* sub (識別子) は公開鍵のハッシュ値を Base64 エンコードしたもの
* sub_jwk は署名検証に用いる公開鍵情報

## 認可リクエスト
* URL はカスタム URL スキーマ (`openid://`)
	* ネイティブアプリからネイティブアプリへ認可リクエストを送ることもできる
* reaponse_type は id_token
	* 認可エンドポイントで ID トークンを発行
	* トークンエンドポイントは使用しない
* client_id は URL 形式
	* この URL のフラグメントに ID トークンが付加される。静的/動的なクライアント登録ができないため

## 認可レスポンス
* Implicit Flow と同様

## 事例
[OpenID Connect Self-Issued IdPを応用したSingle Sign Onの実装](https://speakerdeck.com/rtechkouhou/openid-connect-self-issued-idpwoying-yong-sitasingle-sign-onfalseshi-zhuang)

キラーアプリを SIOP にして、他アプリは SIOP に認証をリクエストすることでシングルサインオンを実現。

## Next
* FIDO UAF との比較

## 参考
- [OpenID Connect Self-issued OP概要 ~OpenID Technight #15より~ - Qiita](https://qiita.com/samiii/items/93b56c6061cfbb6653ec)
- [OpenID ConnectのSelf-Issued OPの話](https://ritou.hatenablog.com/entry/20130718/1374107391)
C#7以降でお手軽に多重ループを抜ける

C#7以降でお手軽に多重ループを抜ける方法です。
C#ではgotoを除けば多重ループを抜ける構文がなく、フラグ用変数を使用するか、該当部分を関数化するして対応してきました。
わざわざ関数化するにしても煩わしさを感じていたわけですが、ローカル関数を使用するとお気楽に多重ループを抜けることが出来ます。

``` C#
private void function() 
{
     int counter = 0;
     // do something here

     // 多重ループをローカル関数で囲う
     void DoIt()
     {
        while(true)
        {
            while(true)
            {
                // ローカル変数をそのまま参照できる！
                counter++;
                // Return文でローカル巻子を抜ける ＝ 多重ループを抜ける
                if(counter >= 10) return;
            }
        }
    }
    // ローカル関数を実行
    DoIt();
    // do some other things here
    // 結果
    Console.WriteLine($"counter={counter}");
}

```
このように徒然なるまま書いたコードに数行足すだけで簡単に
多重ループを抜けることが出来ました。

ローカル関数を定義しただけで実行文を書くのを忘れたりするので注意。
JavaScriptのように関数の即時実行が出来たらいいんですが。

以上、スタジオへお返しします。
accessファイルを開いた瞬間にエラーになるときの対処方法



エラー詳細は

　障害モジュールの名前:	VBE7.DLL

とかのとき、下記で解決した。

```
hogehogehoge.accdb /decompile
```

いやー、焦った、焦った。

参考サイト
http://blog.livedoor.jp/tea_cocoa_cake/archives/6423808.html