django auth - has_perm returns True while list of permissions is empty - django-authentication

I'm wondering why this code section prints out the following:
print "request.user.has_perm('bug_tracking.is_developer'): " + str(request.user.has_perm('bug_tracking.is_developer'))
print request.user.get_all_permissions()
request.user.has_perm('bug_tracking.is_developer'): True
set([])
I would expect that request.user.has_perm('bug_tracking.is_developer') returns false if the list of all permissions is empty!?

huups...was a super user ;-)
Superuser status
Designates that this user has all permissions without explicitly assigning them.

Also note that if you have a method has_perm in you User model, the authentication backends' has_perm methods will not called ever.

Related

How can I conditionally run a block of resources or a recipe in chef?

I've the following recipe used to create some users, add them to a group and set the password to expire at the first login.
search(:users, '*:*').each do |user|
userPassword = "$1$scmdevop$ZDTyqia9RXSrpHGK75FjN/"
user user['id'] do
comment user['comment']
home user['home']
shell user['shell']
manage_home true
password "#{userPassword}"
end
if user['sudo'] then
group "#{node.default["sudogroup"]}" do
action :modify
members user['id']
append true
end
end
if (user['resetPassword'] == nil) || (user['resetPassword']) then
bash 'setExporation' do
code 'chage -d 0 ' + user['id']
user 'root'
end
end
end
The problem is that in this way it will continue to reset the password and set the espiration at every run so I was trying to find how to make it conditionally. I would like to use the following command to check if the user exist
grep -qs #{user["id"]} /etc/passwd
The problem is that I can use the not_if clause only in the first resource because after that the user has been clearly created. Is there a way to get the entire block of three resources being conditional to a shell exit code?
Thanks,
Michele.
What you probably want is a notification from the user resource, but this might be a little hard because that would trigger on any change, not just creation. The underlying problem here is that the desired behavior you stated is expressed in procedural terms, not in terms of convergent state. Best approach is probably to build a custom resource to hide some of this logic, but at heart what you want is an if statement like you already have.

Passing parameter in "Examples:" table of "Scenario Outline:" in a feature file

Here as you can see I am trying fetch a value from .yml file located in config/environments in Examples: table.
But instead of fetching it is sending the value as it is?
Is it possible to pass parameter like this? If Yes, how?
If not, which Ruby or Cucumber feature/concept refrains user to do so and why?
Feature: Verify login of all test users
I want to verify all test users can login.
Scenario Outline: Login as different users on the website
Given I am on login page
When I enter "<username>" and password
Then I click Login button
And I see "<user>" successfully logged in
Examples:
|user|username|
|testuser1|#{FigNewton.test1_email}|
|testuser2|FigNewton.test2_email|
First of all this is a pretty poor feature, better would be
Scenario: Test Users can login
Given there are some test users
When the test users login
Then all test users should be logged in
or something like that. Features are for stating what you want to do and why, not how you do things.
IF you do the above then all the programming will be done in the step definitions. This will allow you do do whatever you want.
You can implement this quite easily e.g
Given 'there are some test users' do
#test_users = create_test_users
end
When 'the test users login' do
#login_results = login_each(#test_users)
end
Then 'all test users should be logged in' do
expect(check_for_errors(#login_results).count).to eql 0
end
then implement the methods you need in a step helper e.g
module TestUsersLoginStepHelper
def create_test_users
...
def login_each(users)
users.each do
...
...
end
World TestUsersLoginStepHelper
By putting all the work in the step definitions, you make your live much easier, as you can use the full power of ruby to do what you need
Answer to query1:
You can parametrize via Examples: table but not directly passing value using FigNewton gem because it is a .feature file not a Ruby .rb file.
Answer to query2:
How you do it:
Parametrize and Loop it on username and in you steps definition mention what to do when particular user name found. By this you can easily parametrize.
Examples:
|user|username|
|testuser1|test1|
|testuser2|test2|
Step definition
When(/^I enter "([^"]*)" and password$/) do |username|
case username
when 'test1'
on(LoginPage).user_email = FigNewton.test1_email
when 'test'
on(LoginPage).user_email = FigNewton.test2_email
end
....
....
end
You can use this DDD scenario in project whenever its needed - by using this we do not need to create multiple test cases, it will fetch data value from Example outline.
Feature file : Test case
Scenario Outline: Login to application
When I enter "username>" and "password>"
Then I click Login button
And I see user successfully logged in
Examples:
|username|password|
|abc#gmail.com|Test1234!|
|abc#yahoo.com|Test1234!|
Step definition:
When(/^I enter "([^"])" and "([^"])"$/) do |username,password|
sleep 20
on(Login).email_edit_text_element.send_keys username
on(Login).password_edit_text_element.send_keys password
end
Then(/^I click Login button$/) do
sleep 20
on(Login).login_button_element.click
end
Then(/^I see user successfully logged in$/) do
expect(on(Login).account_bg_cover_element.displayed?).to be_truthy
puts 'Login Success'
end
In ruby file, you have created methods, you are calling that methods in step definition.
It will work. make sure about the name of parameter you are passing.

checking groups at runtime with devise and devise_ldap_authenticatable

I can get this devise_ldap_authenticatable working just fine when I don't care about what groups they are, it either connects to ldap and authenticates the user signing in under devise or doesn't. But I want to let only certain members that are apart of one or several specific groups in. I had a post on this question here:
Checking group membership in rails devise ldap gem, is it in the yaml?
(the gem for completeness sake is this one: https://github.com/cschiewek/devise_ldap_authenticatable)
Got to thinking I am asking the wrong question. I think I want to know how in devise (and the devise_ldap_authenticatable is the data stored where perhaps I can peek at my array of memberOf's myself and check the groups for myself in code, and then at that time don't let them in. Is there anywhere on the net that's hows this? My googling has turned up nothing but not being a ldap or devise pro I am guessing my terms suck.
I am sure I just might of missed the how to do this, closest I can see that might help (Though in its form as I read it makes little sense to me is the part on the readme here:
https://github.com/cschiewek/devise_ldap_authenticatable/blob/master/README.md
about querying ldap, is this the case?)
You could do this with a callback or validation on the User (or equivalent) model.
before_create :user_is_not_member_of_specified_group?
private
def user_is_not_member_of_specified_group?
member_of = Devise::LdapAdapter.get_ldap_param(self.username,"memberOf")
test member_of
end
where test is a method that returns true/false based on your conditions for the member groups.
The Devise::LdapAdapter.get_ldap_param(self.username,"memberOf") is a method from devise_ldap_authenticatable that will return an array of member groups. You'll want to run your group testing on this array.
If you use a validation you could specify an error message for users that failed the test. Hope this helps.
EDIT
Another way to handle this would be to let your gem handle the redirection and error messages by monkeypatching the authorized? method in Devise::LdapAdapter::LdapConnect (https://github.com/cschiewek/devise_ldap_authenticatable/blob/master/lib/devise_ldap_authenticatable/ldap_adapter.rb). It would look like:
Devise::LdapAdapter::LdapConnect.class_eval do
def user_group_test
member_of = self.ldap_param_value("memberOf")
test member_of # your group test method
end
def authorized?
DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
if !user_group_test
DeviseLdapAuthenticatable::Logger.send("Not authorized because custom authentication failed.")
return false
elsif !authenticated?
DeviseLdapAuthenticatable::Logger.send("Not authorized because not authenticated.")
return false
elsif !in_required_groups?
DeviseLdapAuthenticatable::Logger.send("Not authorized because not in required groups.")
return false
elsif !has_required_attribute?
DeviseLdapAuthenticatable::Logger.send("Not authorized because does not have required attribute.")
return false
else
return true
end
end
end
You would want to put this in a custom initializer file in config/initializers.

Ruby: How do you have optional first arguments? but default trailing arguments?

I'd like to have a method that is similar to this:
def method_with_optional(..., user = current_user, account = current_account)
...
because, I don't want to have to pass in current_user, and current_account every time.
but as long as a user object isn't passed, the user formal parameter shouldn't be over-ridden.
This way I could do the following
method_with_optional(params[:id])
or
method_with_optional(params[:id], User.new)
What you're looking for are named arguments, which is not supported in Ruby 1.8, but you may have some success with arguments.
Sorry, at the moment there is no built-in support for named parameters, you have to wait for Ruby 2.0.
An alternative to default arguments would be to assign the variable in the body of the method and to provide the User, Account arguments as a part of the params hash. You can check to see if the params contains a User and/or Account and then do the needful:
user = params[:user] || current_user
account = params[:account] || account
EDIT: If you cannot add things to the Params hash before invoking the method, then I don't know what you can do other than re-order the formal parameters in the method signature :)

Devise: Is it possible to NOT send a confirmation email in specific cases ? (even when confirmable is active)

Here is my situation, I use devise to allow users to create account on
my site and manage their authentication.
During the registration process I allow customers to change some
options, leading to an actually different account being created but
still based on the same core user resource.
I would like to choose not to send a confirmation email for some of
those account types. I don't care if the account do not get confirmed
and user cannot log in, that's ok, no pb with that.
How would I go about doing that ?
Thanks,
Alex
Actually it's quite easy once I dig a little deeper.
Just override one method in your User model (or whatever you are using):
# Callback to overwrite if confirmation is required or not.
def confirmation_required?
!confirmed?
end
Put your conditions and job's done !
Alex
If you just want to skip sending the email but not doing confirmation, use:
# Skips sending the confirmation/reconfirmation notification email after_create/after_update. Unlike
# #skip_confirmation!, record still requires confirmation.
#user.skip_confirmation_notification!
If you don't want to call this in your model with a callback overwrite this method:
def send_confirmation_notification?
false
end
You can also simply add the following line of code in your controller before creating the new user:
#user.skip_confirmation!
I don't know if Devise added this after the other answers were submitted, but the code for this is right there in confirmable.rb:
# If you don't want confirmation to be sent on create, neither a code
# to be generated, call skip_confirmation!
def skip_confirmation!
self.confirmed_at = Time.now
end
I was able to do something similar with the functions:
registrations_controller.rb
def build_resource(*args)
super
if session[:omniauth] # TODO -- what about the case where they have a session, but are not logged in?
#user.apply_omniauth(session[:omniauth])
#user.mark_as_confirmed # we don't need to confirm the account if they are using external authentication
# #user.valid?
end
end
And then in my user model:
user.rb
def mark_as_confirmed
self.confirmation_token = nil
self.confirmed_at = Time.now
end

Resources