Working with existing Devise


(Alex Brinkman) #1

Is there a recommended way to integrate PushType with an existing site, that already has authentication provided via Devise? I see PushType is using Devise, but what I’d really like it to do is use my already set up User model and login forms. Is that possible?


(Aaron Russell) #2

Hi @alexbrinkman thanks for your question. In theory, yes this can be done. In practice, I’ve not actually done this yet so there’s likely to be a few bumps along the way and a bit of work to do. I hope to smooth this out soon as I think this should be as easy as possible.

The first thing to do pick the PushType engines you actually need. The default push_type gem is simply a wrapper for three different engines. You need to leave out PushType’s auth engine.

# Gemfile - remove the default 'push_type' gem and replace with:
gem 'push_type_core'
gem 'push_type_admin'

Now when you fire up your server, you should be able to access the PushType admin UI without even logging in. So you need to somehow hook your authentication in to the PushType admin engine. As you’re using Devise, you can try doing it how we’re doing it. Take a look at:

Which you can include into the admin controller in your application.rb file. Try:

config.to_prepare do
  PushType::AdminController.include PushType::AuthenticationMethods
end

The final bit of the jigsaw is to tell the PushType::UsersController to use your user model. Ideally this would be done with a config option, but alas one does not exist yet. Instead you’ll need to override the user_scope method. Take a look at:

https://github.com/pushtype/push_type/blob/master/admin/app/controllers/push_type/users_controller.rb#L54-L56

I dare say there’s more to it than this. But if you’re up for messing around and trying to get this working, I’d be really keen to learn how you get along. I want to smooth this out and learn where I can make changes in PushType itself to make this as painless as possible.


(Alex Brinkman) #3

Thanks @aaron for the detailed write up! I will be digging into this in the upcoming weeks, and will let you know how it goes.


(Epipheus) #4

Wouldn’t it be easier to just enable a CAS server option and point it to that server? I’m thinking it might help avoid getting into the guts of PushType (?)

(my random 2 cents – feel free to toss out)


(Aaron Russell) #5

@epipheus I think it’s a common use case that someone will want to integrate PushType with their existing app, which already has a user model and already has some kind of authentication. I’ve tried to anticipate that in the design of PushType - that’s why the push_type_auth engine can be omitted from the Gemfile. Every app and authentication system is going to be different, so there will always be an element of getting your hands dirty with code, but in time the “best approach” for integrating an existign auth system will hopefully become well understood and documented.

In future, there’s no reason why there can’t be a push_type_sso engine for integrating with a single sign on service and acts as a drop in replacement for push_type_auth.


(Alex Brinkman) #6

@aaron - I’m diving into this now and ran into an issue. Here’s what I’ve done so far:

  • Fork the repo (from f5b9946 on Oct 19)
  • Comment out the ‘push_type_auth’ from the Gemfile, commit back to my fork
  • Include my fork of PushType into my project
  • Go through the regular installation instructions, migrating db, etc.
  • When I bring up Rails and open the site, I hit the following error:
Sprockets::FileNotFound in FrontEnd#show
couldn't find file './webpack/admin.bundle' under '/Users/brinkman/.rvm/gems/ruby-2.3.1@cscl/bundler/gems/push_type-6197a0b93bc5/admin/app/assets/javascripts' with type 'application/javascript'

If I point my project’s Gemfile back to your official repo, and reload, I get the “You’ve installed PushType. Hurrah!” message. So something with just commenting out that module isn’t allowing me to load the site.

Any ideas? I’m happy to work through it, but I thought you might be interested in my progress since this seems like a use case you’d like to be able to have work.


(Alex Brinkman) #7

@aaron - Ok, nevermind, I misunderstood what you were saying about removing the auth module. I included the two other modules straight from my project and everything works as you described. Sorry for the false alarm!


(Aaron Russell) #8

No problem. I actually did this myself this week too, pretty much following exactly what I put in the post above.

However, I decided I didn’t want any UI in PushType for managing users at all (as it’s covered elsewhere in the app), so I removed the users menu item from PushType by putting the following in my application.rb:

config.after_initialize do
  PushType.menu(:main).items.delete_if { |i| i.key == :users }
end

(Alex Brinkman) #9

@aaron - Excellent, thanks for the help. Removing the user management was on my list of things to, so thanks for that, you saved me a bunch of time!


(Alex Brinkman) #10

Ok @aaron, I’m getting close, but still have one last issue with the user model. I was able to authenticate the user properly, using my app’s authentication. I removed the UI for the user management within PushType as you mentioned. However, when I create a new instance of any type of node, I get an AssociationTypeMismatch error from Active Record:

PushType::User(#70265251466080) expected, got User(#70265218529940)

I tracked it down to the push_type_user helper method in PushType::AdminController, which returns my logged in user for current_user (regular devise User), while the PushType::Node creator and updater are expecting a PushType::User.

You mentioned that I needed to override the user_scope method, but that pertains to the user management, not with the user associated with a node, right?

I don’t know the best way to get past this, do you have ideas?


(Aaron Russell) #11

@alexbrinkman ah yes, I’d forgotten about that.

If you’ve used the concern approach suggested above, also add the following protected method so that it gets included into PushType::AdminController:

def push_type_user
  nil
end

In normal use, PushType saves the user id of the user who created and who last updated a node, and those respective user names are displayed in the UI when editing a node. In practice, that’s not really of any significant importance and it’s perfectly safe to nullify the push_type_user method this way - you just won’t know the creator or updater of any node.

In future, when this is smoothed out a little, the user class should be set through a config option and then we can dynamically create a node->user association using the right class name.


(Alex Brinkman) #12

Ok, that worked! Thanks for all of the help, you’ve been awesome!


(Matthew T Cianciolo) #13

Have there been any changes or a better way to set up pushtype in a program that already has Devise auth? I have followed the steps above (removing the auth gem, using the concerns) and I am able to authenticate normal users fine, but the pushtype page does not have any authentication needed to access it. Is there something I am missing?


(Aaron Russell) #14

@pickledyamsman the way described above is generally right, although since that was written we’ve added and API engine to PushType which the above doesn’t mention at all.

I’ve recently built an ecommerce site using Solidus and PushType alongside each other. In this case I didn’t need PushType to worry about users at all - we just worked with Solidus’ users.

This gist will hopefully point you in the right direction (the key is adding the authentication methods to the relevant controllers):

Note that in this solution I’ve just blocked access to the API totally by always returning a 401 status. That’s a lazy solution because I know the API isn’t used right now. In future versions of PushType the admin engine will make use of the API so I’ll need to revisit this solution.


(Matthew T Cianciolo) #15

Thanks I will tinker with this for a bit!

edit: That worked perfectly and now everything is working as it should!


(Matthew T Cianciolo) #16

I am now getting the error that was previously mentioned PushType::User(#70265251466080) expected, got User(#70265218529940) even with the protected method

   push_type_user
     nil
   end

I tried including this in both authentication_methods.rb and api_authentication_methods.rb but I get the message with either of them. Has this also changed?

Not sure if this information is relevant, but I am able to get into pushtype and view any nodes I have created previously but I get this error when I try to change them or create any new nodes.


(John R Epperson) #17

Note: This is a terrible hack. Don’t do this at home.

So, I ran into that problem as well when trying to have users for the frontend of the app and users on the backend with push type. In order to just get past the problem, I ended up using a solution that I still feel was suboptimal, but I wanted to at least mention it as a problem AND corroborate your pain. I ended up using multiple devise models. This was NOT ideal from many different angles, but I managed to cobble it together and it got me past the problem. I created a job that creates a front-end user after each push_type user creation and created a link between the two accounts. This allows things to function, but it’s something that I want to blow away eventually. There was only so much monkey-patching I could keep in my head at one time and this solution ended up being the one that I was able to wrap my head around.

Anyway…I wanted to also just mention that I ran into that trouble as well, but I also wanted to mention that alternative option - while discouraging you from going down that path if at all possible.


(Matthew T Cianciolo) #18

After some additional testing over this weekend I still haven’t gotten this working but I do have some notes if they help at all! It seems that the push_type_user method is not getting included in PushType::AdminController, but why it is not I’m still not sure. If I take out the push_type_user method it acts the same way as if it is included.

If I am logged into Devise this issue comes up, but if I log out it is no longer a problem. It will act like there is no user and no PushTypeUser and it will work fine. So the problem is only happening if I have a User logged in.

Also, it seems to work this way whether the API is included or not.


(Matthew T Cianciolo) #19

Ok got it working now. What did it was overwriting the node model because of the associations there.

module PushType
  class Node < ActiveRecord::Base

    include PushType::Customizable
    include PushType::Nestable
    include PushType::Templatable
    include PushType::Unexposable
    include PushType::Publishable
    include PushType::Trashable
    include PushType::Presentable

    belongs_to :creator, class_name: 'User'
    belongs_to :updater, class_name: 'User'

    acts_as_tree name_column: 'slug', order: 'sort_order', dependent: :destroy

    validates :title, presence: true
    validates :slug,  presence: true, uniqueness: { scope: :parent_id }

    def self.find_by_base64_id(secret)
      find Base64.urlsafe_decode64(secret)
    rescue ArgumentError
      raise ActiveRecord::RecordNotFound
    end

    def base64_id
      Base64.urlsafe_encode64 id.to_s
    end

    def permalink
      @permalink ||= self_and_ancestors.map(&:slug).reverse.join('/')
    end

    def orphan?
      parent && parent.trashed?
    end

    def trash!
      super
      self.descendants.update_all deleted_at: Time.zone.now
    end

  end
end

This was really just to get to the two lines with belongs_to. With this change the push_type_user method doesn’t need to be overwritten anymore either.

I don’t think this is a long term solution but for now this is working for anyone coming into this thread!

I also ended up overwriting the Asset model as well to get images to upload.


Adding user roles and even document types
(Aaron Russell) #20

Hey @pickledyamsman glad you got this sorted. By returning nil from the push_type_user method, this in effect should nullify the creator and updater associations, so in theory it shouldn’t matter what class your user model is. Not sure why that wasn’t working to be honest, but glad you got it sorted and bonus that it keeps the associations there.

In any case, in future the user class should be made configurable. I’ve just raised an issue to get this sorted soon. (we be a few weeks at least as I’m currently travelling)