<commit_before>#
# Copyright (c) 2013 NORDUnet A/S
# All rights reserved.
#
#   Redistribution and use in source and binary forms, with or
#   without modification, are permitted provided that the following
#   conditions are met:
#
#     1. Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     2. Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided
#        with the distribution.
#     3. Neither the name of the NORDUnet nor the names of its
#        contributors may be used to endorse or promote products derived
#        from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Author : <NAME> <<EMAIL>>
#

"""
Store VCCSAuthCredential objects in database.
"""

import pymongo
import bson
import time

import vccs_auth.credential
from vccs_auth.credential import VCCSAuthCredential


class VCCSAuthCredentialStore():

    """
    Class providing access to the VCCS authentication backend private
    credential store.
    """

    def __init__(self):
        pass

    def get_credential(self, credential_id, check_active=True):
        """
        Get a credential from the database.

        Unless check_active is False, it will be verified that this is not a
        revoked credential.

        :param credential_id: unique identifier as string
        :param check_active: If True, do not return revoked credentials
        :returns: VCCSAuthCredential object
        """
        raise NotImplementedError("Subclass should implement get_credential")

    def add_credential(self, cred):
        """
        Add a new credential to the database.

        :param cred: VCCSAuthCredential object
        :returns: True on success
        """
        raise NotImplementedError("Subclass should implement add_credential")

    def update_credential(self, cred, safe=True):
        """
        Update an existing credential in the database.

        :param cred: VCCSAuthCredential object
        :param safe: boolean, sub-class specific meaning
        :returns: True on success
        """
        raise NotImplementedError("Subclass should implement update_credential")


class VCCSAuthCredentialStoreMongoDB(VCCSAuthCredentialStore):
    """
    Store VCCSAuthCredential objects in MongoDB.

    The MongoDB documents look like this :

    {'_id': mongodb's unique id,
     'revision': integer - used to do atomic updates,
     'credential': dict that can be turned into VCCSAuthCredential,
     }
    """

    def __init__(self, uri, logger, conn=None, db_name="vccs_auth_credstore", **kwargs):
        VCCSAuthCredentialStore.__init__(self)
        if conn is not None:
            self.connection = conn
        else:
            if "replicaSet=" in uri:
                self.connection = pymongo.mongo_replica_set_client.MongoReplicaSetClient(uri, **kwargs)
            else:
                self.connection = pymongo.MongoClient(uri, **kwargs)
        self.db = self.connection[db_name]
        self.credentials = self.db.credentials
        retries = 5
        for this in xrange(retries):
            try:<commit_msg>More retry margin.<commit_after>#
# Copyright (c) 2013 NORDUnet A/S
# All rights reserved.
#
#   Redistribution and use in source and binary forms, with or
#   without modification, are permitted provided that the following
#   conditions are met:
#
#     1. Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     2. Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided
#        with the distribution.
#     3. Neither the name of the NORDUnet nor the names of its
#        contributors may be used to endorse or promote products derived
#        from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Author : <NAME> <<EMAIL>>
#

"""
Store VCCSAuthCredential objects in database.
"""

import pymongo
import bson
import time

import vccs_auth.credential
from vccs_auth.credential import VCCSAuthCredential


class VCCSAuthCredentialStore():

    """
    Class providing access to the VCCS authentication backend private
    credential store.
    """

    def __init__(self):
        pass

    def get_credential(self, credential_id, check_active=True):
        """
        Get a credential from the database.

        Unless check_active is False, it will be verified that this is not a
        revoked credential.

        :param credential_id: unique identifier as string
        :param check_active: If True, do not return revoked credentials
        :returns: VCCSAuthCredential object
        """
        raise NotImplementedError("Subclass should implement get_credential")

    def add_credential(self, cred):
        """
        Add a new credential to the database.

        :param cred: VCCSAuthCredential object
        :returns: True on success
        """
        raise NotImplementedError("Subclass should implement add_credential")

    def update_credential(self, cred, safe=True):
        """
        Update an existing credential in the database.

        :param cred: VCCSAuthCredential object
        :param safe: boolean, sub-class specific meaning
        :returns: True on success
        """
        raise NotImplementedError("Subclass should implement update_credential")


class VCCSAuthCredentialStoreMongoDB(VCCSAuthCredentialStore):
    """
    Store VCCSAuthCredential objects in MongoDB.

    The MongoDB documents look like this :

    {'_id': mongodb's unique id,
     'revision': integer - used to do atomic updates,
     'credential': dict that can be turned into VCCSAuthCredential,
     }
    """

    def __init__(self, uri, logger, conn=None, db_name="vccs_auth_credstore", retries=10, **kwargs):
        VCCSAuthCredentialStore.__init__(self)
        if conn is not None:
            self.connection = conn
        else:
            if "replicaSet=" in uri:
                self.connection = pymongo.mongo_replica_set_client.MongoReplicaSetClient(uri, **kwargs)
            else:
                self.connection = pymongo.MongoClient(uri, **kwargs)
        self.db = self.connection[db_name]
        self.credentials = self.db.credentials
        for this in xrange(retries):
            try:
{'fraction_non_alphanumeric': 0.06458769875508444, 'fraction_numerical': 0.0020954024405275486, 'mean_word_length': 3.118781725888325, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2821369', 'n_tokens_mistral': 2224, 'n_tokens_neox': 2085, 'n_words': 862}