Web2py manage user registration key pending status - authentication

I am hosting web2py for a client and don't want to give out web2py admin access. There are multiple applications running in web2py. All of them require approval for registered useraccounts. I would like to have a control which allows app admins to open a table of records with a pending registration key. The only function required is to remove the pending status from the registration key. This seems to be all but impossible outside of the appadmin control.

The Auth tables are just standard database tables and can therefore be accessed and edited as any other tables. There is no need to use appadmin in particular for this task. You have at least three options:
Use the built-in Application Management functionality. If you want to limit which auth_user fields are writable, you could include a condition such as the following in a model file:
if request.function == 'appadmin' and request.args(0) == 'manage':
[setattr(field, 'writable', False) for field in db.auth_user
if field.name != 'registration_key']
Create a custom action and use the built-in grid functionality. To limit the viewable records to those with pending registrations, you can pass a query as the first argument to the grid:
SQLFORM.grid(db.auth_user.registration_key == 'pending', ...)
You can create your own CRUD functionality using any of the facilities available in web2py.

Related

Reduce Active Directory users in Jira using LDAP Query

I am retrieving users for Active directory in Jira 7 by using LDAP. I am trying to reduce the number of users brought from LDAP to a particular group that we have created. So in order to do that i put (objectCategory=group)(cn=WebAgileDevs) in the group object filter along with the default settings. The only thing i change is the Base DN and credentials required. When i save and test it does show me that it is testing 1 group and 15 users which is what i want!(See the screenshot). BUT, when i go and sync it, it brings in 43000 users!! What am i missing???
Test Remote Directory Screenshot
The group filter is used to filter the list of groups that are imported to JIRA, and the user filter is used to filter the list of users that are imported to JIRA. The two need not necessarily correspond. Your group filter would be instructing JIRA to bring in only that one group (into the list of groups), but without further refinement, your user filter will still be pulling in all users, as you noticed. This means that you need to adjust the user filter too.
From your question, you want to import only those users who are a member of a specific group. Atlassian provides some general guidance here.
The last example on that page is particularly relevant for you:
(&(objectCategory=Person)(sAMAccountName=*)(memberOf=cn=CaptainPlanet,ou=users,dc=company,dc=com))
This tells JIRA to pull in only those user objects that are a member of the group cn=CaptainPlanet,ou=users,dc=company,dc=com. You would want to replace this with your cn=WebAgileDevs (plus whatever trailing qualifiers you need to fully qualify the group name).

implement a booking lock for users in a scheduling app

I've built a scheduling web app where users can book a conference for a given date and time slot on that date.
Now I need to implement a booking lock, which means that the admin can apply this lock and users can no longer book from that time on.
My current design includes a model booking_lock that only has one attribute of "status" with values of "On" and "Off".
The model would have only one record in the database at any given time as its sole responsibility would be to provide the data to check if booking has been locked.
---------------------EDIT-----------------------------------
This is not meant to lock individual records (conferences). To do this I use the attribute of user_id. If that is 0, then the conference is available for booking.
What I want to do now is disable (lock) the booking entirely before the user hits the database.
For example:
When a user logs on they see a notification saying the booking is locked. Also, they wouldn't see a respective button to book a conference and if by chance they would navigate to the respective URL they would be redirected to home page with the same notice as above. I've got all this covered.
But I need a general switch to be turned on and off and be the basis for this kind of check. Hence the booking_lock model.
Note: I use hanami-model.
---------------------EDIT-----------------------------------
My question is twofold:
Is there a better way of implementing such a lock?
How to ensure there is only one record in the db for such lock?
1. Is there a better way of implementing such a lock?
It seems that your requirement is to have an application-wide setting, which is best done with
An environment variable
A value stored in database
Environment variables:
pros: system already in place, simple usage, can easily be configured statically and changed dynamically
cons: might be difficult to maintain with a multi-tenant architecture (multiple servers running the same app)
DB persistence
pros: scales easily with a multi-tenant architecture
cons: can seem a bit of an overkill for one setting BUT can easily be abstracted into a Key/Value store for multiple settings.
Example:
Create an AppSettings model with two columns: key & value.
Create and save an AppSetting with key "lock_booking_for_parents" and change the value through an admin interface.
Access this AppSetting throughout the app to know if you should lock booking or not.
Also, if you are worried about querying your database everytime you need to know if booking is enabled/disabled, you can easily implement caching.
2. How to ensure there is only one record in the db for such lock?
Environment variable
Not applicable
DB persistence
You can create a helper class to access your settings with default behavior, and use first_or_create method to ensure the record is unique.
class AppSettingsHelper
def self.booking_enable?
app_setting_record = AppSettings.find_by_key("lock_booking_for_parents")
if app_setting_record
return app_setting_record.value
else
## default behavior of your app when no record has been created yet
return true
end
end
def self.enable_booking
AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: false})
end
def self.disable_booking
AppSettings.where(:key => "lock_booking_for_parents").first_or_create({value: true})
end
end
You could try the ActiveRecord pessimistic locking method, or something like it. Set a field on your record that indicates a lock and try it:
booking_lock = UUID.new # Or any sufficiently unique string
Booking.update_all({ id: #booking.id, booking_lock: booking_lock }, { booking_lock: nil })
booked = Booking.find_by(id: #booking.id, booking_lock: booking_lock)
If you get the record back you successfully locked it. If not you need to try again with a different booking, it got nabbed before you could claim it.

How to create relationships in a RESTful API

I have 2 tables, User table and User_token table, they are one to one/none relatonship, not sure how to create this RESTful API.
i prefer to setup
# to get user attributes
GET /users/123
# to get user's token
GET /users/123/token
or should i create
# to get user attributes and token by JOIN the table
GET /users/123
the argument we have here, if we are doing the first setup, which i like it, it takes thousands of API requests compare to second one
that is depend you requirement.
for example if you need User Attributes and Token every time than
# to get user attributes and token by JOIN the table
GET /users/123
is better.
other wise another approach is good to get required data when needed.
REST has nothing to do with your database structure.
Your resources can contain properties or sub-resources. Every resource has at least one resource identifier (URL).
So in your case the GET /users/123 is a valid solution.

How to join two objects in Rally

I would like to join the user object and project permission object to see how many users have been assigned to a project, for audit purpose. I don't see a common field with common values (email address or first name/last name) between these objects. I used Excel plugin to retrieve two separate data sheet and unable to map them. Any thoughts on this on how to do this?
You're probably seeing something similar to the following when you query on ProjectPermissions:
In this situation, the default User object selected from the "Columns" picker in the query dialog, gives you the User's DisplayName, which doesn't unambiguously map to a Rally UserID.
Note, however, that you can add dot-notation sub-fields of Objects manually by typing them into the Columns field. In the following example, I've included User.Username and User.LastLoginDate as additional fields I want to show on the Permissions report:
Of course, you could also just include User.Username, and run a second query on the User object with all fields selected, and do a join in Excel.
One note of caution - if you have many users (say 1,000), and a lot of projects, (say 1,000, which is not uncommon in large Rally subscriptions), querying directly against the ProjectPermissions endpoint can rapidly result in total results that number on the order of 10^6. This will probably time out in an Excel query.
The Rally User Management: User Permissions Summary script works around this by querying Permissions in a loop on a user-by-user basis. It's slow, but it returns results without timeouts. Certainly not as convenient as Excel either - you need to install Ruby 1.9.2+ and the rally_api gem to get it working.

Suborganizations and Unique id

I can succesfully authenticate my application with ApacheDS
But now i use only one domain.
I want to add subdomains or sub organizations under root domain.
For example a root organization as
dc=example,dc=com
and sub organizations dc=x
another sub organization dc=y
Now i can authenticate users using uid attribute
like:
user-search-filter="(uid={0})"
i use login name like user1, without an # extension
But i want to have suborganizations and i want to use user1#x.example.com
Is it possible and how?
My application is a spring application but i think subject is independent from my application side.
The attribute defined in the LDAP standards track for email addresses is mail, rfc822mailbox, or 0.9.2342.19200300.100.1.3 as defined in RFC4524. Perhaps your filter should be an attribute assertion using one of those types, for example, user-search-filter="mail={0}".
I am not sure what is meant by "manually". LDAP does not have a concept of organizations, only entries that might belong to an organization. These entries might have a mail attribute if the entry belongs to an objectClass that allows or requires the mail attribute. In other words, if your filter is mail={0} (which might become mail=user1#x.example.com), then a search using that filter (given the appropriate base object and scope) will return all entries that have a mail attribute with the value user1#x.example.com irrespective of where that user is located and irrespective of the value of the uid attribute.
If the users in an organization can identified some other way, perhaps by organization or other attribute, then the filter could be:
(&(uid={0})(o=x))
or
(&(uid={0})(o=y))
One way or another, the users' entry must be identifiable by the contents of the entry. The primary key in an LDAP database is the distinguished name (uid=abc,dc=x,dc=example,dc=com) but attributes in the entry can be used to tighten the filter. Some alternatives are:
use unique identifiers (all uid or mail values are unique in the database, therefore, only one is ever returned to a search request)
use an attribute to identify users in an organization (like o in the example filters above)
use a dynamic group to generate a list of users in an organization.
consider using an extensible match filter to make values in the distinguished names be part of the filtering process
see also
using ldapsearch - the article is about the ldapsearch command line tool, but the concepts are useful when constructing search requests
mastering search filters