Changeset 3258
- Timestamp:
- 05/26/07 08:35:08 (1 year ago)
- Files:
-
- trunk/Schevo/doc/SchevoSchemaDefinition.txt (modified) (3 diffs)
- trunk/Schevo/schevo/field.py (modified) (8 diffs)
- trunk/Schevo/schevo/fieldspec.py (modified) (1 diff)
- trunk/Schevo/schevo/icon/__init__.py (modified) (1 diff)
- trunk/Schevo/schevo/icon/schema (deleted)
- trunk/Schevo/schevo/identity (deleted)
- trunk/Schevo/setup.py (modified) (1 diff)
- trunk/Schevo/tests/test_calculated_field_unicode.py (modified) (2 diffs)
- trunk/Schevo/tests/test_field.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Schevo/doc/SchevoSchemaDefinition.txt
r3233 r3258 486 486 487 487 488 HashedValue field type 489 ...................... 488 HashedValue field types 489 ....................... 490 490 491 491 A **HashedValue** field, upon having its value set, will store a 492 492 one-way hash of that value. 493 493 494 You can use the `compare(value)` method of a `HashedValue` field to 495 see if the hash matches a value, but it is not possible to retrieve 496 the original value from the one-way hash. 494 Use the `compare(value)` method of a `HashedValue` field instance to 495 see if the hash matches a value. 496 497 It is not possible to retrieve the original value from the one-way 498 hash. 499 500 **HashedPassword** fields are a convenience class to show that a field 501 specifically stores hashed values of passwords. 497 502 498 503 This is useful for storing information about a user's password in a … … 522 527 field, but that it is a multiple-line field. 523 528 524 **Password** fields are used to store plaintext Unicode strings. An525 application may assume that the contents of a `Password` field should526 not be displayed as plaintext. **NOTE:** `Password` fields are not527 necessarily secure. You may wish to use the `HashedValue field type`_528 instead.529 530 529 531 530 Blob fields … … 577 576 Custom field types 578 577 .................. 578 579 580 Deprecated field types 581 ...................... 582 583 Deprecated field types are those field types that are available in 584 Schevo in order to support legacy schemata, but are no longer 585 recommended for use. 586 587 If you have a database schema that uses any of these field types, you 588 should use a different field type instead. 589 590 When you use a deprecated field type, Schevo will give a Python 591 `DeprecationWarning` about such use to encourage you to use a 592 different field type. 593 594 The following types of fields are deprecated: 595 596 - **Password**: Use one of the `HashedValue field types`_ instead. 597 598 If you wish to store a plain-text password in your schema, you can 599 do one of the following: 600 601 * Use the `Unicode` field type:: 602 603 class Foo(E.Entity): 604 password = f.unicode() 605 606 * Create a custom `PlaintextPassword` field type:: 607 608 class PlaintextPassword(F.Unicode): 609 pass 610 611 class Foo(E.Entity): 612 password = f.plaintext_password() 579 613 580 614 trunk/Schevo/schevo/field.py
r3236 r3258 190 190 was = None 191 191 192 _deprecated_class = False 193 _deprecated_class_see_also = None 192 194 _name = None 193 195 … … 479 481 480 482 class HashedValue(Field): 481 """Field which stores a value as a one-way hash. 482 483 Useful for storing passwords. 483 """Field that stores a value as a one-way hash. 484 484 485 485 When you assign or set the value of this field, it stores a … … 487 487 value itself. To see if another plaintext value 'matches' the 488 488 stored hash, use the compare() method. 489 490 When a unicode value, as opposed to a string value, is given to 491 hash or to compare to an existing hash, it will be encoded to a 492 UTF-8 encoded string before the hash or comparison operation 493 occurs. 489 494 490 495 hash_header: The value that is prepended to all hashed values, to … … 525 530 if value is UNASSIGNED: 526 531 return value 527 if value.startswith(self.hash_header):532 if isinstance(value, str) and value.startswith(self.hash_header): 528 533 # Short-circuit if the value is already hashed. 529 534 return value 530 535 else: 536 if isinstance(value, unicode): 537 value = value.encode('utf8') 531 538 return self.hash_encode(value) 532 539 … … 540 547 algorithm. 541 548 """ 549 if isinstance(value, unicode): 550 value = value.encode('utf8') 542 551 header_len = len(self.hash_header) 543 552 salt = hashed_value[header_len:header_len+12] … … 563 572 564 573 574 class HashedPassword(HashedValue): 575 """Field that stores a password as a one-way hash.""" 576 577 578 # -------------------------------------------------------------------- 579 580 565 581 class String(Field): 566 582 """String field class. … … 642 658 643 659 data_type = unicode 644 645 646 class Password(Unicode):647 """Password field class.648 649 Intended to designate a unicode field as something that stores a650 plaintext string, but whose value shouldn't be exposed in a UI.651 """652 653 data_type = unicode654 655 def __unicode__(self):656 v = self.get()657 if v is UNASSIGNED:658 return Field.__unicode__(self)659 else:660 return u'(Hidden)'661 662 def reversible(self, value=None):663 return u''664 660 665 661 … … 1561 1557 1562 1558 1559 # -------------------------------------------------------------------- 1560 1561 1562 class Password(Unicode): 1563 """Password field class. 1564 1565 Intended to designate a unicode field as something that stores a 1566 plaintext string, but whose value shouldn't be exposed in a UI. 1567 """ 1568 1569 data_type = unicode 1570 1571 _deprecated_class = True 1572 _deprecated_class_see_also = 'http://schevo.org/wiki/SchevoSchemaDefinition' 1573 1574 def __unicode__(self): 1575 v = self.get() 1576 if v is UNASSIGNED: 1577 return Field.__unicode__(self) 1578 else: 1579 return u'(Hidden)' 1580 1581 def reversible(self, value=None): 1582 return u'' 1583 1584 1563 1585 optimize.bind_all(sys.modules[__name__]) # Last line of module. 1564 1586 trunk/Schevo/schevo/fieldspec.py
r3112 r3258 167 167 ) 168 168 warn(msg, DeprecationWarning, 2) 169 # Warn about class deprecation if this class is deprecated. 170 if _Field._deprecated_class: 171 msg = ( 172 "%r is a deprecated field type. " 173 'See %s for more information.' 174 % (self.__class__.__name__, _Field._deprecated_class_see_also) 175 ) 176 warn(msg, DeprecationWarning, 2) 169 177 170 178 def __call__(self, fn): trunk/Schevo/schevo/icon/__init__.py
r1877 r3258 14 14 # Needs to be imported right away. 15 15 import schevo.entity 16 import schevo.icon.schema17 16 18 17 trunk/Schevo/setup.py
r3112 r3258 114 114 db = schevo.script.db:start 115 115 shell = schevo.script.shell:start 116 117 [schevo.schema_export]118 icon=schevo.icon.schema119 identity=schevo.identity.schema120 116 """, 121 117 ) trunk/Schevo/tests/test_calculated_field_unicode.py
r3112 r3258 15 15 class Thing(E.Entity): 16 16 image = f.image() 17 password = f. password()17 password = f.hashed_password() 18 18 @f.image() 19 19 def calc_image(self): 20 20 return self.image 21 @f. password()21 @f.hashed_password() 22 22 def calc_password(self): 23 23 return self.password … … 31 31 # Unicode reprs of fields on thing itself. 32 32 assert unicode(thing.f.image) == u'(Binary data)' 33 assert unicode(thing.f.password) == u'( Hidden)'33 assert unicode(thing.f.password) == u'(Encrypted)' 34 34 assert unicode(thing.f.calc_image) == u'(Binary data)' 35 assert unicode(thing.f.calc_password) == u'( Hidden)'35 assert unicode(thing.f.calc_password) == u'(Encrypted)' 36 36 # Unicode reprs of fields on thing's default view. 37 37 thing_view = thing.v.default() 38 38 assert unicode(thing_view.f.image) == u'(Binary data)' 39 assert unicode(thing_view.f.password) == u'( Hidden)'39 assert unicode(thing_view.f.password) == u'(Encrypted)' 40 40 assert unicode(thing_view.f.calc_image) == u'(Binary data)' 41 assert unicode(thing_view.f.calc_password) == u'( Hidden)'41 assert unicode(thing_view.f.calc_password) == u'(Encrypted)' 42 42 43 43 trunk/Schevo/tests/test_field.py
r3112 r3258 531 531 532 532 533 class Test Password(object):533 class TestHashedPassword(object): 534 534 535 535 def test_unicode_representation(self): 536 f = field. Password(None, None)536 f = field.HashedPassword(None, None) 537 537 f.set('some-password') 538 assert unicode(f) == u'(Hidden)' 538 assert unicode(f) == u'(Encrypted)' 539 540 def test_unicode_values(self): 541 f = field.HashedPassword(None, None) 542 value = u'some-unicode-password-\ucafe' 543 f.set(value) 544 assert f.compare(value) 545 546 547 class TestPasswordIsDeprecated(object): 548 549 """ 550 Change `showwarning` to log to a list instead of to stderr, so we 551 can test the deprecation warning below:: 552 553 >>> import warnings 554 >>> old_showwarning = warnings.showwarning 555 >>> captured_warnings = [] 556 >>> def showwarning(message, category, filename, lineno, file=None): 557 ... captured_warnings.append((message, category, filename, lineno)) 558 >>> warnings.showwarning = showwarning 559 560 Create a schema that has a `password` field class:: 561 562 >>> body = ''' 563 ... class Foo(E.Entity): 564 ... 565 ... p = f.password() 566 ... ''' 567 568 When using the schema, a deprecation warning is given for the `p` 569 field definition:: 570 571 >>> from schevo.test import DocTest 572 >>> len_before = len(captured_warnings) 573 >>> t = DocTest(body) 574 >>> len_after = len(captured_warnings) 575 >>> len_after - len_before 576 1 577 >>> message, category, filename, lineno = captured_warnings[-1] 578 >>> print str(message) #doctest: +ELLIPSIS 579 'password' is a deprecated field type. ... 580 581 The line number that the warning is on appears to be line four 582 above, but since a two-line header is prepended to the body during 583 unit testing, it's actually line six that the warning occurs at:: 584 585 >>> lineno 586 6 587 588 Place the old `showwarning` function back into the `warnings` 589 module:: 590 591 >>> warnings.showwarning = old_showwarning 592 593 """ 539 594 540 595
