セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

git rebaseのお勉強

読んだもの

このページは図解もわかりやすいし、状況も似ていたので、ありがたかった。しかし、最後のrebase -iでコミットをまとめてしまうのは、後で見返す際に良い影響があるとは思えないので微妙だと感じた。
git rebaseを初めて使った際のまとめ - Qiita

ちょっとわかりにくいけど、便利さは伝わってきた。公開リポジトリrebaseご法度なのを理解できた。rebaseを行うのはローカルの自分しか触っていない部分のみに絞る。 Git - リベース

状況

あまり理想的な状況ではなかったけれど、masterから派生したb1ブランチがあり、b1のプルリクを投げてレビュー待ちの間(ここでかなり待たされる状況)、b1の最終コミットからb2ブランチを伸ばし、作業を進めた。最終的にどちらのチェックも通った時、この二つをどうマージして行こうかといった状況。せっかくなのでrebase使う勉強をしようかなと。
f:id:thinline196:20181205010244p:plain

結果

  1. b1masterに普通にマージ
  2. b2の派生元をmasterに変更(git rebase master (#b2ブランチ上で実行)) (コンフリクトの可能性あり& ここで解消)
 $ git fetch origin
 $ git reset --hard origin/master(masterを最新の先頭にする(ここはb2の派生元をmasterの最新にしたかったのでこの処理))
 $ git checkout b2
 $ git rebase master
  1. b2をリモートにプッシュ $ git push -f origin b2`
  2. b2masterにマージ or 作業続行

    今更

    今更こんなこと勉強しているの恥ずかしいです。以降使えるようになります。。。

NICTのポートスキャン来てた

すっかり忘れてました

他の人がハニポで観測しているのを見て思い出しました。

公式のお知らせ

公式からのお知らせによると、11月14日(水) に開始し、来年1月末までを目途に継続して行われるとのこと。その際使用されるIPアドレスは、210.150.186[.]238, 122.1.4[.]87, 122.1.4[.]88だそうです。 日本国内でインターネットに接続されたIoT機器等に関する事前調査の実施について | NICT-情報通信研究機構

210.150.186[.]238

f:id:thinline196:20181129001410p:plain f:id:thinline196:20181129001428p:plain

122.1.4[.]87

来てない!涙

122.1.4[.]88

来てない!涙

まとめ

結果的に今観測できていたのは210.150.186[.]238からのみ。スキャンを受けたポートは80(http), 81, 2222(ssh), 2223(telnet), 2323(Philips製のTV)の5種類。(22,23ポートはハニポの都合で2222,2223で受けている) 事前告知されていた22, 23, 80をはじめ、miraiで狙われているポートとして2323がスキャン対象になったと考えられる。81ってなんだっけ、、 (wikiだとTorだった) ASNは全てNTT PC Communications, Inc.となっていた。

rubyチュートリアル12章 メモ

隠しフィールド

form_forを利用したフォーム内に隠しフィールドを設定する。

<%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= hidden_field_tag :email, @user.email %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Update password", class: "btn btn-primary" %>
<% end %>

隠しフィールドの定義の仕方で値へのアクセス方法が変わる。hidden_field_tag :email, @user.emailとした場合、params[:email]でアクセスでき、f.hidden_field :email, @user.emailとした場合、params[:user][:email]となる。

時間の比較

checkpoint_at < 2.hours.ago

checkpoint_atはdatetime。< 記号を「〜より早い時刻」と読む。"checkpoint_atが現在時刻より2時間以上前 (早い) の場合"にはtrueとなる。個人的には2時間より先(<)(遠く)にチェックポイントの時間があると読むとしっくりくる。(遠近法で遠いと小さいみたいな)

errors.add

バリデーションに対するエラーを出力する方法として準備されている。 Active Record バリデーション | Rails ガイド
デフォルトでは下のような使い方をするが、チュートリアルでは予め決められた表示形式を利用する形を使った。

user.errors.add(:password, "は以下の文字を含むことができません !@#%*()_-+=")


バリデーション失敗時に上のコードを書いて再描画させることで間違いがあったフォームがハイライトされる。おそらく、name属性値から繫がりを調べてフォームを特定していると思われる。ちなみにform_withを用いて生成したフォームは下のhtmlに変換されて出力されいた。

<%=form_with model: @user, url:password_reset_path(params[:id]), local:true do |f|%>
...
 <%= f.password_field :password, class: "form-control"%>

#変換後
<input class="form-control" type="password" name="user[password]">


ruby チュートリアル11章 メモ

ActionMaier

Railsに標準で組み込まれている、メールを送信してくれる機能。text形式とhtml形式のテンプレートメールを生成する事ができ、宛先や件名含めコントローラから簡単に生成する事ができる。メイラーの生成は下のコマンド。後ろの二つは追加するメソッド名を指定している。

$ rails generate mailer UserMailer account_activation password_reset

実行すると、app/views/user_mailer/account_activation.text.erbapp/views/user_mailer/account_activation.html.erbの様に2つのテンプレートが生成される(password_reset)も同様。

アカウント有効化リンクの生成

#前回
edit_user_url(user)
#生成されるurl
http://www.example.com/users/1/edit

#今回
edit_account_activation_url(@user.activation_token, ...)
http://www.example.com/account_activations/q5lt38hQDc_959PVoo6b7A/edit

上の生成されたリンク内のトークンへeditアクション内ではparams[:id]でアクセスできる。

url内@エスケープ

上で生成したurlにメールアドレスも含める場合、@エスケープする必要があるが、これはメソッドが自動で行ってくれる。

edit_account_activation_url(@user.activation_token, email: @user.email)
#生成されるurl
account_activations/q5lt38hQDc_959PVoo6b7A/edit?email=foo%40example.com

editアクション内ではparams[:email]でアクセスできる。

RSpecでのmailerのテスト

RSpecを普通に入れいていれば、チュートリアルの説明と同じ形のテストファイルがRSpec内にも生成される。ので、同じ手順に沿って進めて問題ない。

メソッドの抽象化

チュートリアルではauthenticated?メソッドを例に挙げている。今まで実装していた、リメンバートークンを比較するメソッドは下。

# トークンがダイジェストと一致したらtrueを返す
def authenticated?(remember_token)
  return false if remember_digest.nil?
  BCrypt::Password.new(remember_digest).is_password?(remember_token)
end


これをsendメソッドを用いる事で、柔軟に変数へアクセス可能となる。文字列、シンボルを渡す事が可能。

def authenticated?(attribute, token)
  digest = self.send("#{attribute}_digest") #モデル内に定義されているのでselfは省略可能
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

form_with使用時のエラー表示

下のサイトに書いてありますが、form_withを使用するとデフォルトではvalidation時のエラーが表示されない様です。local:trueにする事で、解決します。

    <%=form_with scope: :session, url:login_path,local: true do |f|%>

Rails 5.1のform_withでViewにvalidationエラー表示 - Qiita

アカウント有効化のフィーチャーテスト

チュートリアルでは、ユーザがサインアップしてから有効化のリンクを踏んでログインできるまでをまとめてテストしている。rspecで再現するなら、capybaraを利用して行うが、capybaraがコントローラ内のインスタンス変数が取れないので、生成されたactivation_tokenを取得できず、有効化のリンクを生成できない。代わりの手法として、生成されたメールから正規表現でリンクを取得してみた。チュートリアル上のテストではメール自体のテストを網羅できていないので、フィーチャーテストとしてはむしろ良くなったようにも見えます。

activation_url = expect(ActionMailer:: Base.deliveries.last.body.encoded).to match("^http.*?#{CGI.escape(user.email)}")


他の案としては、コントローラテストで個別に書くとか(コントローラ内からならインスタンス変数にアクセスできる)

ruby チュートリアル10章 メモ

form_for(@user)の判定

form_forを利用すると自動で入力フォームとそのsubmit先の設定等を設定し表示できるようにしてくれる。一般にcreateアクションとeditアクション用のフォームは同じform_for(@user)で生成される。このアクションの違いは@user内のnew_record?論理値メソッドを使用して判定している。その結果trueならPOSTfalseならPATCHをリクエストに使用する。

$ rails console
>> User.new.new_record?
=> true
>> User.first.new_record?
=> false

認証と認可

認証(authentication)はユーザを識別すること、認可(authorization)はそのユーザが実行可能な操作を管理すること。

unless

if文がtrueの際の処理を書くなら、unless文はfalseの際の処理を記述する。

before_action

すでに定義されているアクション実行前に作動する。登録してあるユーザのみ実行させるなどの認証をここで指定できる。only:を使用すると指定したアクションでのみ、before_actionが作動するようになる。

リダイレクトの発生タイミング

チュートリアルでは下のようなコードが出る。これは別ページでセッションに移動先を保持させておいて、このメソッドを使用してリダイレクトを発生させる。(引数は無視) この場合、リダイレクトの発生タイミングは最終行のコードが実行されてからになる為、リダイレクトも発生するがセッション削除も行われる。リダイレクトの発生タイミングは最終行のコードの実行後か明示的にreturnを呼ばれた時になる。

#app/helpers/sessions_helper.rb
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end


request.get?

送られてきたリクエストがGETかどうか判定できる。チュートリアルでは下のように使用して、GETリクエストの時だけ、URLをセッションに退避させておき、必要になった時にリダイレクトで飛ばせるようにしている。UPDATEPATCH等が飛んできた時にそれを退避してしまわないよう、GETのみに絞っている。

#app/helpers/sessions_helper.rb
session[:forwarding_url] = request.original_url if request.get?


ページネーション(pagination)

ユーザ一覧を1ページにずらっと並べると見にくいので、それを10人ずつ表示したりすること。チュートリアルではgem 'will_paginate'を使用する。
導入後、下のように確認が可能。

 @users = User.paginate(page: params[:page])

デフォルトでは30人ずつ取り出され、pageはそのインデックス番号を指定。nilが届いた場合は、1ページ目が自動で指定される。


パーシャルの利用

下のコードはhtmlタグをパーシャルを利用して上手く表示する例。

#app/views/users/index.html.erb
#before
<ul class="users">
  <% @users.each do |user| %>
    <li>
  <%= gravatar_for user, size: 50 %>
  <%= link_to user.name, user %>
</li>
  <% end %>
</ul>

#after
<ul class="users">
  <% @users.each do |user| %>
    <%= render user %>
  <% end %>
</ul>

肝心のパーシャルの部分は、_user.html.erbファイルを自動で探しに行くのでそこに定義してやる。

<li>
  <%= gravatar_for user, size: 50 %>
  <%= link_to user.name, user %>
</li>


この時、下のようにすれば更にeachの部分も省略可能になる。

<ul class="users">
  <%= render @users %>
</ul>

RailsはこれをUserオブジェクトのリストであると認識、それぞれをパーシャルとして書き出してくれる。すごい。