Skip to content. | Skip to navigation

Four Digits | Willemsplein 44, 6811 KD Arnhem, The Netherlands | info@fourdigits.nl
 
Maarten Kling is working as a Senior developer for Four Digits in the Netherlands. Maarten is a Zope developer for seven years and a Plone developer and integrator for four years. Maarten has implemented over a dozen websites, some examples are; Cool Region, NPO and the Royal Dutch Chess Organisation. His specialisation is implementing a website design in Plone based on a Photoshop document and creating viewlets, portlets and content-types.
 

Using SQLPASPlugin for mysql user authenticating

by Maarten Kling Sep 10, 2008

Using a existing mysql db including over 3000 usernames and passwords to login into Plone and using a table view for there properties.

I was randomly searching the Internet for some nice new articles about Plone when I stumbled into SQLPASPlugin. After some reading I start to give it a try on a project that we where working on.

The project had a database including over 3000 users who could login at a administration tool built with  Zope 2. The current Mysql database was connected to Zope using ExUserFolder. This worked fine for Zope, however, we are porting the application to Plone now so we needed another solution.

I created a new plone instance and configured my buildout to include SQLPASPlugin and MySQLDA to connect to Mysql. The buildout.cfg part looks something like this :

parts =
...
zmysqlda
...
[productdistros]
recipe = plone.recipe.distros
urls =
http://plone.org/products/sqlpasplugin/releases/1.0/SQLPASPlugin-1.0.tar.gz
...
[zmysqlda]
recipe = cns.recipe.zmysqlda
target = ${productdistros:location}
...

In my case,  the Mysql bindings are already installed on my system. If there are not installed you need the MySQL-python package :http://pypi.python.org/pypi/MySQL-python/1.2.2

After installation it's time to run buildout (./bin/builout) again and start Plone (./bin/instance fg). I created a Plone site and went to the portal_quickinstaller. Here I found SQLPASPlugin, and installed it.

In the root of my Plone site I created a Z MySQL Database connection, which connected to the Mysql server on my local machine witch includes the database with the user tables.

Time to take a look at the SQLPASPlugin configuration screen (SQL Authentication), found in the control panel of Plone. I configured the table, username, and password column.

For me this worked perfectly because all my users where in the table passwd ( created for exuserfolder a long time ago ) having a username and password column. If you don't have a database yet follow the link at the bottom for an SQL script.

sqlauthentication

The SQL Authentication control panel

Now i went to the ZMI of my Plone site and had a look at the acl_user folder. There where three new items there, named source_users, source_roles and source_properties. Because all the users already have roles defined in the current zope application I mapped these roles using the following screen :

rolesview

The roles view in the ZMI

That was easy, mapping the roles table to my passwd table, the rols_col_username column to my username column and the roles_col_rolename column to my roles column.

It was time to take a look at the source_properties tab :

source_properties

Filled in source_properties

Here I discovered that it was possible to map property fields to columns in my database.

My passwd table did not had a fullname or email field, they were stored in different tables. So I created a view :

CREATE VIEW propertiesview as SELECT username,'' as password, email, telefoon  as phone, concat(name,' ',prefix,' ',lastname) as fullname from usertable;

This way I could map all the fields that I needed (not all shown here, but you can select more if you need) as properties for my users and even put some fields together to create the fullname field. All the fields in the view could be mapped  by filling them in by col_mapping as:

selected_field / property_name_in_plone (for example : In the image above as fullname/fullname)

However, after configuring this all, my properties didn't show up, so it was time to take a look at the plugin registry of acl_users. There was a link named 'Properties Plugins', I clicked it and found out it was looking for properties using the mutable_properties plugin fist, so i moved my source_properties plugin to the top.

changeorder

The properties plugin view

Now it was time to try it all and perform a login. To bad, it failed because ExUserFolder crypted all my passwords in a different way as the standard options available in SQLPasPlugin. So for now we made a little change to the PlainEncrypter in encrypt.py (line 79) of SQLPASPlugin.

def validate(self, reference, attempt):
"""Validate attempt against reference."""
pwd = crypt.crypt(attempt, reference[:2])
return reference == crypt.crypt(attempt,reference[:2])

Now my plain password posted in the login_form are crypted the way ExUserFolder did it, so the comparison will succeed now.

Now I could login using the usernames and passwords from my existing MySQL database and I also found out that my fullname and email address are shown correct now! ( made some dance moves here! \o/ )

If you have used ExUserFolder in the past check out this code for the crypt function:

tarbal ( encrypt.py , encrypt.zcml )

References:

Database example:

Good to know:

If you want to change password encryption:

By default, SQLPASPlugin currently stored passwords as plain text. You may configure it to use MD5 or SHA encryption algorithms.

  • In the root of your Plone site in the ZMI, go to the acl_users folder (note: the acl_users folder at the root of your plone site, NOT your Zope root).
  • Go to the source_users folder.
  • Select the properties tab.
  • In default_encryption enter sha or md5 or crypt!

IMPORTANT: A VERY STUPID THING TO KNOW!

  • Z SQL Methods are limiting resultsets to a maximum of 1000 results default. (ARG!)
  • In my case I lost over 2k users in the user overview and it took me (not for the fist time) over an hour to figure out why!
  • Solution: Go to your ZMI, acl_users -> source_users -> sqlLoadAllUsers -> Advanced and set maximum rows to retrieve to 0 (no limit)
 

an old way?

Posted by Anonymous User at Sep 13, 2008 04:43 PM

it seems an old way to develop... ZMySQLDA, ExUserFolder, autogenerated ZSQL method... what about a PAS Authentication plugin and an sqlachemy approach? I started from SQLPASPlugin and created a PAS plugin with sqlalchemy (no ZSQL, no DB connector... ) it seems to work fine and better...

 
Maarten Kling

sqlachemy

Posted by Maarten Kling at Sep 19, 2008 10:07 AM
Its not the newest way indeed, but only had a quick look at sqlachemy, so this worked fine for me now.
Will do some more research in time on sqlachemy.
 
Asbjorn

published

Posted by Asbjorn at Apr 27, 2009 01:19 PM
Did you publish the sqlalchemy pas plugin? Would be nice to have a look at it :)
 
Stefano

an old way?

Posted by Stefano at Sep 03, 2010 01:31 PM
How can I configure pas.plugin.sqlachemy? I have installed it with buildout but now I don't see any object in my acl_users folder.
thanks
 
Farida

Where can I find the database example?

Posted by Farida at Oct 21, 2008 03:12 PM
Thanks for nice article on using SQLPASPlugin. I tried getting the Database example and link seems to not work.

Any alternative URL to get to this sqlpas_db.sql?

Thanks in advance!
Farida
 
Martijn Jacobs

sqlpas_db.sql

Posted by Martijn Jacobs at Oct 21, 2008 03:32 PM
The file contains the following content :

create database sqlpasdb;
\c sqlpasdb;
create schema sqlpas;
create table sqlpas.users (
  username varchar(64) primary key,
  full_name text,
  email text,
  password text
);

create user myuser with password 'mypassword';
grant all on schema sqlpas to myuser;
grant all on table sqlpas.users to myuser;
 
steven

stevenfrcc@gmail.com

Posted by steven at May 11, 2009 10:42 PM
hi, is there a way i can map the group of each user?
 
Steven

use the same table for user and role

Posted by Steven at Jun 25, 2009 12:20 AM
Hi,
is there a way i can use the user and role in the same table?
 
Rod Tatham

pool_recycle

Posted by Rod Tatham at Jul 27, 2010 10:45 AM
I found that I needed to set this property in SQLAlchemyDA to stop the connection dropping after 8 hrs:-

pool_recycle 3600

- Thanks for the post - especially "A VERY STUPID THING TO KNOW"!!
 
Made by Four Digits based on Plone.
Made by Four Digits based on Plone.