Guest User

AuthEmailNonceController

a guest
Mar 28th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 7.60 KB | None | 0 0
  1. require 'jwt'
  2. require 'securerandom'
  3.  
  4. class Api::V1::Rest::AuthEmailNonceController < ApplicationController
  5.  
  6.   # =begin
  7.   # @apiVersion 1.0.0
  8.   # @api {post} /api/v1/rest/auth_email_nonce Login or Register using Server Key with nonce
  9.   # @apiDescription Register user if not exist, otherwise only return access key
  10.   # @apiName LoginOrRegisterEmailNonce
  11.   # @apiGroup Rest API
  12.   #
  13.   # @apiParam {String} user[app_id] Application id, 'qisme', 'kiwari-stag', etc
  14.   # @apiParam {String} user[secret_key] Application server key
  15.   # @apiParam {String} user[email] Valid email to be register or sign in
  16.   # @apiParam {String} user[fullname] Valid fullname to be register or sign in
  17.   # @apiParam {String} [user[avatar_url]] Valid avatar_url to be register or sign in.
  18.   # Default avatar_url = https://d1edrlpyc25xu0.cloudfront.net/image/upload/t5XWp2PBRt/1510641299-default_user_avatar.png
  19.   # @apiParam {String} user[nonce] Nonce from SDK
  20.   # =end
  21.   def create
  22.     begin
  23.       user = nil
  24.       identity_token = nil
  25.       jwt = ""
  26.  
  27.       # delete all session if not used within one month
  28.       # put here since it will be called everytime user want to login, no need in transaction because it must be deleted whether the transaction success or not
  29.       AuthSession.where("auth_sessions.updated_at < ?", 1.month.ago).destroy_all
  30.  
  31.       ActiveRecord::Base.transaction do
  32.         # app_id
  33.         app_id = params[:user][:app_id]
  34.         if app_id.nil? || app_id == ""
  35.           raise Exception.new("App_id can't be empty.")
  36.         end
  37.  
  38.         # server_key
  39.         server_key = params[:user][:server_key]
  40.         if server_key.nil? || server_key == ""
  41.           raise Exception.new("Server key can't be empty.")
  42.         end
  43.  
  44.         # find application using app_id and server_key
  45.         application = Application.find_by(app_id: app_id, server_key: server_key)
  46.  
  47.         if application.nil?
  48.           render json: {
  49.             error: {
  50.               message: "Application id not found or invalid server key."
  51.             }
  52.           }, status: 404 and return
  53.         end
  54.  
  55.         # email
  56.         email = params[:user][:email]
  57.         if email.present? && !email.nil? && email != ""
  58.           email = email.strip().delete(' ')
  59.  
  60.           if email == ""
  61.             raise Exception.new("Email can't be empty.")
  62.           end
  63.         else
  64.           raise Exception.new("Email can't be empty.")
  65.         end
  66.  
  67.         # fullname
  68.         fullname = params[:user][:fullname]
  69.         if fullname.nil? || fullname == ""
  70.           raise Exception.new("Fullname can't be empty.")
  71.         end
  72.  
  73.         # avatar_url is optional
  74.         avatar_url = params[:user][:avatar_url]
  75.  
  76.         # need to set default user avatar_url
  77.         if avatar_url.nil?
  78.           avatar_url = "https://d1edrlpyc25xu0.cloudfront.net/image/upload/t5XWp2PBRt/1510641299-default_user_avatar.png"
  79.         end
  80.  
  81.         # nonce
  82.         nonce = params[:user][:nonce]
  83.         if nonce.nil? || nonce == ""
  84.           raise Exception.new("Nonce can't be empty.")
  85.         end
  86.  
  87.         user = User.find_by(email: email, application_id: application.id)
  88.  
  89.         # if nil then register
  90.         if user.nil?
  91.           role = Role.member
  92.           if role.nil?
  93.             render json: {
  94.               error: {
  95.                 message: "Can't find user role, please contact admin to seed their database."
  96.               }
  97.             }, status: 404 and return
  98.           end
  99.  
  100.           new_user_credential = params[:user].permit!
  101.  
  102.           email_sdk = email.tr('+', '').delete(' ')
  103.           email_sdk = email_sdk.gsub('@', '.')
  104.           email_sdk = email_sdk.downcase.gsub(/[^a-z0-9_.]/i, "") # only get alphanumeric and _ and . string only
  105.           email_sdk = email_sdk + "@" + application.app_id + ".com" # will build string like user_email_name.email.com@app_id.com
  106.  
  107.           new_user_credential.delete(:app_id) # delete app id, replace with application_id
  108.           new_user_credential["application_id"] = application.id
  109.           new_user_credential["passcode"] = nil
  110.           new_user_credential["qiscus_token"] = "qiscus_token" #
  111.           new_user_credential["qiscus_email"] = email_sdk
  112.           new_user_credential["email"] = email
  113.           new_user_credential["fullname"] = fullname
  114.           new_user_credential["avatar_url"] = avatar_url
  115.  
  116.           # using class initiation to avoid user send another params (i.e fullname and it is saved)
  117.           user = User.new
  118.           user.email = new_user_credential["email"]
  119.           # user.fullname = new_user_credential["email"] # fullname set to be nil to inform client
  120.           user.application_id = new_user_credential["application_id"]
  121.           user.passcode = new_user_credential["passcode"]
  122.           user.qiscus_token = new_user_credential["qiscus_token"]
  123.           user.qiscus_email = new_user_credential["qiscus_email"]
  124.           user.fullname = new_user_credential["fullname"]
  125.           user.secondary_phone_number = new_user_credential["secondary_phone_number"]
  126.           user.is_public = false
  127.           user.avatar_url = new_user_credential["avatar_url"]
  128.           user.save!
  129.  
  130.           # add user id to email to ensure that email is really unique
  131.           email_sdk = "userid_" + user.id.to_s + "_" + user.qiscus_email
  132.  
  133.           # this ensure qiscus email sdk to be unique
  134.           user.update_attribute(:qiscus_email, email_sdk)
  135.  
  136.           user_role = UserRole.new(user_id: user.id, role_id: role.id)
  137.           user_role.save!
  138.         else
  139.           # if user is exist then do nothing
  140.         end
  141.  
  142.         # login or register to SDK using rest api
  143.         email_sdk = user.qiscus_email
  144.         username = user.fullname
  145.         avatar_url = user.avatar_url
  146.         password = SecureRandom.hex # generate random password for security reason
  147.  
  148.         qiscus_sdk = QiscusSdk.new(application.app_id, application.qiscus_sdk_secret)
  149.         qiscus_token = qiscus_sdk.login_or_register_rest(email_sdk, password, username, avatar_url)
  150.         user.update_columns(qiscus_token: qiscus_token) # always update qiscus token
  151.  
  152.         # generate identity_token using nonce
  153.         payload = {
  154.           "iss": application.app_id, # your qiscus app id, can obtained from dashboard
  155.           "iat": Time.now.to_i, # current timestamp in unix
  156.           "exp": (Time.now + 2*60).to_i, # An arbitrary time in the future when this token should expire. In epoch/unix time. We encourage you to limit 2 minutes
  157.           "nbf": Time.now.to_i, # current timestamp in unix
  158.           "nce": nonce, # nonce string from nonce API
  159.           "prn": email_sdk, # your user identity such as email
  160.           "name": "", # optional, string for user name
  161.           "avatar_url": "" # optional, string url of user avatar
  162.         }
  163.  
  164.         header = {
  165.           "alg": "HS256",
  166.           "typ": "JWT",
  167.           "ver": "v2"
  168.         }
  169.  
  170.         identity_token = JWT.encode(payload, application.qiscus_sdk_secret, 'HS256', header)
  171.  
  172.       end
  173.  
  174.             jwt = ApplicationHelper.create_jwt_token(user, request)
  175.       render json: {
  176.         identity_token: identity_token,
  177.         access_token: jwt,
  178.         data: user
  179.       } and return
  180.  
  181.     rescue ActiveRecord::RecordInvalid => e
  182.       msg = ""
  183.       e.record.errors.map do |k, v|
  184.         key = k.to_s.humanize
  185.         msg = msg + "#{key} #{v}, "
  186.       end
  187.  
  188.       msg = msg.chomp(", ") + "."
  189.       render json: {
  190.         error: {
  191.           message: msg
  192.         }
  193.       }, status: 422 and return
  194.  
  195.     rescue Exception => e
  196.       render json: {
  197.         error: {
  198.           message: e.message
  199.         }
  200.       }, status: 422 and return
  201.     end
  202.   end
  203.  
  204. end
Add Comment
Please, Sign In to add comment