Grails Spring Security Core Plugin redirect issue - grails

I'm using the "Spring Security Core Plugin" for Grails and am using a simple map in my Config.groovy file to restrict access based on authentication type.
For example, I want to prevent users from going to the "user/create" page because obviously you wouldn't want people to be able to create other users when they're logged in (I'm ignoring for now that managers/mods would be able to have this functionality). To accomlish this, I have
grails.plugins.springsecurity.interceptUrlMap = [
'/user/create': ['IS_AUTHENTICATED_ANONYMOUSLY']
]
The only problem is, it seems to be acting like the action:
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
I want it to redirect to the page it was previously on though.
i.e. user/list, attempt to call action create from user controller, if logged in, would reidirect back to user/list.
Any help is GREATLY appreciated.

I might be wrong, but I don't think you can do what you want using ['IS_AUTHENTICATED_ANONYMOUSLY'], it won't restrict logged in user since per documentation
The token accepts any authentication, even anonymous.
Why not just put something like
//in user controller
def create() {
if(springSecurityService.currentUser) {
//let them know they're already logged in
flash.message = message(code: 'your.....message')
redirect(action: "list")
}
//else take them to create form
...
}

Also change 'IS_AUTHENTICATED_ANONYMOUSLY' to 'permitAll'. and use the if statement.

Related

Is it possible to do Devise sign in, out, etc without any redirection whatsover?

I'm using Devise, but not using the Devise controllers directly because I'm performing all of the actions through a custom built GraphQL API. One issue I have, for example, is that after enabling confirmable, if a user tries to sign in and I call Devise::Controllers::Helpers#sign_in the user gets redirected to /api/v1/users/sign_in, which doesn't exist and it would be wrong even if it exist. Instead, I need the failure to sign in to be returned back to my code (return value, exception, whatever), so that my API can encode that response to the frontend.
How can I do that?
For example, this is my log in function:
def resolve(email:, password:)
user = User.find_for_authentication(email: email)
if user&.valid_password?(password)
context[:sign_in].call(user)
{ current_user: user }
else
{ errors: [{ message: 'Email or password incorrect.' }] }
end
end
context[:sign_in] is set up in the GraphqlController by including Devise::Controllers::Helpers and then simply:
context = {
current_user: current_user,
sign_in: method(:sign_in),
sign_out: method(:sign_out)
}
Note: I am not using GraphqlDevise because I don't want to use Devise Token Auth, I'm using cookies.
I believe passing devise's sign_in/sign_out methods via context is probably a deadend.
The suggestion in the comment to your question from #Int'l Man Of Coding Mystery is good ie you could use: https://github.com/graphql-devise/graphql_devise.
If you're not keen in introducing another dependency and figuring out how to wire everything you can perhaps go with overriding devise's SessionController.
See for some examples here: Rails - How to override devise SessionsController to perform specific tasks when user signs in?
(but also don't hesitate to look at the source code for the matching Devise release: https://github.com/heartcombo/devise/blob/master/app/controllers/devise/sessions_controller.rb)
Depending on your use case you might be even able to do what you need by using some of the config options - e.g. you can perhaps try to override after_sign_in_path etc.

how to get the viewsource of page at dynamically in rails

i want to get the view source of this page "http://localhost:3000/splash_templates/edit_template/10017".
I used httpclient gem, but with this am getting the view source of login page.
So how to set the authentication and how to get the view source
I haven't used it before but you need to first authenticate user and then get content.
http://www.rubydoc.info/gems/httpclient/2.1.5.2/HTTPClient this url will help you. Configuring authentication credentials section provide way to authorize user runtime.
Hope this help you!
You need to login to get the source of the pages.
Although your question is not clear as to what kind of authentication is requested to be set, however here is the hint that you can go ahead with
Authentication with Web server. Supports BasicAuth, DigestAuth, and Negotiate/NTLM (requires ruby/ntlm module).
clnt = HTTPClient.new
domain = 'http://dev.ctor.org/http-access2/'
user = 'user'
password = 'user'
clnt.set_auth(domain, user, password)
p clnt.get_content('http://dev.ctor.org/http-access2/login').status
You can read more on this Here
Hope that helps ;)

Rails 3 - logging in a user automatically after creating the account

In my users_controller I have two methods signup_process and login. I would like to call login automatically for a user after a successful signup_process call.
Is this possible? In other language frameworks I would usually just call the login controller action direct from the signup_process action passing the username and password - but I think that is frowned upon in Rails.
Is there some way instead to post the user data to the users.login action from my controller?
This must be a common pattern - what am I missing? :)
Thanks in advance!
Not sure what you mean by frowned upon, but here's one way
class UsersController < ...
def signup
// Do some stuff
do_login(username, password)
// render or redirect as you wish
end
def login
do_login(username,password)
// render or redirect as you wish
end
private
def do_login(username,password)
// do the actual login processing
// can even render or redirect here if it's common to both setup and login
end
end
Would that do what you want?
Well, what does the login action do?
Most likely, it sets something in the session indicating the user is logged in. You could do just that, after creating the user.
It does not make sense to call a controller action, since it's most likely hooked up with a view/form.
Please provide more information on what the login action does, if you still feel like you need to go through it.

Symfony sfDoctrineGuardPlugin custom login query

I use symfony sfDoctrineGuardPlugin to manage authentication for both frontend users and backend users. It's fine, except that I don't want frontend users to be able to login to the backend app. I can setup credentials, but credentials are checked after a user gets authenticated. What I want is to have sigin in form to never validate for a user, that is not in a backend group. How can I do this?
I think I found a better solution. sfDoctrineGuard plugin has its own post validator that checks for an optional callable for user retrival.
//app.yml
all:
sf_guard_plugin:
retrieve_by_username_callable: sfGuardUser::getForBackend
//sfGuardUser.class.php
public static function getForBackend($username)
{
$query = Doctrine::getTable('sfGuardUser')->createQuery('u')
->leftJoin('u.Groups g')
->leftJoin('g.Permissions p')
->where('u.username = ? OR u.email_address = ?', array($username, $username))
->addWhere('u.is_active = ?', true)
->addWhere('p.name = ?', 'backend');
return $query->fetchOne();
}
Here's one idea: You could try creating a custom post-validator for the login form. Here's a Google result:
http://www.symfony-project.org/blog/2008/09/05/call-the-expert-how-to-implement-a-conditional-validator
In this validator, you could check whether the user belongs to the group in question and then throw an error accordingly. The user would not get authenticated.
I think you just have to add:
storage:
class: sfSessionStorage
param:
session_name: sf_backend
at the end of your backend/config/factories.yml
By default, symfony shares session cookies, with this solution, symfony separate this cookies.

What's the restful way to implement a forgotten password feature?

I have the following restful structure:
My login page uses the session/new action
My signup page the users/new action
My logout page uses the session/destroy action
My register process uses the users/create action
I need 3 more actions for:
I forgot my password page
Start forgotten password action (send email)
Reset password based on token
Where do these 3 actions fit in a restful world?
To clarify:
I know I can create whatever actions on my existing session and user controllers (eg. a reset_password get action or a start_reset_password post action) it just doesn't really sit right, it seems I am trying to make these controllers do too much work.
REST is not black magic. Figure out what your technical goals are for these pages, then pick the right verbs to go with them.
I forgot my password page: essentially a static form, right? You want this to be cachable. GET on any URL you want.
Send email: costly action which you don't want repeated and you DO want executed every time the user requests it: POST or PUT on any URL you want. Heck, you could make it the same as the above URL if you wanted to, but I don't see a particularly pressing need to.
Reset password based on token: I'd consider implementing this as a login-via-token instead, but if you're going to do it your way, then it has server-side consequences and hence should probably be a POST or PUT.
I ended up creating a new controller called forgotten_passwords, to control the process
forgotten_passwords - new : maps to I forgot my password page
forgotten_passwords - create : maps to start forgotten password action (send email with token)
forgotten_passwords - show : maps to the end of the process (a page where the user sees her new password)
I am pretty happy with this design. I think it called for a new controller.

Resources