示例#1
0
def registerPersistentConfig(site, type_):
    """ Try to get persistent pipeline configuration of given type (export or import)
        and register it for use with transmogrifier.
    """
    global CONFIGFILE
    anno = IAnnotations(site)
    key = '%s.%s' % (ANNOKEY, type_)
    config = anno.has_key(key) and anno[key] or None

    # unregister old config
    name = 'persitent-%s' % type_
    if name in configuration_registry._config_ids:
        configuration_registry._config_ids.remove(name)
        del configuration_registry._config_info[name]

    # register new
    if config is not None:
        title = description = u'Persistent %s pipeline'
        tf = tempfile.NamedTemporaryFile('w+t', suffix='.cfg')
        tf.write(config)
        tf.seek(0)
        CONFIGFILE = tf
        configuration_registry.registerConfiguration(name, title, description, tf.name)
        return name
    else:
        return None
    def migrate(self):
        if self.is_updated(): 
            return 'already migrated'
        
        # set the appropriate list type based on the previous settings
        # this may need to mark the appropriate interface on the mailing
        # list as well
        if self.context.moderated:
            self.context.list_type = PostModeratedListTypeDefinition
        elif self.context.closed:
            self.context.list_type = MembershipModeratedListTypeDefinition
        else:
            self.context.list_type = PublicListTypeDefinition

        # copy over the membership stuff
        annot = IAnnotations(self.context)
        listen_annot = annot.get('listen', {})
        old_subscribers = listen_annot.get('subscribers', [])

        # create the new annotations by using current adapters
        mem_list = IWriteMembershipList(self.context)
        for subscriber in old_subscribers:
            mem_list.subscribe(subscriber)

        # unsubscribe (but leave as allowed senders) those who don't 
        # receive mail
        nomail = listen_annot.get('norecvmail', [])
        for allowed_sender in nomail:
            mem_list.unsubscribe(allowed_sender)

        # copy over the moderation messages
        self.mod_post_pending_list = getAdapter(self.context, IPostPendingList, 'pending_pmod_post')
        for i in self.context.mqueue.objectIds():
            (header, body) = splitMail(self.context.mqueue[i])
            post = {'header':header, 'body':body}
            (user_name, user_email) = parseaddr(header.get('from', ''))
            self.mod_post_pending_list.add(user_email, user_name=user_name, post=post)

        # creates list managers from moderators and list owner
        managers = []
        managers.append(self.context.list_owner)
        for moderator in self.context.moderators:
            managers.append(moderator)
        self.context.managers = tuple(managers)
        convert_manager_emails_to_memberids(self.context)

        # translate archived vocabulary
        if self.context.archived == 'not archived':
            self.context.archived = 2
        elif self.context.archived == 'plain text':
            self.context.archived = 1
        elif self.context.archived == 'with attachments':
            self.context.archived = 0
        else:
            return 'error translating archive option'

        # annotate the list to say the migration completed
        self.migration_annot.append('policy_migration')

        return 'successfully migrated'
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     req_annot = annot.get(annot_key, None)
     if req_annot is None:
         req_annot = set()
         annot[annot_key] = req_annot
     self._req_store = req_annot
示例#4
0
 def afterSetUp(self):
     self.obj = Dummy()
     self.dan = IClickdates(self.obj)
     self.dan.clickDate()
     self.thisMonth = datetime.date.today().month
     self.thisYear = datetime.date.today().year
     self.annotations = IAnnotations(self.obj)
     self.date = "%s-%s" % (self.thisYear, self.thisMonth)
示例#5
0
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     wiki_annot = annot.get(annot_key, None)
     if wiki_annot is None:
         wiki_annot = IOBTree()
         annot[annot_key] = wiki_annot
     self.annot = wiki_annot
示例#6
0
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     homepage_annot = annot.get(self.KEY, None)
     if homepage_annot is None:
         homepage_annot = OOBTree()
         annot['opencore.project.browser.home_page'] = homepage_annot
     self.annot = homepage_annot
示例#7
0
 def __init__(self, context):
     self.context = context
     key = str(context)
     annotations = IAnnotations(context)
     storage = annotations.setdefault(ANNOT_KEY,
                                      PersistentMapping())
     storage.setdefault('hmac_key', key)
     self.storage = storage
示例#8
0
    def __init__(self, context):
        annotations = IAnnotations(context)
        dcdata = annotations.get(DCkey)
        if dcdata is None:
            self.annotations = annotations
            dcdata = ZDCAnnotationData()

        super(ZDCAnnotatableAdapter, self).__init__(dcdata)
 def clearMemoCache(self):
     # from the request
     req = self.portal.REQUEST
     annotations = IAnnotations(req)
     cache = annotations.get(ViewMemo.key, None)
     if cache is not None:
         annotations[ViewMemo.key] = dict()
     # from the timestamp cache
     opencore.utils.timestamp_cache.clear()
示例#10
0
 def __init__(self, context):
     self.context = context
     if self.bcrypt is None:
         return
     annotations = IAnnotations(context)
     storage = annotations.setdefault(ANNOT_KEY,
                                      PersistentMapping())
     storage.setdefault('bcrypt_salt', self.bcrypt.gensalt())
     self.storage = storage
示例#11
0
 def __init__(self, context):
     _ATCTFileAudio.__init__(self, context)
     annotations = IAnnotations(context)
     self.encoding_data = annotations.get(self.ENCODING_KEY, None)
     if self.encoding_data == None:
         self.encoding_data = PersistentDict()
         annotations[self.ENCODING_KEY] = self.encoding_data
         self.encoding_data['encoding'] = ""
         self.encoding_data['original_encoding'] = ""
示例#12
0
 def __init__(self, requester, folder):
     self.requester = requester
     self.folder = folder
     annot = IAnnotations(requester)
     req_annot = annot.get(annot_key, None)
     if req_annot is None:
         req_annot = PersistentDict()
         annot[annot_key] = req_annot
     self._req_store = req_annot
示例#13
0
 def addPath(self, path):
     path = self._make_relative(path)
     annotations = IAnnotations(self.context)
     old = annotations.get(self.key, ())
     fixed = map(self._make_relative, old)
     if path not in fixed:
         fixed.append(path)
     new = tuple(fixed)
     if new != old:
         annotations[self.key] = new
示例#14
0
 def __init__(self, context, request):
     self.context = context
     self.request = request
     annotations = IAnnotations(context.getCanonical())
     mapping = annotations.get(KEY)
     if mapping is None:
         mapping = annotations[KEY] = PersistentDict({
             'page_background': None,
         })
     self.mapping = mapping
示例#15
0
class LoggerSection(object):
    classProvides(ISectionBlueprint)
    implements(ISection)

    def __init__(self, transmogrifier, name, options, previous):
        self.transmogrifier = transmogrifier
        keys = options.get('keys') or ''
        self.pathkey = options.get('path-key', '_path').strip()
        self.keys = Matcher(*keys.splitlines())
        self.previous = previous
        self.logger = name
        self.storage = IAnnotations(transmogrifier).setdefault(VALIDATIONKEY, [])

    def __iter__(self):
        start_time = time()
        count = 0
        problematic = 0
        for item in self.previous:
            # source sections add store path of current generated item in annotation
            # it gives posibility to monitor what items go through all pipeline
            # sections between source section and this section and what don't
            if self.pathkey in item and item[self.pathkey] in self.storage:
                self.storage.remove(item[self.pathkey])
            count += 1
            # print item data stored on keys given as option
            items = []
            for key in item.keys():
                if self.keys(key)[0] is not None:
                    items.append("%s=%s" % (key, item[key]))
            if items:
                msg = ", ".join(items)
                logging.getLogger(self.logger).info(msg)
            yield item
        
        working_time = int(round(time() - start_time))

        # log items that maybe have some problems
        if self.storage:
            problematic = len(self.storage)
            logging.getLogger(self.logger).warning('\nNext objects didn\'t go through full pipeline:\n%s' % \
                '\n'.join(['\t'+i for i in self.storage]))
        # delete validation data from annotations
        anno = IAnnotations(self.transmogrifier)
        if VALIDATIONKEY in anno:
            del anno[VALIDATIONKEY]

        seconds = working_time % 60
        minutes = working_time / 60 % 60
        hours = working_time / 3600
        stats = "\nPipeline processing time: %02d:%02d:%02d\n" % (hours, minutes, seconds)
        stats += "\t%4d items were generated in source sections\n" % (count + problematic)
        stats += "\t%4d went through full pipeline\n" % count
        stats += "\t%4d were discarded in some section" % problematic
        logging.getLogger(self.logger).info(stats)
示例#16
0
 def testExportNodeWithAnnotation(self):
     """
     when membrane tool is annotated, hash-type node should get exported
     attribute 'name' on the node should contain the hash-type
     """
     # initially add the annotation on to the membrane_tool
     annot = IAnnotations(self.portal.membrane_tool)
     annot.setdefault(ANNOT_KEY, {})['hash_type'] = 'bcrypt'
     node = self.adapter._exportNode()
     self.failUnless('<hash-type name="bcrypt"/>' in node.toxml())
     # clear the bogus annotation
     del annot[ANNOT_KEY]
    def capture(self, order, amount):
        annotations = IAnnotations(order)
        trans_id = annotations[interfaces.keys.processor_txn_id]
        if annotations.has_key(APPROVAL_KEY):
            annotation = IAnnotations( order )
            if annotation.get( interfaces.keys.capture_amount ) is None:
                annotation[ interfaces.keys.capture_amount ] = amount
            else:
                annotation[ interfaces.keys.capture_amount ] += amount            
            return interfaces.keys.results_success

        return result.response_reason
示例#18
0
    def save_import_history(self):
        annot = IAnnotations(self.context)
        listen_annot = annot.get(PROJECTNAME)
        if listen_annot is None:
            annot[PROJECTNAME] = listen_annot = OOBTree()
        import_annot = listen_annot.get('import')
        if import_annot is None:
            listen_annot['import'] = import_annot = OOBTree()

        now = str(time.time())
        data = dict(msgids=self.msgids, filename=self.filename)
        import_annot[now] = OOBTree(data)
示例#19
0
 def removePath(self, path):
     path = self._make_relative(path)
     annotations = IAnnotations(self.context)
     old = annotations.get(self.key, ())
     if old:
         fixed = map(self._make_relative, old)
         fixed = [loc for loc in fixed if loc != path]
         new = tuple(fixed)
         if new != old:
             if new:
                 annotations[self.key] = new
             else:
                 del annotations[self.key]
 def save_import_history(self):
     annot = IAnnotations(self.context)
     listen_annot = annot.get(PROJECTNAME)
     if listen_annot is None:
         annot[PROJECTNAME] = listen_annot = OOBTree()
     import_annot = listen_annot.get('import')
     if import_annot is None:
         listen_annot['import'] = import_annot = OOBTree()
         
     now = str(time.time())
     data = dict(msgids=self.msgids,
                 filename=self.filename)
     import_annot[now] = OOBTree(data)
示例#21
0
def authenticated_memberid(context):
    """ the last modified author is set on an annotation """
    from opencore.project.browser.metadata import ANNOT_KEY
    from Missing import Value as MissingValue
    annot = IAnnotations(context)
    annot = annot.get(ANNOT_KEY, {})

    val = annot.get('lastModifiedAuthor')
    if val:
        return val

    # @@ adapters must return something or code must expect component
    # errors
    return MissingValue
示例#22
0
    def isPending(self):
        annot = IAnnotations(self.context)
        sub_mod_pending_list = getAdapter(self.context,
                                          IMembershipPendingList,
                                          'pending_sub_mod_email')

        return sub_mod_pending_list.is_pending(self.user_email)
示例#23
0
 def capture(self, order, amount):
     #AC - Authorization and Mark for Capture
     annotation = IAnnotations(order)
     trans_ref_num = annotation[interfaces.keys.processor_txn_id]
     data = createCaptureXMLFile(self.options, order, trans_ref_num, amount)
     
     result = self.process(data, timeout=None)
     
     if result.proc_status == "0":
         if annotation.get(interfaces.keys.capture_amount) is None:
             annotation[interfaces.keys.capture_amount] = amount
         else:
             annotation[interfaces.keys.capture_amount] += amount            
         return interfaces.keys.results_success
     else:
         return result.status_msg
示例#24
0
class ClickdateAnnotationTest(PloneTest):
    """
    test for adapter
    """
    def afterSetUp(self):
        self.obj = Dummy()
        self.dan = IClickdates(self.obj)
        self.dan.clickDate()
        self.thisMonth = datetime.date.today().month
        self.thisYear = datetime.date.today().year
        self.annotations = IAnnotations(self.obj)
        self.date = "%s-%s" % (self.thisYear, self.thisMonth)

    def test_annotation(self):
        self.assertTrue(self.annotations.has_key(ANNOTATION))

    def test_month_key(self):
        key = self.annotations[ANNOTATION]
        self.assertTrue(key.has_key(self.date))

    def test_date(self):
        key = self.annotations[ANNOTATION][self.date]
        clickdate = key[0]
        self.assertEqual(clickdate.year, self.thisYear)
        self.assertEqual(clickdate.month, self.thisMonth)
示例#25
0
    def _extractQueryIndexMap(self):
        fragment = self._doc.createDocumentFragment()
        annots = IAnnotations(self.context)
        query_index_map = annots.get(QIM_ANNOT_KEY)
        if query_index_map is not None:
            child = self._doc.createElement('query_index_map')
            
            for key, value in query_index_map.items():
                sub = self._doc.createElement('index')
                sub.setAttribute('name', key)
                inner = self._doc.createTextNode(value)
                sub.appendChild(inner)
                child.appendChild(sub)

            fragment.appendChild(child)
        return fragment
示例#26
0
class GEOMap(object):
    """ geomap
    """
    implements(IGEOMap)

    def __init__(self, context):
        """ init  """
        self.annotations = IAnnotations(context)
        self.geomap = self.annotations.get(GEOMAP_KEY, None)
        if self.geomap == None:
            self.annotations[GEOMAP_KEY] = PersistentMapping()
            self.geomap = self.annotations[GEOMAP_KEY]
            self.geomap['mapcenter'] = None
            self.geomap['mapzoom']   = None
            self.geomap['maptype']   = None

    def getMapCenter(self):
        """ return map center """
        return self.geomap['mapcenter']

    def getMapZoom(self):
        """ return map zoom """
        return self.geomap['mapzoom']

    def getMapType(self):
        """ return map type """
        return self.geomap['maptype']


    def setMap(self, mapcenter, mapzoom, maptype):
        """ set map options """
        self.geomap['mapcenter'] = mapcenter
        self.geomap['mapzoom'] = mapzoom
        self.geomap['maptype'] = maptype
示例#27
0
class GEOLocated(object):
    """ geolocation
    """
    implements(IGEOLocated)

    def __init__(self, context):
        """ init  """
        self.annotations = IAnnotations(context)
        self.geolocation = self.annotations.get(GEOLOCATION_KEY, None)
        if self.geolocation == None:
            self.annotations[GEOLOCATION_KEY] = PersistentMapping()
            self.geolocation = self.annotations[GEOLOCATION_KEY]
            self.geolocation['latitude']  = None
            self.geolocation['longitude'] = None

    def getLongitude(self): 
        """ return longtitude """
        return self.geolocation['longitude']

    def getLatitude(self):
        """ return latitude """
        return self.geolocation['latitude']

    def setLongitude(self, value):
        """ set longtitude """
        self.geolocation['longitude'] = float(value)

    def setLatitude(self, value):
        """ set latitutde """
        self.geolocation['latitude'] = float(value)

    def setLocation(self, latitude, longitude):
        """ set location """
        self.geolocation['longitude'] = float(longitude)
        self.geolocation['latitude'] = float(latitude)
示例#28
0
    def post_validate(self, REQUEST, errors):
        form = REQUEST.form
        if form.has_key("password") or form.has_key("confirmPassword"):
            password = form.get("password", None)
            confirm = form.get("confirmPassword", None)

            annotations = IAnnotations(self)
            passwordDigest = annotations.get(PASSWORD_KEY, None)

            if not passwordDigest:
                if not password and not confirm:
                    errors["password"] = u"An initial password must be set"
                    return
            if password or confirm:
                if password != confirm:
                    errors["password"] = errors["confirmPassword"] = u"Passwords do not match"
示例#29
0
    def __init__(self, transmogrifier, name, options, previous):
        self.previous = previous
        self.context = transmogrifier.context

        # next is for communication with 'logger' section
        self.anno = IAnnotations(transmogrifier)
        self.storage = self.anno.setdefault(VALIDATIONKEY, [])

        self.pathkey = options.pop('path-key', '_path')
        self.entrieskey = options.pop('entries-key', '_entries')

        # handle exclude-contained parameter
        if "exclude-contained" in options.keys():
            self.exclude_contained = options.pop('exclude-contained')
            self.exclude_contained = self.exclude_contained == "true"
        else:
            self.exclude_contained = False

        # remove 'blueprint' option - it cannot be a query
        options.pop('blueprint')

        self.query = {}
        for k, v in options.items():
            for p in v.split(';'):
                params = p.split('=', 1)
                if len(params) == 1:
                    self.query[k] = p.strip()
                else :
                    q = self.query.setdefault(k, {})
                    q[params[0].strip()] = params[1].strip()

        self.catalog = utils.getToolByName(self.context, 'portal_catalog')
示例#30
0
    def post_validate(self, REQUEST, errors):
        form = REQUEST.form
        if form.has_key('password') or form.has_key('confirmPassword'):
            password = form.get('password', None)
            confirm = form.get('confirmPassword', None)

            annotations = IAnnotations(self)
            passwordDigest = annotations.get(PASSWORD_KEY, None)

            if not passwordDigest:
                if not password and not confirm:
                    errors['password'] = u'An initial password must be set'
                    return
            if password or confirm:
                if password != confirm:
                    errors['password'] = errors[
                        'confirmPassword'] = u'Passwords do not match'
示例#31
0
 def __init__(self, transmogrifier, name, options, previous):
     self.transmogrifier = transmogrifier
     keys = options.get('keys') or ''
     self.pathkey = options.get('path-key', '_path').strip()
     self.keys = Matcher(*keys.splitlines())
     self.previous = previous
     self.logger = name
     self.storage = IAnnotations(transmogrifier).setdefault(VALIDATIONKEY, [])
示例#32
0
    def test_hashers(self):
        for htype in HASHERS:
            login_id = 'hashtest_%s' % htype
            member = self.portal_member
            if not getAdapter(member, IHashPW, htype).isAvailable(): continue
            
            mbtool = getToolByName(member, 'membrane_tool')
            annot = IAnnotations(mbtool)
            annot.setdefault(ANNOT_KEY, {})['hash_type'] = htype
            member.setRoles('Member')
            member.processForm(values=MEM_DATA)

            password = member.getPassword()
            hash_type, hashed = password.split(':', 1)

            self.assertEqual(htype, hash_type)
            self.failUnless(member.verifyCredentials(dict(login='******',
                                                          **MEM_DATA)))
示例#33
0
 def __init__(self, context):
     """ init  """
     self.annotations = IAnnotations(context)
     self.geolocation = self.annotations.get(GEOLOCATION_KEY, None)
     if self.geolocation == None:
         self.annotations[GEOLOCATION_KEY] = PersistentMapping()
         self.geolocation = self.annotations[GEOLOCATION_KEY]
         self.geolocation['latitude']  = None
         self.geolocation['longitude'] = None
示例#34
0
 def __init__(self, context):
     """ init  """
     self.annotations = IAnnotations(context)
     self.geomap = self.annotations.get(GEOMAP_KEY, None)
     if self.geomap == None:
         self.annotations[GEOMAP_KEY] = PersistentMapping()
         self.geomap = self.annotations[GEOMAP_KEY]
         self.geomap['mapcenter'] = None
         self.geomap['mapzoom']   = None
         self.geomap['maptype']   = None
示例#35
0
    def verifyCredentials(self, credentials):
        """Authenticate against the password stored via attribute on this person,
        or pass authentication on to the next PAS plugin
        """
        login = credentials.get('login', None)
        password = credentials.get('password', None)
        logger.info("Adapting an igcPerson... %s %s" % (login,password))
        
        if login is None or password is None:
            return False

#TODO: with a line of code, we can have here login as anyone, for testing
#        gcommons_tool = getToolByName(self.context,FSD_TOOL)
#        if (password == gcommons_tool.getUseInternalPassword()( return true
        
        digest = sha(password).digest()
        annotations = IAnnotations(self.context)
        passwordDigest = annotations.get(PASSWORD_KEY, None)
        return (login == self.getUserName() and digest == passwordDigest)
示例#36
0
    def verifyCredentials(self, credentials):
        """Authenticate against the password stored via attribute on this person,
        or pass authentication on to the next PAS plugin
        """
        login = credentials.get('login', None)
        password = credentials.get('password', None)
        logger.info("Adapting an igcPerson... %s %s" % (login, password))

        if login is None or password is None:
            return False


#TODO: with a line of code, we can have here login as anyone, for testing
#        gcommons_tool = getToolByName(self.context,FSD_TOOL)
#        if (password == gcommons_tool.getUseInternalPassword()( return true

        digest = sha(password).digest()
        annotations = IAnnotations(self.context)
        passwordDigest = annotations.get(PASSWORD_KEY, None)
        return (login == self.getUserName() and digest == passwordDigest)
示例#37
0
 def getAnnotation(context):
     annotations = IAnnotations(context)
     try:
         result = annotations[key]
     except KeyError:
         result = factory()
         annotations[key] = result
     # Containment has to be set up late to allow containment proxies
     # to be applied, if needed. This does not trigger an event and is idempotent
     # if containment is set up already.
     contained_result = zope.app.container.contained.contained(
         result, context, key)
     return contained_result
    def migrate(self):
        if self.is_updated():
            return _(u'already migrated')

        # set the appropriate list type based on the previous settings
        # this may need to mark the appropriate interface on the mailing
        # list as well
        if self.context.moderated:
            self.context.list_type = PostModeratedListTypeDefinition
        elif self.context.closed:
            self.context.list_type = MembershipModeratedListTypeDefinition
        else:
            self.context.list_type = PublicListTypeDefinition

        # copy over the membership stuff
        annot = IAnnotations(self.context)
        listen_annot = annot.get('listen', {})
        old_subscribers = listen_annot.get('subscribers', [])

        # create the new annotations by using current adapters
        mem_list = IWriteMembershipList(self.context)
        for subscriber in old_subscribers:
            mem_list.subscribe(subscriber)

        # unsubscribe (but leave as allowed senders) those who don't
        # receive mail
        nomail = listen_annot.get('norecvmail', [])
        for allowed_sender in nomail:
            mem_list.unsubscribe(allowed_sender)

        # copy over the moderation messages
        self.mod_post_pending_list = getAdapter(self.context, IPostPendingList,
                                                'pending_pmod_post')
        for i in self.context.mqueue.objectIds():
            (header, body) = splitMail(self.context.mqueue[i])
            post = {'header': header, 'body': body}
            (user_name, user_email) = parseaddr(header.get('from', ''))
            self.mod_post_pending_list.add(user_email,
                                           user_name=user_name,
                                           post=post)

        # creates list managers from moderators and list owner
        managers = []
        managers.append(self.context.list_owner)
        for moderator in self.context.moderators:
            managers.append(moderator)
        self.context.managers = tuple(managers)
        convert_manager_emails_to_memberids(self.context)

        # translate archived vocabulary
        if self.context.archived == 'not archived':
            self.context.archived = 2
        elif self.context.archived == 'plain text':
            self.context.archived = 1
        elif self.context.archived == 'with attachments':
            self.context.archived = 0
        else:
            return _(u'error translating archive option')

        # annotate the list to say the migration completed
        self.migration_annot.append('policy_migration')

        return _(u'successfully migrated')
示例#39
0
 def get_import_annot(self):
     annot = IAnnotations(self.context)
     listen_annot = annot.get(PROJECTNAME)
     if listen_annot:
         return listen_annot.get('import')
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     listen_annot = annot.setdefault(PROJECTNAME, OOBTree())
     self.digest = listen_annot.setdefault('digest', PersistentList())
示例#41
0
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     self.listen_annot = annot.setdefault(PROJECTNAME, OOBTree())
     self.mail_sender = ISendMail(context)
     self.mem_list = IWriteMembershipList(self.context)
示例#42
0
 def setPasswordDigested(self, value):
     """
     This is used when migrating, password already sha
     """
     annotations = IAnnotations(self)
     annotations[PASSWORD_KEY] = value
示例#43
0
 def setPassword(self, value):
     """"""
     if value:
         annotations = IAnnotations(self)
         annotations[PASSWORD_KEY] = sha(value).digest()
 def __init__(self, context):
     self.context = context
     annot = IAnnotations(context)
     self.listen_annot = annot.setdefault(PROJECTNAME, OOBTree())
     self.migration_annot = self.listen_annot.setdefault(
         'migration', PersistentList())