{ "info": { "author": "Chris McDonough, Florent Aide, Christopher Perkins", "author_email": "repoze-dev@lists.repoze.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 1 - Planning", "Intended Audience :: Developers", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application" ], "description": "Sample repoze.who middleware config and plugins for TG2. This package\ndepends on repoze.who 0.8 or better.\n\nTrying it Out\n\n - Install TG2 into a virtualenv.\n\n - Install this package into the same virtualenv via \"setup.py\n install\".\n\n - Create a TG2 quickstart project using the virtualenv's python.\n\n - In the development.ini of you project...\n\n - In the config.middleware module of your project, add the following\n just under \"CUSTOM MIDDLEWARE HERE\"::\n\n # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)\n\n from tgrepozewho.middleware import make_who_middleware\n app = make_who_middleware(app, config, User, user_criterion, user_id_col,\n DBSession)\n\n - Add the following definitions in you model.__init__::\n\ngroups_table = Table('tg_group', metadata,\n Column('group_id', Integer, primary_key=True),\n Column('group_name', Unicode(16), unique=True),\n Column('display_name', Unicode(255)),\n Column('created', DateTime, default=datetime.datetime.now)\n)\n\nusers_table = Table('tg_user', metadata,\n Column('user_id', Integer, primary_key=True),\n Column('user_name', Unicode(16), unique=True),\n Column('email_address', Unicode(255), unique=True),\n Column('display_name', Unicode(255)),\n Column('password', Unicode(40)),\n Column('created', DateTime, default=datetime.datetime.now)\n)\n\npermissions_table = Table('tg_permission', metadata,\n Column('permission_id', Integer, primary_key=True),\n Column('permission_name', Unicode(16), unique=True),\n Column('description', Unicode(255))\n)\n\nuser_group_table = Table('tg_user_group', metadata,\n Column('user_id', Integer, ForeignKey('tg_user.user_id',\n onupdate=\"CASCADE\", ondelete=\"CASCADE\")),\n Column('group_id', Integer, ForeignKey('tg_group.group_id',\n onupdate=\"CASCADE\", ondelete=\"CASCADE\"))\n)\n\ngroup_permission_table = Table('tg_group_permission', metadata,\n Column('group_id', Integer, ForeignKey('tg_group.group_id',\n onupdate=\"CASCADE\", ondelete=\"CASCADE\")),\n Column('permission_id', Integer, ForeignKey('tg_permission.permission_id',\n onupdate=\"CASCADE\", ondelete=\"CASCADE\"))\n)\n\n# identity model\nclass Group(object):\n \"\"\"An ultra-simple group definition.\n \"\"\"\n def __repr__(self):\n return '' % self.group_name\n\nclass User(object):\n \"\"\"Reasonably basic User definition. Probably would want additional\n attributes.\n \"\"\"\n def __repr__(self):\n return '' % (\n self.email_address, self.display_name)\n\n def permissions(self):\n perms = set()\n for g in self.groups:\n perms = perms | set(g.permissions)\n return perms\n permissions = property(permissions)\n\n def by_email_address(klass, email):\n \"\"\"A class method that can be used to search users\n based on their email addresses since it is unique.\n \"\"\"\n session = DBSession()\n return session.query(klass).filter(klass.email_address==email).first()\n\n by_email_address = classmethod(by_email_address)\n\n def by_user_name(klass, username):\n \"\"\"A class method that permits to search users\n based on their user_name attribute.\n \"\"\"\n session = DBSession()\n return session.query(klass).filter(klass.user_name==username).first()\n\n by_user_name = classmethod(by_user_name)\n\n def _set_password(self, password):\n \"\"\"encrypts password on the fly using the encryption\n algo defined in the configuration\n \"\"\"\n algorithm = config.get('authorize.hashmethod', None)\n self._password = self.__encrypt_password(algorithm, password)\n\n def _get_password(self):\n \"\"\"returns password\n \"\"\"\n return self._password\n\n password = property(_get_password, _set_password)\n\n def __encrypt_password(self, algorithm, password):\n \"\"\"Hash the given password with the specified algorithm. Valid values\n for algorithm are 'md5' and 'sha1'. All other algorithm values will\n be essentially a no-op.\"\"\"\n hashed_password = password\n\n if isinstance(password, unicode):\n password_8bit = password.encode('UTF-8')\n\n else:\n password_8bit = password\n\n if \"md5\" == algorithm:\n hashed_password = md5.new(password_8bit).hexdigest()\n\n elif \"sha1\" == algorithm:\n hashed_password = sha.new(password_8bit).hexdigest()\n\n # TODO: re-add the possibility to provide own hasing algo\n # here... just get the real config...\n\n #elif \"custom\" == algorithm:\n # custom_encryption_path = turbogears.config.get(\n # \"identity.custom_encryption\", None )\n #\n # if custom_encryption_path:\n # custom_encryption = turbogears.util.load_class(\n # custom_encryption_path)\n\n # if custom_encryption:\n # hashed_password = custom_encryption(password_8bit)\n\n # make sure the hased password is an UTF-8 object at the end of the\n # process because SQLAlchemy _wants_ a unicode object for Unicode columns\n if not isinstance(hashed_password, unicode):\n hashed_password = hashed_password.decode('UTF-8')\n\n return hashed_password\n\n def validate_password(self, password):\n \"\"\"Check the password against existing credentials.\n \"\"\"\n algorithm = config.get('authorize.hashmethod', None)\n return self.password == self.__encrypt_password(algorithm, password)\n\nclass Permission(object):\n \"\"\"A relationship that determines what each Group can do\n \"\"\"\n pass\n\nmapper(User, users_table,\n properties=dict(_password=users_table.c.password))\n\nmapper(Group, groups_table,\n properties=dict(users=relation(User,\n secondary=user_group_table, backref='groups')))\n\nmapper(Permission, permissions_table,\n properties=dict(groups=relation(Group,\n secondary=group_permission_table, backref='permissions')))\n\n\n - Add the following import in you controllers.root file::\n\n from tgrepozewho import authorize\n\n - Add the following methods to your controllers.root:RootController\n class::\n\n @expose('whotg.templates.about')\n @authorize.require(authorize.has_permission('manage'))\n def manage_permission_only(self, **kw):\n return dict(now=now, page='about')\n \n @expose('whotg.templates.about')\n @authorize.require(authorize.is_user('editor'))\n def editor_user_only(self, **kw):\n return dict(now=now, page='about')\n\n @expose('whotg.templates.login')\n def login(self, **kw):\n came_from = kw.get('came_from', '/')\n return dict(now=now, page='login', header=lambda *arg: None,\n footer=lambda *arg: None, came_from=came_from)\n\n\n\n - Add the following template as \"login.html\" into your project's\n 'templates' directory::\n\n \n \n\n \n\n \n \n Login Form\n \n\n \n\n
\n Login:
\n Password:
\n \n
\n\n \n \n\n - Setup you database config in the normal way by tweaking the development.ini file\n\n - Create the necessary tables by using::\n\n paster setup-app development.ini\n\n - Create a user manually in your database\n\n - Create a group (any name), and a permission named \"manage\", link this permission\n to the group you just created and also add a user to your group.\n\n - Create another user which is in no group but is named \"editor\"\n\n - Start the project's server via paster serve::\n\n paster server --reload development.ini\n\n - Visit http://localhost:8080/editor_user_only in your browser. You\n will be presented with the login form. The \"right\"\n username/password combination is \"editor/editpass\" (this user has the\n username 'editor'). Submitting this set of credentials will show\n the about page. Any other username/password combination will\n result in the user being presented the login form again. Note that\n once you've obtained the credentials for the first time, if you\n visit the /editor_user_only page again, you are not asked to\n reauthenticate. Log out forcibly by visiting\n http://localhost:8080/logout_handler.\n\n - Visit http://localhost:8080/manage_permission_only in your browser.\n You will be presented with the login form. The \"right\"\n username/password combination is \"manager/managepass\" (this user\n possesses the manage permission). Submitting this set of\n credentials will show the about page. Any other username/password\n combination will result in the user being presented the login form\n again. Note that if you've authenticated as the 'editor' user, and\n you visit the /manage_permission_only page, you will be logged out\n and asked for credentials (editors cannot see this page). Note\n that once you've obtained the credentials for the first time, if\n you visit the /manage_permission_only page again, you are not asked\n to reauthenticate. Log out forcibly by visiting\n http://localhost:8080/logout_handler.\n\nMisc\n\n If you start \"paster serve\" in a shell with the WHO_LOG environment\n variable set to \"1\", you will see repoze.who logging output on the\n console.\n\nNot yet finished\n\n You can run the unit tests by using \"python setup.py test\" in the\n source package.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://www.repoze.org", "keywords": "web application server wsgi tg2", "license": "BSD-derived (http://www.repoze.org/LICENSE.txt)", "maintainer": null, "maintainer_email": null, "name": "tg.ext.repoze.who", "package_url": "https://pypi.org/project/tg.ext.repoze.who/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/tg.ext.repoze.who/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://www.repoze.org" }, "release_url": "https://pypi.org/project/tg.ext.repoze.who/0.1-r26/", "requires_dist": null, "requires_python": null, "summary": "tg.ext.repoze.who are repoze.who plugins for TurboGears 2", "version": "0.1-r26" }, "last_serial": 800517, "releases": { "0.1-r11": [ { "comment_text": "", "digests": { "md5": "ef9217434b8ad0a11234393d3eddd792", "sha256": "0405611607e0f3117534616f6fef2290f2a1250b8fdcf1d92ef6307c8293fd86" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1_r11-py2.5.egg", "has_sig": false, "md5_digest": "ef9217434b8ad0a11234393d3eddd792", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 17187, "upload_time": "2008-06-01T22:19:48", "url": "https://files.pythonhosted.org/packages/3c/41/2e898980bd637995adb82c103a2533bf759ab64a66832a59c60437936427/tg.ext.repoze.who-0.1_r11-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "7179123346935d780b46b00015436c6a", "sha256": "b9fd03490af6c28e95483b654e16026012d00496d11f281037c74312c39c3672" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1-r11.tar.gz", "has_sig": false, "md5_digest": "7179123346935d780b46b00015436c6a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18982, "upload_time": "2008-06-01T22:19:46", "url": "https://files.pythonhosted.org/packages/ff/27/b584a085d05fa34d6206c19d2dcbab2e62769c7d0ddaf47b6e69022db3e5/tg.ext.repoze.who-0.1-r11.tar.gz" } ], "0.1-r26": [ { "comment_text": "", "digests": { "md5": "f3c16ec5651fab57c7355731f837d46c", "sha256": "c9558a69528e8c28bb8162e8315ca1f92db1a9a3a0cf0ab722de86f3bd76aecd" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1_r26-py2.5.egg", "has_sig": false, "md5_digest": "f3c16ec5651fab57c7355731f837d46c", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 17194, "upload_time": "2008-06-04T15:12:04", "url": "https://files.pythonhosted.org/packages/4c/10/5f0b7f9cad20da6619153b698226444c21848265191bb6390b0c3ca28573/tg.ext.repoze.who-0.1_r26-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "91c6166158fe7c2ceafe41d1abd8daf4", "sha256": "dbbc5323eadd4ef8ddaad83016158caf624276abf2c4296f27e1de1652d91672" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1-r26.tar.gz", "has_sig": false, "md5_digest": "91c6166158fe7c2ceafe41d1abd8daf4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19009, "upload_time": "2008-06-04T15:12:03", "url": "https://files.pythonhosted.org/packages/3a/16/ad3f6e5ee2d1b7364505131914882f7056b2fb2ea4e98b1c97ff2754cef1/tg.ext.repoze.who-0.1-r26.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f3c16ec5651fab57c7355731f837d46c", "sha256": "c9558a69528e8c28bb8162e8315ca1f92db1a9a3a0cf0ab722de86f3bd76aecd" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1_r26-py2.5.egg", "has_sig": false, "md5_digest": "f3c16ec5651fab57c7355731f837d46c", "packagetype": "bdist_egg", "python_version": "2.5", "requires_python": null, "size": 17194, "upload_time": "2008-06-04T15:12:04", "url": "https://files.pythonhosted.org/packages/4c/10/5f0b7f9cad20da6619153b698226444c21848265191bb6390b0c3ca28573/tg.ext.repoze.who-0.1_r26-py2.5.egg" }, { "comment_text": "", "digests": { "md5": "91c6166158fe7c2ceafe41d1abd8daf4", "sha256": "dbbc5323eadd4ef8ddaad83016158caf624276abf2c4296f27e1de1652d91672" }, "downloads": -1, "filename": "tg.ext.repoze.who-0.1-r26.tar.gz", "has_sig": false, "md5_digest": "91c6166158fe7c2ceafe41d1abd8daf4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19009, "upload_time": "2008-06-04T15:12:03", "url": "https://files.pythonhosted.org/packages/3a/16/ad3f6e5ee2d1b7364505131914882f7056b2fb2ea4e98b1c97ff2754cef1/tg.ext.repoze.who-0.1-r26.tar.gz" } ] }