Ruby on Rails IF Statement Verification Check - mysql

so I'm new to ruby on rails and I'm having a problem with this if statement, basically what I'm checking for is if the confirmation token in the sql database exists for the email address logging in. If it does kick back a message your email isn't verified. Once you click the link in the email, it deletes the token in the database. Then you can proceed to login. I cant get it working for the life of me. Everything else works but the verification check. Thank you for your help !!!
def authenticate(email, password)
command = AuthenticateUser.call(email, password)
user = User.find_by email:(email)
confirmationtoken =
User.find_by_confirmation_token(params[:confirmation_token].to_s)
if user.present? && confirmationtoken.present?
render json: {error: 'Email not verified' }, status: :unauthorized
elsif command.success?
render json: {
access_token: command.result,
message: 'Login Successful'
}
else
render json: { error: command.errors }, status: :unauthorized
end
end

You can simply check whether the user's confirmation_token attribute is set:
user = User.find_by(email: email)
if user && user.confirmation_token.present?
# ...
elsif command.success?
# ...
else
# ...
end
user.confirmation_token.present? can be shortened to user.confirmation_token?

I think this will help clean up your logic since theres no need to do a user lookup twice. And looking up the user and using the object could cause security concern .. let AuthenticateUser find the user and get success if they're in the system. When you send an email off just build a button in the email with a link to an endpoint that will verify the email and set the confirmation token to nil.
def authenticate(email, password)
command = AuthenticateUser.call(email, password)
has_confirmation_token =
User.find_by_confirmation_token(params[:confirmation_token]).present?
if !has_confirmation_token && !command.success?
render json: {error: 'Email not verified' }, status: :unauthorized
elsif command && command.success?
render json: {
access_token: command.result,
message: 'Login Successful'
}
else
render json: { error: command.errors }, status: :unauthorized
end
end

Related

Flask Oauth2 get Google+ profile-picture-url from the profile-picture-json

I have a problem here in obtaining the Google+ profile-picture-url from the profile-picture-json. I'm quite a beginner and this is my first webapp so please take this into account.
My callback function:
def callback(self):
self.validate_oauth2callback()
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()
},
decoder=jsondecoder
)
me = oauth_session.get('').json()
social_id = 'google$' + me['sub']
username = me.get('name', None) if me.get('name', None) else me['email'].split('#')[0]
email = me['email'] if me['email_verified'] == True else None
url = me.get('profile', None)
image_json = 'https://www.googleapis.com/plus/v1/people/' + me['sub'] + '?fields=image&key=AIz..yAl..juCqj..sjj9y..PuM..R..9..F8p..mo'
image = image_json['image'] # <-- THIS DOESN'T WORK
return social_id, username, email, url, image, me
My problem is that the variable image_json contains the following:
{
"image": {
"url": "https://lh6.googleusercontent.com/-f..i0..dl..Gc/AAAAAAAAAAI/AAAAAAAAABQ/iNw-IEz...o/photo.jpg?sz=50",
"isDefault": false
}
}
and I have to extract the profile-picture-url from that. A substring method doesn't work since in order to get that code I have to "run" the url saved in image_json.
What I need is something like image = image_json['image'] to retrieve the string:
"https://lh6.googleusercontent.com/-f..i0..dl..Gc/AAAAAAAAAAI/AAAAAAAAABQ/iNw-IEz...o/photo.jpg?sz=50"
and I would like to change that size in 256 instead of 50.
I have followed many posts but I didn't found a solution for this thing.
The view that will call this function is the following:
#auth.route('/callback/<provider>')
def oauth_callback(provider):
oauth = OAuthSignIn.get_provider(provider)
social_id, username, email, url, image, jsonme = oauth.callback()
if social_id is None:
flash('Authentication failed! Access to ' + provider + ' denied.')
return redirect(url_for('main.home'))
user = User.query.filter_by(email=email).first()
if not user:
user = User(social_id=social_id, username=username, email=email, social_page=url, social_image=image)
db.session.add(user)
db.session.commit()
else:
...
login_user(user, True)
return redirect(url_for('main.home'))

Return a value to a CGI script

In my main script, main.cgi, I present the user with a form to login. When this form is submitted it, another script is called to perform the verification, login.cgi.
login.cgi
# Convert request method to Uppercase eg: GET, POST
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
# If "POST" request sent, check login credentials
if ("$ENV{'REQUEST_METHOD'}" eq "POST"){
# Get login parameters
my $username = param('username');
my $password = param('password');
my $loginCheckResult = check_login($username, $password);
# If login was successful, create a cookie
if ($loginCheckResult){
# Set Cookie
my $cookie = CGI::Cookie->new(-name=>'USERID',-value=>$cookie_value);
print redirect(-uri => '/cgi-bin/main.cgi/', -cookie => $cookie);
# If login was Unsuccessful, redisplay the login page
} else {
# Do something here...
}
}
If the login is successful, I create a cookie and send the user back to the main page. Here I can test if a cookie is existent to determine whether the login was successful.
However, I'm not sure what to do if the login was unsuccessful.
main.cgi
if ($cookie eq ""){
print show_login_form();
# Login successful
} else{
print $cookie;
}
If I redirect them back to main.cgi, the login form will be showed again but no error will be displayed. If I include an error message underneath
print show_login_form();
then it will always be showed. Is there a way that I could send back a variable to indicate that the login failed and then check for this variable in main.cgi?
Or should I just create another login form in login.cgi upon an unsuccessful login attempt and include an error message in this form?
Thank you for your help.
The code in the 'successful login' code path is the code that generated the page a logged-in user should see.

Rspec received unexpected message :[] with

I write a mapper which matches attributes received from facebook and set them to my model.
class Mapper::FacebookUser
def initialize (user, facebook_user)
#user = user
#facebook_user = facebook_user
end
def name
#user.name = #facebook_user['name'] if #facebook_user['name'] rescue false
end
end
The response from Facebook is something like this: (JSON)
{
"name": "Jo Doe"
}
And my user_spec is that:
require 'spec_helper.rb'
describe Mapper::FacebookUser do
before(:each) do
#facebook_user = double("FacebookUser")
#user = User.new
end
it 'should map name to name' do
#facebook_user.stub(:name).and_return("User Name")
Mapper::FacebookUser.new(#user, #facebook_user).name
#user.name.should eq("User Name")
end
end
RSpec::Mocks::MockExpectationError: Double "Facebook" received
unexpected message :[] with ("name")
I tried the following:
#facebook_user.stub(:name).and_return("User Name")
#facebook_user.stub("name").and_return("User Name")
#facebook_user.stub(:[]).and_return({name: "User Name"})
#facebook_user.stub(:[]).and_return({name: "User Name"}.to_json)
only this one works, but I am quite sure, that's not the way:
#facebook_user.stub(:[]).and_return("User Name")
What is wrong with my approach?
How can I get my test working?
many thanks
I use rspec:
rspec (2.14.1)
rspec-core (2.14.7)
rspec-expectations (2.14.4)
rspec-mocks (2.14.4)
rspec-rails (2.14.0)
First, you're not obviously using #facebook_event in your model, so I'm not sure you're stubbing it. If you want to stub the object/method you are using in your name method, you'd need to stub the :[] method on the #facebook_user object you're passing in on your new call. The reason you're getting the error you're getting is because your not stubbing that method.
I assume the one approach you tried with the #facebook_event stub is working because the real Mapper::FacebookUser#[] method calls that object in that way.
My approach is now
I hope this helps someone
facebook_user = { "name": "Jo Doe" }
class Mapper::FacebookUser
def initialize (user, facebook_user={})
#user = user # AR model
# allows ['key'] or [:keys]
#facebook_user = facebook_user.with_indifferent_access
end
def name
#user.name = #facebook_user.dig('name') # sets to nil if not present (works also with chains) >= Ruby 2.3
end
end
require 'spec_helper.rb'
describe Mapper::FacebookUser do
before(:each) do
#user = User.new
#facebook_user = {}
end
it 'should map name to name' do
#facebook_user['name']
Mapper::FacebookUser.new(#user, #facebook_user).name
#user.name.should eq("User Name")
end
end

Create an elsif statement in Rails API?

I am trying to receive a JSON post to my Rails 3 application. The JSON post is just an email with a subject which will be one of the following:
BACKUP_PASS/VERIFY_PASS
BACKUP_FAIL/VERIFY_FAIL
BACKUP_FAIL/VERIFY_PASS
etc..
I have the following code in my controller:
def backupnotification
email_payload = JSON.parse(params[:payload])
Activity.create(:action => 'failed to backup', :details => email_payload['recipient'], :user_id => '28')
end
I've also added the following to my routes file:
post '/api/activity/backupnotification' => 'activities#backupnotification'
Obviously, this would create a new Activity record regardless of the backup status. What I would like to do is create an activity with an action of failed to backup if the term FAIL appears anywhere in the subject, and successfully backed up if the term FAIL does not exist.
The JSON post (email_payload) includes an attribute called subject. I was wondering if I could do something like this:
if email_payload['subject'] => "FAIL"
...
else
...
end
What would be the best way of doing this?
Assuming you can access your subject in a similar way as your recipient, you can try something like this.
def backupnotification
email_payload = JSON.parse(params[:payload])
if email_payload['subject'].include?('FAIL')
action_message = 'failed to backup'
else
action_message = 'successfully backed up'
end
Activity.create(
:action => action_message,
:details => email_payload['recipient'],
:user_id => '28')
end

How do I create an rspec test that validates a JSON response?

I have a Groups Controller with a method def inbox.
If the user is a group member then inbox returns a JSON object.
If the user is not a member, then inbox should redirect thanks to CanCan permissions.
How do I write an rspec to test these two use cases?
Current spec:
require 'spec_helper'
describe GroupsController do
include Devise::TestHelpers
before (:each) do
#user1 = Factory.create(:user)
#user1.confirm!
sign_in #user1
#group = Factory(:group)
#permission_user_1 = Factory.create(:permission, :user => #user1, :creator_id => #user1.id, :group => #group)
end
describe "GET inbox" do
it "should be successful" do
get inbox_group_path(#group.id), :format => :json
response.should be_success
end
end
end
Routes:
inbox_group GET /groups/:id/inbox(.:format) {:controller=>"groups", :action=>"inbox"}
Routes File:
resources :groups do
member do
get 'vcard', 'inbox'
end
....
end
This is how I do this:
describe "GET index" do
it "returns correct JSON" do
# #groups.should have(2).items
get :index, :format => :json
response.should be_success
body = JSON.parse(response.body)
body.should include('group')
groups = body['group']
groups.should have(2).items
groups.all? {|group| group.key?('customers_count')}.should be_true
groups.any? {|group| group.key?('customer_ids')}.should be_false
end
end
I'm not using cancan, therefore I cannot help with this part.
Sometimes it might be good enough to verify if response contains valid JSON and to show actual response otherwise, here is an example:
it 'responds with JSON' do
expect {
JSON.parse(response.body)
}.to_not raise_error, response.body
end
Try this:
_expected = {:order => order.details}.to_json
response.body.should == _expected
I think the first thing you want to do is to check that the response is of the correct type, i.e. that it has the Content-Type header set to application/json, something along the lines of:
it 'returns JSON' do
expect(response.content_type).to eq(Mime::JSON)
end
Then, depending on your case, you might want to check whether the response can be parsed as JSON, like wik suggested:
it 'responds with JSON' do
expect {
JSON.parse(response.body)
}.to_not raise_error
end
And you could merge the above two into a single test if you feel like two tests for checking JSON response validity are too much.
To assert JSON you can do this too:
ActiveSupport::JSON.decode(response.body).should == ActiveSupport::JSON.decode(
{"error" => " An email address is required "}.to_json
)
This blog gives some more ideas.