Extending DokuWiki’s Authentication Classes

DokuWiki is a fine product, and its extensibility is a big element of that. I’ve known for a while that it has different authentication classes, and I’ve even used some of the different ones it comes with. Recently I had cause to write my own, to marry up with some user information stored in an Oracle database table, and used to access the company intranet. Working with DokuWiki’s skeleton classes to create my own was much easier than I expected and here’s my experience.

Choosing the class to extend

Since my requirements are pretty simple, my new class extends auth_basic – and I used the plain.class.php that comes with DokuWiki (for plain text authentication) as a template to guide me.

The first step was to chop out most of the functionality. This is done by setting the class’ cando properties to false, which was quick. My system has all its user maintenance and so on done elsewhere so I don’t want users to be able to change passwords or anything. My declaration now reads:

class auth_symphony extends auth_basic {
    var $users = null;
    var $_pattern = array();
    /**
     * Constructor
     *
     * Carry out sanity checks to ensure the object is
     * able to operate. Set capabilities.
     *
     * @author  Christopher Smith <[email protected]>
     */
    function auth_plain() {
  $this->cando['addUser']      = false;
  $this->cando['delUser']      = false;
  $this->cando['modLogin']     = false;
  $this->cando['modPass']      = false;
  $this->cando['modName']      = false;
  $this->cando['modMail']      = false;
  $this->cando['modGroups']    = false;
      $this->cando['getUsers']     = false;
      $this->cando['getUserCount'] = false;
    }

Getting the information to dokuwiki

I included the standard library that we use here with all PHP pages, that handles things like database connection setup and so on. Then I altered the function _loadUserData(), creating a new empty array for $this-users and then then running a select statement and populating the array with the results. I found it useful to get the wiki working with plain text authentication first and just a couple of users set up so I could observe the output of the various functions. Here’s the altered function:

    function _loadUserData(){
    $this->users = array();
	

$L_sql = "
SELECT u.user_name
,u.extranet_pass
, d.dept_code
,u.full_name
,u.email
FROM vis_users u
, vis_subdepts d
WHERE d.subdept_code = u.subdept_code
AND u.extranet_valid = 'Y'
";

$L_bind_in = array();

$L_results = exec_sql($L_sql,$L_bind_in);

foreach($L_results as $L_result) {
$this->users[$L_result['USER_NAME']]['pass'] = md5($L_result['EXTRANET_PASS']);
$this->users[$L_result['USER_NAME']]['name'] = $L_result['FULL_NAME'];
$this->users[$L_result['USER_NAME']]['mail'] = $L_result['EMAIL'];
$this->users[$L_result['USER_NAME']]['grps'] = array('user',$L_result['DEPT_CODE']);
}
}

if anyone can make any suggestions about pasting clean code snippets in textpattern, I’d be grateful! In the meantime, I apologise for the state of the above example

I removed the functions for creating, modifying and deleting users as I had already told my class it couldn’t use those.

The results

All in all this was quite simple to get working, and DokuWiki is designed to have its authentication functions replaced in this way which is invaluable. We also created a new template for the site and hey presto we’re ready to go with no further modifications1 and no hassle when upgrades come around.

1 OK so actually I added some class definition to the breadcrumb hyperlinks because I changed the bar colour, but that’s almost no modification!

Diet Oracle – working with Oracle eXpress Edition

I’m a big oracle fan, which might seem a bit strange in a world dominated with the LAMP stack and its exclusive use of MySQL or, at a push, Postgresql. That’s not the entire world obviously, that’s my world and it is definitely MySQL-orientated. In the world of work however, I’ve had extensive exposure to Oracle and think its great, so I was very excited when I saw the free mini-Oracle be released earlier this year. These are my first experiences of working with it.

Installing Oracle XE on Windows.

OK so I’m not actually going to use this on windows really but when I tried to install this on Linux I had a major problem right at the outset. There is a choice of either a .rpm or a .deb file to install from and since I had sent my sysadmin to the supermarket, I had no idea which I needed! The windows installer promised to be point-and-click and since I’m actually running Windows on one machine at the moment (grr wireless drivers grr) I was tempted by the idiot-proof windows installer so I grabbed that.

Well, idiot-proof was a gross understatement! I ran the installer, it asked me where I’d like the files put and then to input a root password, and the next thing I know its all done and inviting me to log in. I’ve installed Oracle many times on Windows and believe me, its not supposed tobe this easy. Anyway it works, I’ve been chattering to it on command line and everything is cool. The next step is to get it installed under Linux – it turns out that our Ubuntu server would like the .deb file best, so I’ll try that out and keep updating here.

Recursive Queries in Oracle

I’ve come across a very neat trick in Oracle that I thought I’d share. Its useful for situations where you can have circular references in the data diagram, for example when the table includes a column which is a reference for another entry in the same table. Usually it would be necessary to write some function which could be called recursively and allow you to traverse this tree layout, however in Oracle there is the CONNECT BY PRIOR syntax.

The users and groups example

Sticking with my earlier example let’s say I’ve got an employees table and the employee can have a manager, which is an employee

users

ID USERNAME FIRST_NAME LAST_NAME MANAGER JOB_TITLE
1 esme Esmerelda Jones   Chief
2 rose Rose Micklethwaite 1 Queen Secretary
3 simon Simon Hirst 2 Secretary
4 tom Thomas Pockleton 1 Assistant Chief
5 miranda Miranda De Silva 4 Chief Assistant to the Assistant Chief
6 emily Emily Smith 2 Secretary
select first_name || ' ' || last_name, level
from users
connect by prior id = manager
start with id = 1

Will output the list of people followed by their reports. We can distinguish who is where in the tree using the magical column “level” which is available when we connect in this way. I’ve used the level to indent the name column by two spaces for each level down the tree the person is and to show their job title:

select lpad('  ', (level - 1) * 14) || first_name || ' ' || last_name, job_title
from users
connect by prior id = manager
start with id = 1

The Alt-Tab-while-you’re-waiting Trap

Today I’m working on a complicated database driven web page. I edit the source using vim on the main file server. In order to get the file onto the webserver, I then quit out of the file and a script checks my syntax and ftps the file into the correct location on the webserver. Once its there, my prompt returns and I know its time to refresh the web page. Which is interesting, but if you are still reading then you must be wondering what my point is.

Its this, the file check and write takes too long. Its not ages, its like, seven seconds. But its long enough for me to jump to the other window (or in this case, tab) and read the next headline in my feedreader, or the message in my chat window … and you can guess what happens next! I read the article, or reply to the message, or whatever. About three minutes later (if I’m lucky), I’ll remember to refresh the page, check my changes and go on with the task in hand.

This is why all programmers need fast hardware and efficient tools to develop with. My waiting attention span just isn’t long enough to wait more than about three seconds for compile/upload/reload/whatever else is needed. I think I can multitask but actually I end up distracting myself completely!

Speaking of which, my upload is finished ….

Regular Expressions in Oracle

I need to operate on a big table with lots of records, but only on rows where the primary key starts with a number. Because obviously its a good idea to differentiate types of records in this way …. only joking! Its just one of those little tasks that crops up from time to time.

The Fast and Dirty Way

select code
from products
where substr(code,1,1) in (0,1,2,3,4,5,6,7,8,9)

Oracle Regular Expression Method

select code
from products
where regexp_like(code,'^[[:digit:]]')

Further Resources

I got this from this article on technology and also the definition of some of the character classes from this very helpful resource on psoug

Good Advice for Life at the Office

I came across this when reading an article on Mike’s site yesterday:

_“The best advice I ever received from a manager is that it is easier to get forgiveness than permission.”

The article is at Top 3 Ways to Fight Bureaucratic Inertia in IT and it makes for interesting reading. More than once I’ve had projects cancelled or stalled indefinitely because of two superiors’ inability to agree on the requirements and Mike’s article has given me some ideas on how to manage this type of situation in the workplace.

Workplace Eating Arrangements

Its a funny thing but the smallest details when you are looking for a job are actually the most important. I’ve never actually asked to see inside the ladies when I’ve been at a job interview but I’ve always wished I had once I got the job!

I’ve been a big fan of Joel Spolsky for some time, but he posted an advert to his site today that had me riveted. He’s looking for a sysadmin for Fog Creek, and in the advert he writes

“We’re still a small friendly company and we all eat lunch together every day at one big table.”

This is what I’m looking for in a company, this sums up my requirements for my entire working life, and he’s nailed it in a single sentence.

Lucene search functionality – following on from crawlers and spiders

The search functionality works!!

I have PHP 5.1.2 on a Windows XP machine (I know, I know, its my work desktop) and Zend Framework preview release 1.3. I’m using it to index the files in a local copy of DokuWiki – this is an easy starting point as the pages are text files and all held in directories.

zend_lib.php
I have a library file which has some settings used both when building the index and when searching it. This file also includes a function which turns the url of the returned page into a path that dokuwiki can understand.

zend_text.php
The indexing page starts from $startpoint (set in zend_lib.php) and recurses into directories indexing file size, url and content of each file.

zend_text2.php
The search page shows some searching tips and a search box. When a search is performed it then prints links to the pages in dokuwiki and their relevance, ordered by relevance.

I’m so excited that I’m including the files here for now and might think about turning this into a proper dokuwiki plugin – although, personally I like their current search functionality, this current exercise is a PHB requirement. Here are the files:

zend_lib.php

zend_text.php

zend_text2.php

The Beauty of Vim

I work with vim and its fabulous. Although I’ve been a casual linux shell user for some years, I’ve never had to get to grips with vim as my main editor which I’m using eight hours a day until now. And I love it.

Cheat Sheets

Its vital to get a good cheat sheet to start with. This is like a menu of commands to remind you how to do things. Then when you think “wouldn’t it be cool if this program did …”, you can look up how to do it (and I guarantee vim has the feature you wanted, whatever it is. Some of my favourite tricks not always listed on cheat sheets are:

gv reselect your most recent selection
% when on a bracket (either ( or { ), jump to its partner

For more cheat sheets, probably best to look on my del.icio.us page (here and linked in left hand bar) as I keep my favourite links of the moment updated there

Colour Syntax

I have finally managed to get my vim working with colour highlighting which is making my life much easier (and prettier, of course). I’m running vim 6.2 on AIX 5.3 and found that the only way to get my vim into colourful mode was to turn on the syntax and set my terminal to dtterm.

To change your terminal type, at the prompt type:

export TERM=dtterm

Then when you do

echo $TERM

it should tell you that your term type is now dtterm. Unfortunately the change in terminal type made my function keys stop working (argh – see my earlier post on this topic). As a compromise I have aliased vim to set the terminal type when it runs, by adding the following line to my .kshrc file (if you’re running bash then add it to .bashrc instead)

alias vim=’vim -T dtterm’

Arrow keys

I normally use h,j,k,l to navigate in vim (left, down, up and right respectively), but I get stressed by the cursor not wrapping at the end of the lines. I googled for the problem and found that adding this to my .kshrc helped:

set -o emacs
alias __A=$(print ’\0020’) # ^P = up = previous command
alias __B=$(print ’\0016’) # ^N = down = next command
alias __C=$(print ’\0006’) # ^F = right = forward a character
alias __D=$(print ’\0002’) # ^B = left = back a character
alias __H=$(print ’\0001’) # ^A = home = beginning of line

Regex

Regular expressions in vim are more powerful than I can imagine, and I’m loving the find-and-replace, especially because you can use the pattern you matched in your replacement expression by typing \0 as part of the expression. Its so powerful.

For my next trick, I will figure out how to group parts of my pattern to use bits of them in the replacement – I feel a tutorial coming on.

Opera’s Favourite Icon

I’ve been getting wound up recently by Opera spamming my apache logs with errors about missing favicon.ico files. So here’s some instructions for removing this annoying default behaviour:

http://groups.google.co.uk/group/opera.general/browse_thread/thread/601683ed17b42762/ac5685ea6a310180?lnk=st&q=opera+favicon+request+error&rnum=1#ac5685ea6a310180

Symptom

You’ll spot the problem because there will be lines in the apache error.log file which look like this (this error is from a windows machine)

File does not exist: C:/www/favicon.ico, referer:

Normally, on a public website, I’d ignore this unless you do have a favicon set up. However I’m developing locally and so its my copy of Opera that is causing this crud in the files.