2010-11-26

Samba4 & PHPLDAPAdmin

Samba4 includes a PHP LDAP admin configuration sample. Unfortunately it doesn't match up to the current version of PHP LDAP Admin. The configuration you want to put into config/config.php is:
$servers->newServer('ldap_pla');
$servers->setValue('server','name','Samba4 AD Server');
$servers->setValue('server','host','ldapi://%2Fopt%2Fad%2Fsamba4%2Fprivate%2Fldapi');
$servers->setValue('login','auth_type','session');
$servers->setValue('login','attr','dn');

Then you should get an PHP LDAP Admin login screen for your shiny Samba4 AD DSA. For the AD uninitiated the DN of the Administrator's account is "CN=Administrator,CN=Users,DC=ad,DC=mormail,DC=com" (for example, if you AD domain is "ad.mormail.com").  Using that DN and the domain administrator's password you should be able to login.
Another trick is to put that LDAPI LDAP URI into the /etc/openldap/ldap.conf  file so you can use the OpenLDAP LDAP CLI utilities [ldapsearch, ldapadd, ldapmodify, etc...] provided by your distribution.

Python Exceptions and "auto" Instantiation

Interesting thread on the python-list as to what happens regarding raising exceptions. The low-down: If you "raise ExceptionClass" and instance of that ExceptionClass is always created.

For example:
try: raise KeyError
except KeyError: pass

From the documentation:
raise evaluates the first expression as the exception object. It must be either a subclass or an instance of BaseException. If it is a class, the exception instance will be obtained when needed by instantiating the class with no arguments.

Some exception classes require arguments so the naked raise will fail with a TypeError.
 raise UnicodeDecodeError
Traceback (most recent call last):
  File "", line 1, in
TypeError: function takes exactly 5 arguments (0 given)

Seems to me it is clearer to just do the raise with instance syntax:
try:
  raise KeyError()
except KeyError as e:
  pass

2010-11-05

SQLAlchemy & Upcoming Birthdays

OpenGroupware Coils uses SQLAlchemy  as it's ORM. One of the desired features was a Logic command that efficiently returns contacts with upcoming birthdays.  In raw SQL this query would be very simple to write - but how to do it in SQLAlchemy? The answer: "sql.expression.extract" which will create an expression column equivalent to EXTRACT. With EXTRACT it is possible to compare to the year-of-day represented by a date.  The Python code looks like:
db = self._ctx.db_session()
# Get the current day-of-year
doy = datetime.today().timetuple().tm_yday
# Deal with year wrap-around
floor = doy - 2
if (floor < 1): floor +=365
ceiling = doy + 14
if (ceiling > 365): ceiling -= 365
# Create a field that is the SQL expression DOY(Contact.birth_date)
orm_doy = sql.expression.extract('doy', Contact.birth_date)
# Create the query
query = db.query(Contact).filter(and_(sql.expression.between(orm_doy, floor, ceiling),
                                      Contact.birth_date != None,
                                      Contact.is_account == self.accounts,
                                      Contact.status != 'archived'))
In this example "self.accounts" is an attribute with a value of 0 or 1.