postmark app with devise - registration and forgot password emails - postmark

I cannot get postmark to handle registration and forgot password emails:
user_mailer.rb
class UserMailer < ActionMailer::Base
include Devise::Mailers::Helpers
default from: "donotreply#barnpix.com"
def confirmation_instructions(record)
devise_mail(record, :confirmation_instructions)
end
def reset_password_instructions(record)
devise_mail(record, :reset_password_instructions)
end
def unlock_instructions(record)
devise_mail(record, :unlock_instructions)
end
# you can then put any of your own methods here
end
application.rb
config.action_mailer.delivery_method = :postmark
config.action_mailer.postmark_settings = { :api_key => ENV['9302106a-63xxxx-xxx-xx-'] }
user.rb
devise :database_authenticatable, :registerable, :recoverable,
:rememberable, :trackable, :validatable
devise.rb
config.mailer = "UserMailer" # UserMailer is my mailer class
I cannot get this to work at all. Any hints as to what I might be doing wrong or what I might be missing to get this to work ?

I think your problem is caused by this line:
config.action_mailer.postmark_settings = { :api_key => ENV['9302106a-63xxxx-xxx-xx-'] }
ENV is a hash of all environment variables. You should use names to access the values. I guess you’re using Postmark on Heroku, so it will be ENV['POSTMARK_API_KEY'] in that case.

Related

Undefined avatar method from Carrierwave in RoR application

I get this error message:
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `avatar=' for #<User::ActiveRecord_Relation:0x007f87e4c304d8>):
app/controllers/api/v1/user_controller.rb:10:in `upload'
Model:
class User < ActiveRecord::Base
acts_as_token_authenticatable
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
mount_uploader :avatar, AvatarUploader
validates_presence_of :avatar
validates_integrity_of :avatar
validates_processing_of :avatar
end
Controller:
module Api
module V1
class UserController < ApplicationController
before_action :set_user, only: [:show, :update, :destroy]
#before_filter :authenticate_user_from_token!
def upload
puts "here => " + params[:user][:email].to_s
#user = User.where(email: params[:user][:email])
#user.avatar = params[:user][:file]
#user.save!
p #user.avatar.url # => '/url/to/file.png'
p #user.avatar.current_path # => 'path/to/file.png'
p #user.avatar_identifier # => 'file.png'
end
...
environment.rb:
# Load the Rails application.
require File.expand_path('../application', __FILE__)
require 'carrierwave/orm/activerecord'
# Initialize the Rails application.
Rails.application.initialize!
The AvatarUploader was generated and the avatar:string column was added to the users table through the migration execution. I am not sure what's wrong with it.
Extra info: I use Rails: 4.2.4, Ruby: 2.2.1
Many thanks !
The error is pretty informative. When you call User.where(email: params[:user][:email]) you don't get a User object, you get an ActiveRecord_Relation object, wich can contain multiple ActiveRecord objects or be empty. To get a single User you want to use find_by instead of where, then you'll be able to get access to the avatar.

Devise::InvitationsController reports Unpermitted parameters

I have a problem with devise_invitable 1.4.0 and strong parameters when I add additional custom parameters and I really hope somebody can guide me in the right direction. I am able to send invitations, but when an invited user accepts an invitation and enters a desired username, maiden name, password and confirmed password, the following error is shown:
Processing by Users::InvitationsController#update as HTML
Unpermitted parameters: username, name
The user is created as expected, but the 'username' and 'name' columns in the database are empty.
I have tried all the suggestions I could find for related issues, but none of the worked. I have noticed that if I change the app/controllers/users/invitations_controller.rb file in any way (eg inserting a blank space on an empty line) without restarting the webserver (Thin) the problem disappears - but the problem reappears when the webserver is restarted.
The various relevant files look like this:
routes.rb:
Rails.application.routes.draw do
root to: 'visitors#index'
#Tell rails to use the Devise controllers that were generated with this command:
# > rails generate devise:controllers users
#Using these generated controllers allows us to overwrite anything in the deault controllers.
devise_for :users, :path_names => {:sign_in => 'login', :sign_out => 'logout'}, controllers: {confirmations: "users/confirmations", passwords: "users/passwords", registrations: "users/registrations", sessions: "users/sessions", unlocks: "users/unlocks", :invitations => 'users/invitations'}
resources :users
end
config/initializers/devise.rb
Devise.setup do |config|
...
...
config.scoped_views = true
config.authentication_keys = [ :username ]
...
...
end
app/controllers/users/invitations_controller.rb:
class Users::InvitationsController < Devise::InvitationsController
private
# this is called when creating invitation
# should return an instance of resource class
def invite_resource
## skip sending emails on invite
resource_class.invite!(invite_params, current_inviter) do |u|
u.tenant = current_inviter.tenant
u.role = :user
end
end
def after_invite_path_for(resource)
users_path
end
def resource_params
params.permit(user: [:name, :email,:invitation_token, :username])[:user]
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
around_filter :scope_current_tenant
before_filter :configure_permitted_parameters, if: :devise_controller?
if Rails.env.development?
# https://github.com/RailsApps/rails-devise-pundit/issues/10
include Pundit
# https://github.com/elabs/pundit#ensuring-policies-are-used
# after_action :verify_authorized, except: :index
# after_action :verify_policy_scoped, only: :index
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
end
#############################################################################
private
#############################################################################
if Rails.env.development?
def user_not_authorized
flash[:alert] = "Access denied." # TODO: make sure this isn't hard coded English.
redirect_to (request.referrer || root_path) # Send them back to them page they came from, or to the root page.
end
end
def current_tenant
#current_tenant ||= current_user.tenant unless current_user.nil?
end
helper_method :current_tenant
def scope_current_tenant(&block)
if current_tenant.nil?
scope_visitor_schema
yield
else
current_tenant.scope_schema("public", &block)
end
end
def scope_visitor_schema()
original_search_path = ActiveRecord::Base.connection.schema_search_path
ActiveRecord::Base.connection.schema_search_path = 'public'
ensure
ActiveRecord::Base.connection.schema_search_path = original_search_path
end
#############################################################################
protected
#############################################################################
def configure_permitted_parameters
# Only add some parameters
devise_parameter_sanitizer.for(:account_update).concat [:name, :email]
# Override accepted parameters
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:name, :username, :password, :password_confirmation,
:invitation_token)
end
end
end
app/models/user.rb:
class User < ActiveRecord::Base
enum role: [:user, :admin]
after_initialize :create_tenant, :if => :new_record?
belongs_to :tenant
# has_many :invitations, :class_name => self.to_s, :as => :invited_by
scope :unconfirmed, -> { where(confirmed_at: nil) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
# validate :username, presence: true, uniqueness: true, format: { with: /[a-zA-Z0-9]{4,20}/ }
def displayed_username
username.nil? ? "N/A" : username
end
def displayed_name
name.nil? ? "N/A" : name.titleize
end
def create_tenant
#The create_tenant method will also be called when looking up a user,
#so the following ensures a tenant is only created if it does not already
#exist - and the user has not been invited and assigned to an existing tenant:
if self.tenant.nil?
#Set role to 'admin' if a tenant is about to be created:
self.role = :admin #if self.tenant.nil?
self.tenant = Tenant.new
end
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
end
I finally found a fix, which was to place the parameter sanitizer directly in users/invitations_controller.rb instead of the application_controller.rb.
class Users::InvitationsController < Devise::InvitationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:username, :name, :email, :password, :password_confirmation, :invitation_token)
end
end
end

Update model in rails 4

I am very new in rails I have built a form from my model #user
this is my user controller
def me
#user = User.find_by_id(current_user.id)
if !params.empty?
#user.update_attributes params[:user]
end
end
But I getting this error:
ActiveModel::ForbiddenAttributesError
this is my model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
private
def user_params
params.require(:user).permit(:name, :surname, :email, :phone, :mobile)
end
end
I tried to define here an "update" method, but I get errors like this:
ActiveModel::ForbiddenAttributesError
Any idea?
Ok so a few things here
Your update method should look like this
def me
#user = current_user.find_by(params[:Id])
end
You need to have your permitted Params in your controller, and add :Id to those Params
As it looks like your using devise you will need to make your own user controller inheriting from devises controller so that you can override the permitted Params
See the devise docs on how to override the controller as its really simple

device facebook oAuth stucked on redirect page

Im using devise omniauthable for user authentication both with google and facebook. Google works just fine but facebook gets stucked on a redirect page, although on their platform the user logs in correctly (on facebook).
This is the log i get:
2014-09-01T15:26:41.996884+00:00 app[web.1]: (facebook) Request phase initiated.
2014-09-01T15:26:42.211524+00:00 app[web.1]: (facebook) Request phase initiated.
2014-09-01T15:26:41.994627+00:00 app[web.1]: Started GET "/users/auth/facebook?locale=es" for 190.15.201.45 at 2014-09-01 15:26:41 +0000
2014-09-01T15:26:42.205674+00:00 app[web.1]: Started GET "/users/auth/facebook?locale=es" for 190.15.201.45 at 2014-09-01 15:26:42 +0000
2014-09-01T15:26:42.217355+00:00 heroku[router]: at=info method=GET path="/users/auth/facebook?locale=es" host=myapp.herokuapp.com request_id=2b9aab45-c511-4ac9-b36f-4e6925cba3aa fwd="190.15.201.45" dyno=web.1 connect=2ms service=16ms status=302 bytes=1284
My routes:
devise_for :users, :controllers => { omniauth_callbacks: "users/omniauth_callbacks" }
My omniauth_callbacks_controller:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
#user = User.find_for_oauth(env["omniauth.auth"], current_user)
if #user.persisted?
sign_in_and_redirect #user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
[:google_oauth2, :facebook].each do |provider|
provides_callback_for provider
end
My user model:
class User < ActiveRecord::Base
devise :database_authenticatable, :confirmable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
belongs_to :company
before_save :create_user_company
def create_user_company
if self.company_id.nil?
company = Company.new
company.email = self.email
company.save
self.company_id = company.id
self.admin = true
end
end
def self.find_for_oauth(auth, signed_in_resource = nil)
identity = Identity.find_for_oauth(auth)
user = signed_in_resource ? signed_in_resource : identity.user
if user.nil?
email = auth.info.email
user = User.where(:email => email).first if email
if user.nil?
user = User.new(
name: auth.extra.raw_info.name,
email: email ? email : "temp_email#mail.com",
password: Devise.friendly_token[0,20]
)
user.skip_confirmation!
user.save!
end
end
if identity.user != user
identity.user = user
identity.save!
end
user
end
end
Devise initializer is the basic:
config.omniauth :facebook, ENV['FB_APP_ID'], ENV['FB_APP_SECRET']
But i also tried this (didnt work):
config.omniauth :facebook, ENV['FB_APP_ID'], ENV['FB_APP_SECRET'],{client_options: {ssl: {ca_file: Rails.root.join('lib/assets/cacert.pem').to_s}}}
And im using this gems:
gem 'omniauth'
gem 'omniauth-google-oauth2'
gem 'omniauth-facebook'
gem 'devise'
gem 'figaro' #for safe saving of env vars
I would appreciate any hint you might have.
Thanks in advance.
PS: this is not the answer
Ok, if anyone encounters the same problem, this fixed it:
Go into your facebook developer console (developers.facebook)
Enter your App:
On Setting you need to add a contact email.
On Status and Reviews you will find this question (former Sandbox): "Do you want to make this app and all its live features available to the general public?".
Click "Yes".

Why is my enum value wrong in minitest using Pundit gem?

I created a starter app from RailsApps with the rails-devise-pundit example app. I am trying to write a user controller test because I plan to change some functionality and I want to make sure things still work. The pundit UserPolicy is not returning the correct value which is based on a role enum in the User class. The UserPolicy.index? method seen below is returning false when called from the first test in UsersControllerTest. Sorry there is a lot of code and detail here. I hope everyone can follow it.
Here's the failing test in UsersControllersTest. The response is a :redirect instead of :success.
require "test_helper"
class UsersControllerTest < ActionController::TestCase
def setup
#admin = users(:admin)
#admin.role = :admin
end
test "should get index page when authenticated as an admin" do
sign_in #admin
get :index
assert_response :success
end
...
end
Here's my user controller class just showing the index method where my problem is. authorize #users should call the UserPolicy.index? method.
class UsersController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized, except: [:show]
def index
#users = User.all
authorize #users
end
...
end
My pundit user policy class. When I change the index? method so it returns true, the response in my UsersControllerTest is :success. So for some reason #user.admin? is not returning the correct value.
class UserPolicy
attr_reader :user, :record
def initialize(user, record)
#user = user
#record = record
end
def index?
#user.admin?
end
...
end
What is even stranger is that I created a UserPolicyTest class and when I test calling index? from there, I get the correct response. This test works correctly:
require 'test_helper'
class UserPolicyTest < ActiveSupport::TestCase
def setup
#admin = users(:admin)
#admin.role = :admin
end
def test_index
policy = UserPolicy.new #admin, nil
assert policy.index?
end
end
Here is my User model:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
enum role: [:user, :vip, :admin]
after_initialize :set_default_role, :if => :new_record?
validates :name, presence: true
def set_default_role
self.role ||= :user
end
end
Here's my test fixture for an admin user:
admin:
email: admin#example.com
name: Mr Admin
role: admin
encrypted_password: $2a$10$PoBe1MvkoGJsjMVTEjKqgeBUp.xdfzWoiDjBzQhtLAj16NqIa2fOy
remember_created_at: nil
sign_in_count: 3
current_sign_in_at: 2014-01-02 08:31:23
last_sign_in_at: 2014-01-02 08:31:23
current_sign_in_ip: 127.0.0.1
last_sign_in_ip: 127.0.0.1
confirmation_token: nil
confirmed_at: 2014-01-02 08:31:23
confirmation_sent_at: 2014-01-02 08:30:59
created_at: 2014-01-02 08:30:59
updated_at: 2014-01-02 08:31:23
I found that setting the role in the fixture doesn't work. I'm guessing that's because of the after_initialize :set_default_role, :if => :new_record? line in my User model. If there's another reason or a better way to handle this, please let me know.
UPDATE: Maybe this is being caused by strong parameters. When I tried debugging my code with pry, I found that in the UsersControllerTest, after signing in, the admin user had a role of 2 which is correct. But when it got to User.Policy.index?, the role was 0. I may need to add the role field to the devise strong parameters. I saw something about how to do that a while back. It didn't look easy. If someone knows the answer before I get to it, please let me know.
After I changed the value of #admin.role in setup, I didn't save the user. After adding #admin.save to the setup method, the test passed.