require 'bundler/setup' Bundler.require require 'sinatra/reloader' #if development? require 'sinatra-websocket' require 'active_support' require 'active_support/core_ext' require 'active_support/all' require 'sqlite3' require 'active_record' require 'json' require 'bcrypt' require 'openssl' require 'logger' require 'rotp' require 'rqrcode' require 'rqrcode_png' require 'chunky_png' require_relative 'models/user' require_relative 'models/authorization' require_relative 'models/tweet' set :sessions, secret: 'sessions_secret_key' logger = Logger.new(STDOUT) #メインページ get '/' do #ログインOK if session[:current_user_id] user=User.user_check(session[:current_user_id]) if user @active_home="active" @username=user.name @lastlogin=user.updated_datetime erb :index else redirect '/logout' end #2要素認証のみ未認証 elsif session[:user_id] #該当するユーザのチェック @active_login="active" user=User.user_check(session[:user_id]) #2要素認証用トークン登録済み if user && user.rotp_key.present? erb :confirm_otp #2要素認証用トークン未登録の場合は登録してもらう elsif user && user.rotp_key.blank? session[:rotp_key]=User.generate_rotp_key logger.debug(session[:rotp_key]) @qr_base64=User.make_qrcode(user.email, session[:rotp_key]) @account=user.email @rotp_key=session[:rotp_key] erb :generate_rotp_key #そもそもユーザいなかったらセッションをクリアする else redirect '/logout' end #ログインNG else redirect '/login' end end get '/tweet' do #ログインOK if session[:current_user_id] user=User.user_check(session[:current_user_id]) authorization=Authorization.confirm_authorized(session[:current_user_id], "Twitter") logger.debug(authorization) if user && authorization @active_home="active" @username=user.name erb :tweet elsif user erb :error else redirect '/logout' end else redirect '/login' end end #サインアップ(新規登録) get '/signup' do logger.debug(session[:user_id]) #条件式判定のため、未定義ならnilを代入 session[:current_user_id] ||= nil #ログインされてるならセッションクリアしてもらう if session[:current_user_id].present? redirect '/logout' end @active_signup="active" erb :signup end #ログインページ get '/login' do #認証済みならメインページへ if session[:current_user_id] redirect '/' end @active_login="active" erb :login end #user作成 post '/create' do #登録パスワードが不一致したら登録しなおし if params[:password] != params[:confirm_password] redirect '/signup' end #Userクラスより新規データを追加しインスタンス作成 user = User.new(email: params[:email], name: params[:name], created_datetime: Time.now, updated_datetime: Time.now) #bcryptでパスワードをハッシュ値にしてデータ追加 user.encrypt_password(params[:password]) #正常にデータベースに登録できれば、セッションにidを入れて2要素認証の登録へ if user.save! session[:user_id] = user.id end redirect "/" end #rotp_keyを生成する post '/generate_rotp_key' do #rotp_keyが登録されたトークンと同じものかを確認 rotp_at = User.confirm_generated_rotp_key(session[:rotp_key], params[:otp]) #同じものだと確認できたらusersテーブルのrotp_keyに登録し、ログイン成功のセッション情報を入れる if rotp_at User.update(session[:user_id], rotp_key: session[:rotp_key]) session[:current_user_id] = session[:user_id] end #念の為、登録したrotp_keyのセッション情報は削除 session[:rotp_key]=nil redirect '/' end #ログインID・パスワードチェック post '/check' do #もしログイン認証済みならメインページへリダイレクト if session[:current_user_id] {login: "already"}.to_json #Ajaxでemailが送られてきた場合(第1段階) elsif params[:email] #次の処理のためにemailをsessionに入れておく session[:email] = params[:email] #サーバ側でsaltを生成 session[:salt] = BCrypt::Engine.generate_salt logger.debug(session[:salt]) #usersテーブルのpassword_saltとサーバ側で生成したsaltをクライアント側に送る salts=User.send_salt(params[:email], session[:salt]) #Ajaxでハッシュ化したpasswordとクライアント側で生成したsaltが送られてきた場合(第2段階) elsif params[:password] && params[:salt] logger.debug(params[:password]) logger.debug(params[:salt]) #ログイン認証 user = User.authenticate(session[:email], params[:password], session[:salt], params[:salt]) logger.debug(user) #認証OKなら2段階認証するために一旦セッションにidを格納しておく if user session[:user_id] = user.id redirect '/' #認証NGならログインしなおし else {login: "error"}.to_json redirect '/' end end end #rotp_keyを生成する post '/confirm_otp' do #ワンタイムパスワード認証 user = User.confirm_otp(session[:user_id], params[:otp]) #ワンタイムパスワードで認証できたらログイン成功のセッション情報を入れる Time.zone = 'Tokyo' if user User.update(user.id, updated_datetime: Time.now) session[:current_user_id] = user.id end #念の為、登録したrotp_keyのセッション情報は削除 session[:rotp_key]=nil session[:user_id]=nil redirect '/' end #ログアウト get '/logout' do session[:current_user_id] = nil session[:user_id] = nil erb :logout end #ログアウト delete '/session' do session[:current_user_id] = nil session[:user_id] = nil redirect '/login' end post '/send_tweet' do Tweet.new.comment_tweet(params[:comment]) erb :tweet_successful end