老韩
23二/101

取得某个文件夹下所有同类型文件

PHP有一个模块叫做mime_magic,用来判断文件的类型非常有效。使用它的mime_content_type函数,结合递归可以很方便的把某一个文件夹下的所同类型文件找出来,比如我因为某种需求要取出某个文件夹下所有的纯文本文件,即是写了一小段代码来递归(代码片段见下文)。

当然,这里并不是展示什么技巧性的东西,只是介绍性的说明一下有这样一个模块。记得很多年前初学写程序时,是根据文件的后缀来判断文件类型的,显然这是一件多么不靠谱的事情,如果现在还有人这么干,我想是要被耻笑的吧?脚本语言讨人喜爱之处就是它总是为我们提供很多很实用的库,这大大降低了我们的开发成本以及提高了开发效率,虽然,也因此增加了选择成本。比如我们刚刚所说的判断文件类型,即有人建议用PECL的FileInfo库来做。

需要连带说明一下,在Python中对MIME类型的处理,也有内置的一个模块叫mimetypes,可以很方便的取得一个文件的类型。

  1. >>> import mimetypes
  2. >>> mimetypes.guess_type('/home/handaoliang/bodybg.jpg')
  3. ('image/jpeg', None)

PHP取得某文件夹下所有的纯文本文件:

  1. #!/var/iapps/php/bin/php
  2. <?php
  3. class listFiles{
  4.     public $fileLists;
  5.  
  6.     public function __construct(){
  7.         $this->fileLists = array();
  8.     }
  9.  
  10.     public function excuteList($baseDirName)
  11.     {
  12.         $myDirObj = dir($baseDirName);
  13.  
  14.         while($fileName = $myDirObj->read()){
  15.             //如果获取到的文件属性是目录,并且不是.或者..,则再遍历一次。
  16.             if((is_dir($baseDirName."/".$fileName)) && ($fileName != ".") && ($fileName != "..")){
  17.                 listFiles::excuteList("$baseDirName/$fileName");
  18.             }else if(($fileName != ".") && ($fileName != "..")){
  19.                 //判断类型,将文本文件放到数组里。
  20.                 if("text/plain" == mime_content_type($baseDirName."/".$fileName)){
  21.                     array_push($this->fileLists,$baseDirName."/".$fileName);
  22.                 }
  23.                 //echo mime_content_type($baseDirName."/".$fileName)."\n";
  24.                 //$this->getFileType($baseDirName."/".$fileName);
  25.                 //echo "\n";
  26.                 //echo $baseDirName."/".$fileName."\n";
  27.             }
  28.         }
  29.  
  30.         $myDirObj->close();
  31.     }
  32. }
  33.  
  34. $fileListObj = new listFiles();
  35. $fileListObj->excuteList("/home/handaoliang/meeuu.com");
  36. $fileLists = $fileListObj->fileLists;
  37. print_r($fileLists);
  38. ?>
分类: PHP, Python 1个评论
22二/100

给ClueMapper加上LDAP验证功能

一、什么是ClueMapper?

关于ClueMapper(官方网站:http://www.cluemapper.org)是什么东东,还是直接翻译它自己的文档吧:ClueMapper是一套基于WEB的、用于软件或者软件项目管理的应用程序,目前使用Trac来管理单个项目,同时增加了新建Trac实例、支持配置SVN等功能(ClueMapper is a web-based application for managing software and software-based consulting projects. Currently it uses Trac to handle individual projects but adds the ability to create new trac instances, svn configurations, etc.)简而言之:ClueMapper是一个基于Trac的(最新版使用的Trac版本是:Trac-0.11.1)、并且可新增Trac实例的多项目管理软件,并且支持SVN。因为基于Trac,所以ClueMapper也是Python语言环境下运行的软件。

ClueMapper的认证机制并没有延用Trac的机制,而是自己独立做了一系列的改进,主要是加入了repoze.who这个WSGI中间件,这样的话就意味着,只要repoze.who支持的登录方式,ClueMapper都支持,比如basicauth、htpasswd等。

然而不幸的是,在repoze.who支持的诸多认证方式中,恰恰没有ldap的验证支持,这就使得我们必须对ClueMapper的代码进行改进,以加进Ldap的认证支持进去。

  
二、安装和准备

1、安装ClueMapper
关于ClueMapper的安装,只简单的介绍几句,参照ClueMapper的安装文档可以很快上手:
去SVN取得CueMapper的源代码,编译即可。当然,在编译之前,需要先确定是否安装了Python的libxslt和sqlite3支持:

  1. svn co http://www.cluemapper.org/svn/buildout/trunk cluemapper
  2. cd cluemapper
  3. python bootstrap.py
  4. bin/buildout

buildout的过程会稍微慢一点,因为要下载一些包,等到Buildout完成,运行:
./bin/clue-server
不出意外的话,应该会看到如下提示:
2010-02-22 15:39:14,245 INFO [cluemapper] ClueMapper v0.8.4dev-r0-20100222 starting...
2010-02-22 15:39:14,246 INFO [cluemapper] Using configuration at 'etc/cluemapper/cluemapper.ini'
2010-02-22 15:39:14,246 INFO [cluemapper] Listening on ALL INTERFACES, port 8080
2010-02-22 15:39:14,246 INFO [cluemapper] Browse at http://127.0.0.1:8080

此时ClueMapper监听在8080端口。当然,如果系统的Python环境是2.6以上版本,则会碰到类似“DeprecationWarning: the md5 module is deprecated; use hashlib instead import md5”的Warning,这是因为Python2.6以后,不建议直接import md5模块的原因所导致,如果要去掉这个warning,只需要在所有import md5的地方,将之替换为import hashlib模块即可:
hashlib的MD5 Hash函数用法:

  1. import hashlib
  2. _s = hashlib.md5("hash string").hexdigest();

2、安装LDAP
其实自己编译安装ldap,是最靠谱的方法,虽然之前写过介绍Ubuntu下使用apt-get install方法安装ldap的文章,但个人其实非常反感apt-get安装的方式,更喜欢手动Configure安装(貌似是BSD系技术人员的通病?呵呵),安装Ldap之前,需要先安装BDB,我推荐使用BDB做为LDAP的支援数据库。

  1. wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-2.4.21.tgz
  2. tar xzvf openldap-2.4.21.tgz
  3. ./configure --prefix=/var/iapps/ldap
  4. make && make depend
  5. make install

配置ldap的Conf文件:

  1. $sudo vi /var/iapps/ldap/etc/openldap/slapd.conf

在头部加上:

  1. include     /var/iapps/ldap/etc/openldap/schema/core.schema
  2. # added by handaoliang...
  3. include /var/iapps/ldap/etc/openldap/schema/cosine.schema
  4. include /var/iapps/ldap/etc/openldap/schema/misc.schema
  5. include /var/iapps/ldap/etc/openldap/schema/inetorgperson.schema
  6. include /var/iapps/ldap/etc/openldap/schema/openldap.schema
  7. include /var/iapps/ldap/etc/openldap/schema/nis.schema

在最后加上:

  1. database    bdb
  2. suffix      "dc=handaoliang,dc=com"
  3. rootdn      "cn=Manager,dc=handaoliang,dc=com"
  4. # Cleartext passwords, especially for the rootdn, should
  5. # be avoid.  See slappasswd(8) and slapd.conf(5) for details.
  6. # Use of strong authentication encouraged.
  7. rootpw      iloveyou
  8. # The database directory MUST exist prior to running slapd AND
  9. # should only be accessible by the slapd and slap tools.
  10. # Mode 700 recommended.
  11. directory   /var/iapps/ldap/var/openldap-data
  12. # Indices to maintain
  13. index   objectClass eq

启动Ldap:

  1. $sudo /var/iapps/ldap/libexec/slapd

导入用户,测试Ldap安装成功。

3、安装repoze.who的ldap扩展:
安装repoze.who的ldap扩展之前,需要先安装python-ldap(http://pypi.python.org/pypi/python-ldap/2.3.10):

  1. wget -c http://pypi.python.org/packages/source/p/python-ldap/python-ldap-2.3.10.tar.gz
  2. tar -xzvf python-ldap-2.3.10.tar.gz
  3. python setup.py install

安装成功,写一段代码测试一下用Python来连Ldap:

  1. #!/usr/bin/python
  2. #-*- coding:utf-8 -*-
  3.  
  4. import ldap
  5.  
  6. try:
  7.     conn = ldap.open("localhost")
  8.     conn.protocol_version = ldap.VERSION3
  9.     username = "Manager"
  10.     password = "{SSHA}2JPeP6Y+3/N2n8orp+jwKZj1TN310DBw"
  11.     conn.simple_bind(username,password)
  12. except ldap.LDAPError, e:
  13.     print e
  14.  
  15. baseDN = "ou=People,dc=handaoliang,dc=com"
  16. searchScope = ldap.SCOPE_SUBTREE
  17.  
  18. retrieveAttributes = ["cn","userPassword","loginShell","uid"]
  19. searchFilter = "cn=dev"
  20.  
  21. try:
  22.     ldap_result_id = conn.search(baseDN,searchScope,searchFilter,retrieveAttributes)
  23.     result_set = []
  24.     while 1:
  25.         result_type, result_data = conn.result(ldap_result_id, 0)
  26.         if result_data == []:
  27.             break
  28.         else:
  29.             if result_type == ldap.RES_SEARCH_ENTRY:
  30.                 result_set.append(result_data)
  31.  
  32.         #print result_set[0][0][1]['o'][0]
  33.         print result_set
  34.  
  35. except ldap.LDAPError, e:
  36.     print e

返回正确结果,说明环境已经没有问题。然后安装repoze.who的ldap扩展,注意这里不从源码包里运行setup.py安装,而是直接把源码包里的ldap代码拷贝到ClueMapper的repoze.who eggs里,这样的话就避免了安装在Python的系统Libs里,因而方便修改它的源文件,后面会讲到:
到这里下载:http://pypi.python.org/pypi/repoze.who.plugins.ldap/1.0,取得1.0版本的tar.gz包,并解压:

  1. tar xzvf repoze.who.plugins.ldap-1.0.tar.gz
  2. cp -r repoze.who.plugins.ldap-1.0/repoze/who/plugins/ldap/ /home/handaoliang/cluemapper/eggs/repoze.who-1.0.18-py2.6.egg/repoze/who/plugins/

运行bin下面的python脚本:
$./bin/python
进入到python命令行:

  1. from repoze.who.plugins import ldap as repoze_ldap
  2. help(repoze_ldap)

如果import没有出错,并且看到File为:/home/handaoliang/cluemapper/eggs/repoze.who-1.0.5-py2.6.egg/repoze/who/plugins/ldap/__init__.py,则说明安装成功。

三、对repoze.who.plugins.ldap和ClueMapper的验证文件进行修改:
1、对repoze.who.plugins.ldap的修改:

先是repoze.who的ldap扩展,此时需要编辑/home/handaoliang/cluemapper/eggs/repoze.who-1.0.5-py2.6.egg/repoze/who/plugins/ldap/plugins.py文件:
查找:import ldap
在下面加上一句:ldap.set_option(ldap.OPT_REFERRALS, 0),变成:

  1. import ldap
  2. ldap.set_option(ldap.OPT_REFERRALS, 0)

查找:self.ldap_connection.simple_bind_s(dn, password)
将下面的return dn注释掉,改成:return identity['login']
修改后的代码如下:

  1. try:
  2.     self.ldap_connection.simple_bind_s(dn, password)
  3.     # The credentials are valid!
  4.     # bug fixed by handaoliang...Return userid but not dn.
  5.     return identity['login']
  6.     #return dn
  7. except ldap.LDAPError,e:
  8.     #by handaoliang:catched this error:
  9.     #sys.stderr.write("%s\n" % e)
  10.     return None

2、对ClueMapper的验证文件进行修改,编辑src/ClueMapper/src/clue/secure/auth.py文件:

  1. $vi /home/handaoliang/cluemapper/src/ClueMapper/src/clue/secure/auth.py

查找:from repoze.who.plugins import basicauth,在后面把repoze.who.plugins.ldap包含进来:

  1. from repoze.who.plugins import basicauth
  2. #added by handaoliang
  3. from repoze.who.plugins import ldap as repoze_ldap

查找:assert passwdfile,在后面加上如下语句:

  1. #added by handaoliang
  2. #LDAP Config
  3. LDAP_BASE_HOST = 'ldap://localhost'
  4. LDAP_BASE_DN = 'ou=People,dc=handaoliang,dc=com'
  5.  
  6. #Add Plugins to repoze.who.
  7. ldap_auth = repoze_ldap.LDAPAuthenticatorPlugin(LDAP_BASE_HOST,LDAP_BASE_DN)

修改authenticators = [('ldap_auth', ldap_auth)]为authenticators = [('htpasswd', passwd),('ldap_auth', ldap_auth)]

  1. #Modified by handaoliang..
  2. #authenticators = [('ldap_auth', ldap_auth)]
  3. authenticators = [('htpasswd', passwd),('ldap_auth', ldap_auth)]

重新启动ClueMapper,访问:http://localhost:8080/此时即应该可以使用LDAP的账号密码登录。

您可以从这里下载到经过我修改的源码包:http://www.handaoliang.com/tools/fix_cluemapper.tar.gz

您可参照里面的README文件来进行安装:

#-*- coding:utf-8 -*-
INSTALL:
1.把auth.py放到$ClUEMAPPER_PATH/src/ClueMapper/src/clue/secure下面,覆盖原文件,覆盖前请备份原文件。
2.修改LDAP配置(编辑auth.py):
  A.更改LDAP_BASE_HOST为LDAP数据库的HSOT连接,如ldap://localhost
  B.更改LDAP_BASE_DN为LDAP的Base dn
  C.保存文件。
3.将ldap文件夹拷贝到repoze.who-1.0.5-py2.6.egg下的repoze/who/plugins下面。其它的无须更改。

==============================
参考文档:
http://code.gustavonarea.net/repoze.who.plugins.ldap/Using.html
http://www.packtpub.com/article/installing-and-configuring-the-python-ldap-library-and-binding-to-an-ldap-directory
http://wiki.pylonshq.com/display/pylonscookbook/Authentication+and+Authorization+with+%60repoze.who%60
http://www.openldap.org/doc/admin24/quickstart.html