Changeset 5349

Show
Ignore:
Timestamp:
09/03/08 14:46:32 (4 months ago)
Author:
deets
Message:

added elixir support + identity implementations for that

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/tg.devtools/trunk/devtools/commands/quickstart.py

    r5130 r5349  
    105105            help="dry run (don't actually do anything)", 
    106106            action="store_true", dest="dry_run") 
     107    parser.add_option("-e", "--elixir",  
     108            help="use elixir as ORM.", action="store_true", 
     109            dest="elixir", default = False,) 
     110 
    107111 
    108112    def command(self): 
  • projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/model/identity.py_tmpl

    r5169 r5349  
    11{{if identity == "sqlalchemy"}} 
     2{{if not elixir}} 
    23import md5 
    34import sha 
     
    173174    groups = relation(Group, secondary=group_permission_table, 
    174175                      backref='permissions') 
    175  
    176176{{endif}} 
     177{{if elixir}} 
     178 
     179from sqlalchemy.orm import scoped_session, sessionmaker 
     180from datetime import datetime 
     181import elixir 
     182from elixir import Entity, Field 
     183from elixir import DateTime, Unicode 
     184from elixir import using_options 
     185from elixir import ManyToMany 
     186 
     187from tg import config 
     188 
     189# Global session manager.  DBSession() returns the session object 
     190# appropriate for the current web request. 
     191maker = sessionmaker(autoflush=True, autocommit=False) 
     192DBSession = scoped_session(maker) 
     193 
     194metadata = elixir.metadata 
     195 
     196metadata.bind = "sqlite:///:memory:" 
     197metadata.bind.echo = True 
     198 
     199class User(Entity): 
     200    """Reasonably basic User definition. Probably would want additional 
     201    attributes. 
     202    """ 
     203    using_options(tablename="tg_user", auto_primarykey="user_id") 
     204 
     205    user_name = Field(Unicode(16), required=True, unique=True) 
     206     
     207    email_address = Field(Unicode(255), required=True, unique=True) 
     208 
     209    display_name = Field(Unicode(255)) 
     210 
     211    created = Field(DateTime, default=datetime.now) 
     212 
     213    _password = Field(Unicode(40), colname="password", required=True) 
     214 
     215    groups = ManyToMany( 
     216        "Group", 
     217        inverse="users", 
     218        tablename="tg_user_group", 
     219        local_colname="group_id", 
     220        remote_colname="user_id", 
     221        ) 
     222     
     223    def __repr__(self): 
     224        return '<User: email="%s", display name="%s">' % ( 
     225                self.email_address, self.display_name) 
     226 
     227 
     228 
     229    @property 
     230    def permissions(self): 
     231        perms = set() 
     232        for g in self.groups: 
     233            perms = perms | set(g.permissions) 
     234        return perms 
     235 
     236    @classmethod 
     237    def by_email_address(cls, email): 
     238        """A class method that can be used to search users 
     239        based on their email addresses since it is unique. 
     240        """ 
     241        return DBSession.query(cls).filter(cls.email_address==email).first() 
     242 
     243    @classmethod 
     244    def by_user_name(cls, username): 
     245        """A class method that permits to search users 
     246        based on their user_name attribute. 
     247        """ 
     248        return DBSession.query(cls).filter(cls.user_name==username).first() 
     249 
     250 
     251    def _set_password(self, password): 
     252        """encrypts password on the fly using the encryption 
     253        algo defined in the configuration 
     254        """ 
     255        algorithm = config.get('authorize.hashmethod', None) 
     256        self._password = self.__encrypt_password(algorithm, password) 
     257 
     258    def _get_password(self): 
     259        """returns password 
     260        """ 
     261        return self._password 
     262 
     263    password = descriptor=property(_get_password, _set_password) 
     264 
     265    def __encrypt_password(self, algorithm, password): 
     266        """Hash the given password with the specified algorithm. Valid values 
     267        for algorithm are 'md5' and 'sha1'. All other algorithm values will 
     268        be essentially a no-op.""" 
     269        hashed_password = password 
     270 
     271        if isinstance(password, unicode): 
     272            password_8bit = password.encode('UTF-8') 
     273 
     274        else: 
     275            password_8bit = password 
     276 
     277        if "md5" == algorithm: 
     278            hashed_password = md5.new(password_8bit).hexdigest() 
     279 
     280        elif "sha1" == algorithm: 
     281            hashed_password = sha.new(password_8bit).hexdigest() 
     282 
     283        # TODO: re-add the possibility to provide own hasing algo 
     284        # here... just get the real config... 
     285 
     286        #elif "custom" == algorithm: 
     287        #    custom_encryption_path = turbogears.config.get( 
     288        #        "identity.custom_encryption", None ) 
     289        # 
     290        #    if custom_encryption_path: 
     291        #        custom_encryption = turbogears.util.load_class( 
     292        #            custom_encryption_path) 
     293 
     294        #    if custom_encryption: 
     295        #        hashed_password = custom_encryption(password_8bit) 
     296 
     297        # make sure the hased password is an UTF-8 object at the end of the 
     298        # process because SQLAlchemy _wants_ a unicode object for Unicode columns 
     299        if not isinstance(hashed_password, unicode): 
     300            hashed_password = hashed_password.decode('UTF-8') 
     301 
     302        return hashed_password 
     303 
     304    def validate_password(self, password): 
     305        """Check the password against existing credentials. 
     306        """ 
     307        identity = config.get('identity', None) 
     308        if identity is None: 
     309            return password 
     310        algorithm = identity.get('password_encryption_method', None) 
     311        return self.password == self.__encrypt_password(algorithm, password) 
     312 
     313 
     314class Group(Entity): 
     315    """An ultra-simple group definition. 
     316    """ 
     317    using_options(tablename="tg_group", auto_primarykey="group_id") 
     318     
     319    group_name = Field(Unicode(16), unique=True) 
     320     
     321    display_name = Field(Unicode(255)) 
     322     
     323    created = Field(DateTime, default=datetime.now) 
     324     
     325    users = ManyToMany("User") 
     326 
     327    permissions = ManyToMany( 
     328        "Permission", 
     329        inverse="groups", 
     330        tablename="tg_group_permission", 
     331        local_colname="group_id", 
     332        remote_colname="permission_id", 
     333        ) 
     334 
     335    def __repr__(self): 
     336        return '<Group: name=%s>' % self.group_name 
     337 
     338 
     339class Permission(Entity): 
     340    """A relationship that determines what each Group can do 
     341    """ 
     342    using_options(tablename="tg_permission", auto_primarykey="permission_id") 
     343     
     344    permission_name = Field(Unicode(16), unique=True) 
     345     
     346    description = Field(Unicode(255)) 
     347 
     348    groups = ManyToMany("Group") 
     349     
     350{{endif}} 
     351{{endif}} 
  • projects/tg.devtools/trunk/devtools/templates/turbogears/+package+/model/__init__.py_tmpl

    r5169 r5349  
    44from zope.sqlalchemy import ZopeTransactionExtension 
    55from sqlalchemy.orm import scoped_session, sessionmaker 
     6{{if not elixir}} 
    67#from sqlalchemy import MetaData 
    78from sqlalchemy.ext.declarative import declarative_base 
    8  
     9{{endif}} 
     10{{if elixir}} 
     11import elixir 
     12{{endif}} 
    913 
    1014# Global session manager.  DBSession() returns the session object 
     
    1721# extension, but if you need more control, you can switch to the traditional 
    1822# method. 
     23{{if not elixir}} 
    1924DeclarativeBase = declarative_base() 
    2025 
     
    2227# The default metadata is the one from the declarative base. 
    2328metadata = DeclarativeBase.metadata 
     29{{endif}} 
     30{{if elixir}} 
     31metadata = elixir.metadata 
     32{{endif}} 
    2433# If you have multiple databases with overlapping table names, you'll need a 
    2534# metadata for each database. Feel free to rename 'metadata2'. 
     
    6271{{endif}} 
    6372 
     73{{if elixir}} 
     74# setup the elixir models 
     75elixir.setup_all() 
     76{{endif}}