class MultiMixinTestModel(TimeStampableMixin, VersionMixin, BaseModel): class Meta(BaseMeta): table_name = 'multi_mixin_tests' test_id = UnicodeAttribute(hash_key=True) field = UnicodeAttribute()
class User(Model): """ A DynamoDB User """ class Meta: table_name = 'User' region = 'us-east-2' username = UnicodeAttribute(hash_key=True) email = UnicodeAttribute() first_name = UnicodeAttribute() last_name = UnicodeAttribute() phone_number = UnicodeAttribute(null=True) user_id = UnicodeAttribute(range_key=True, default=generate_id) # user_id = UnicodeAttribute(hash_key=True) """ The authoritative truth for membership of a user in either a team or as an individual in a resource is NOT managed here. This is simply a short list of resources and teams for which the user MAY or MAY NOT be a member. These caches must be invalidated and checked whenever a call is made regarding permissions or membership. """ resource_cache = UnicodeSetAttribute(default=set()) team_cache = UnicodeSetAttribute(default=set()) @classmethod def get_user_by_username(self, username): for user in User.query(username): return user @classmethod def get_user_by_userid(self, user_id): for user in User.scan(user_id__eq=user_id): return user @classmethod def get_user_resources_by_username(self, username): for user in User.query(username): return user.resource_cache @classmethod def get_user_list_for_resource(self, resource_id): user_list = [] for user in User.scan(): if (user.resource_cache): for resource in user.resource_cache: if resource == resource_id: user_list.append(user) return user_list def assign_team(self, team_id): self.team_cache.add(team_id) def invalidate_team(self, team_id): self.team_cache.remove(team_id) def to_dict(self): return dict(username=self.username, first_name=self.first_name, last_name=self.last_name, user_id=self.user_id, email=self.email)
class SubMapAttribute(MapAttribute): foo = UnicodeAttribute(attr_name='dyn_foo')
class InboundResponse(MapAttribute): body = UnicodeAttribute() headers = ListAttribute(of=HeaderAttribute) status = NumberAttribute()
class Index(GlobalSecondaryIndex): Meta = make_meta(index_name='index', projection=KeysOnlyProjection()) userid = UnicodeAttribute(hash_key=True)
class UserModel(GenericModel): class Meta(GenericMeta): table_name = os.getenv('TABLE_USERS', 'd-users') columns = ( ('username', UnicodeAttribute(hash_key=True)), ('active', BooleanAttribute(null=True)), ('first_name', UnicodeAttribute(null=True)), ('middle_name', UnicodeAttribute(null=True)), ('last_name', UnicodeAttribute(null=True)), ('email', UnicodeAttribute()), ('bio', UnicodeAttribute(null=True)), ('phone', UnicodeAttribute(null=True)), ('street_address', UnicodeAttribute(null=True)), ('city', UnicodeAttribute(null=True)), ('state', UnicodeAttribute(null=True)), ('zip_code', UnicodeAttribute(null=True)), ('user_roles', UnicodeSetAttribute(null=True)), ) for column in columns: locals()[column[0]] = column[1]
class HeaderAttribute(MapAttribute): key = UnicodeAttribute() value = UnicodeAttribute()
class PatientModel(Model): class Meta: table_name = "healthcareservice-patient-PI3" region = 'us-east-1' read_capacity_units = 1 write_capacity_units = 1 pid = UnicodeAttribute(hash_key=True) first_name = UnicodeAttribute() last_name = UnicodeAttribute() user_email = UnicodeAttribute() user_password = UnicodeAttribute() email_address = UnicodeAttribute() is_seeking = BooleanAttribute() phone = UnicodeAttribute() medical_history = UnicodeAttribute() current_prescription = UnicodeAttribute() preferences = UnicodeAttribute() health_care_plan = UnicodeAttribute()
class IssueAttribute(MapAttribute): id = UnicodeAttribute() title = UnicodeAttribute() section = UnicodeAttribute() creator_token = UnicodeAttribute() votes = UnicodeSetAttribute()
class Address(MapAttribute): latitude = NumberAttribute(null=False) longitude = NumberAttribute(null=False) address = UnicodeAttribute()
class Credential(Model): class Meta: table_name = settings.DYNAMODB_TABLE if settings.DYNAMODB_URL: host = settings.DYNAMODB_URL region = settings.AWS_DEFAULT_REGION connection_cls = DDBConnection session_cls = DDBSession id = UnicodeAttribute(hash_key=True) revision = NumberAttribute() data_type = UnicodeAttribute() data_type_date_index = DataTypeDateIndex() name = UnicodeAttribute() credential_pairs = UnicodeAttribute() enabled = BooleanAttribute(default=True) data_key = BinaryAttribute() # TODO: add cipher_type cipher_version = NumberAttribute(null=True) metadata = JSONAttribute(default=dict, null=True) modified_date = UTCDateTimeAttribute(default=datetime.now) modified_by = UnicodeAttribute() documentation = UnicodeAttribute(null=True) def equals(self, other_cred): if self.name != other_cred.name: return False if self.decrypted_credential_pairs != other_cred.decrypted_credential_pairs: # noqa:E501 return False if self.metadata != other_cred.metadata: return False if self.enabled != other_cred.enabled: return False if self.documentation != other_cred.documentation: return False return True def diff(self, other_cred): if self.revision == other_cred.revision: return {} elif self.revision > other_cred.revision: old = other_cred new = self else: old = self new = other_cred diff = {} if old.name != new.name: diff['name'] = {'added': new.name, 'removed': old.name} old_cred_pairs = old.decrypted_credential_pairs new_cred_pairs = new.decrypted_credential_pairs if old_cred_pairs != new_cred_pairs: diff['credential_pairs'] = self._diff_dict(old_cred_pairs, new_cred_pairs) if old.metadata != new.metadata: diff['metadata'] = self._diff_dict(old.metadata, new.metadata) if old.enabled != new.enabled: diff['enabled'] = {'added': new.enabled, 'removed': old.enabled} if old.documentation != new.documentation: diff['documentation'] = { 'added': new.documentation, 'removed': old.documentation } diff['modified_by'] = { 'added': new.modified_by, 'removed': old.modified_by, } diff['modified_date'] = { 'added': new.modified_date, 'removed': old.modified_date, } return diff def _diff_dict(self, old, new): diff = {} removed = [] added = [] for key, value in old.items(): if key not in new: removed.append(key) elif old[key] != new[key]: # modified is indicated by a remove and add removed.append(key) added.append(key) for key, value in new.items(): if key not in old: added.append(key) if removed: diff['removed'] = sorted(removed) if added: diff['added'] = sorted(added) return diff @property def credential_keys(self): return list(self.decrypted_credential_pairs) def _get_decrypted_credential_pairs(self): if self.data_type == 'credential': context = self.id else: context = self.id.split('-')[0] data_key = keymanager.decrypt_datakey( self.data_key, encryption_context={'id': context}) cipher_version = self.cipher_version cipher = CipherManager(data_key, cipher_version) _credential_pairs = cipher.decrypt(self.credential_pairs) _credential_pairs = json.loads(_credential_pairs) return _credential_pairs @property def decrypted_credential_pairs(self): return (self._get_decrypted_credential_pairs())
class Person(MapAttribute): firstName = UnicodeAttribute() lastName = UnicodeAttribute() age = NumberAttribute()
class Location(MapAttribute): latitude = NumberAttribute() longitude = NumberAttribute() name = UnicodeAttribute()
class TripitAccessToken(Model): """ This table is used to map access keys to access tokens. """ class Meta: """Table configuration.""" aws_access_key_id = os.environ.get("APP_AWS_ACCESS_KEY_ID") aws_secret_access_key = os.environ.get("APP_AWS_SECRET_ACCESS_KEY") table_name = "tripit_access_tokens_" + os.environ.get("ENVIRONMENT") read_capacity_units = os.environ.get("AWS_DYNAMODB_RCU") or 2 write_capacity_units = os.environ.get("AWS_DYNAMODB_WCU") or 2 if os.environ.get("AWS_REGION"): region = os.environ.get("AWS_REGION") if os.environ.get("AWS_DYNAMODB_ENDPOINT_URL"): host = os.environ.get("AWS_DYNAMODB_ENDPOINT_URL") access_key = UnicodeAttribute(hash_key=True) token = UnicodeAttribute() token_secret = UnicodeAttribute() @staticmethod def as_dict(access_key, **attributes): """ Returns the token data mapped to this access key as a hash. """ try: data = TripitAccessToken.get(access_key, **attributes) return { "access_key": access_key, "token": data.token, "token_secret": data.token_secret, } except (TableDoesNotExist, GetError): logger.warning("Access token not created yet for key %s", access_key) return None @staticmethod def insert(access_key, token, token_secret): """ Inserts a new access token. """ try: if not TripitAccessToken.exists(): TripitAccessToken.create_table() new_mapping = TripitAccessToken(access_key, token=token, token_secret=token_secret) new_mapping.save() new_mapping.refresh() except TransactWriteError as failed_write_error: logger.error("Failed to write new data for ak %s: %s", access_key, failed_write_error) @staticmethod def delete_tokens_by_access_key(access_key): """ Deletes a token associated with an access key. """ try: existing_request_token_mapping = TripitAccessToken.get(access_key) existing_request_token_mapping.delete() existing_request_token_mapping.save() existing_request_token_mapping.refresh() return None except TransactWriteError as failed_write_error: logger.error("Failed to write new data for ak %s: %s", access_key, failed_write_error) return None except TableDoesNotExist: logger.warning("Access token not created yet for key %s", access_key) return None
class Photo(Model): """ Photo table for DynamoDB """ class Meta: table_name = 'Photo' region = AWS_REGION user_id = UnicodeAttribute(hash_key=True) id = UnicodeAttribute(range_key=True) tags = UnicodeAttribute(null=True) desc = UnicodeAttribute(null=True) filename_orig = UnicodeAttribute(null=True) filename = UnicodeAttribute(null=True) filesize = NumberAttribute(null=True) geotag_lat = UnicodeAttribute(null=True) geotag_lng = UnicodeAttribute(null=True) upload_date = UTCDateTimeAttribute(default=datetime.now(get_localzone())) taken_date = UTCDateTimeAttribute(null=True) make = UnicodeAttribute(null=True) model = UnicodeAttribute(null=True) width = UnicodeAttribute(null=True) height = UnicodeAttribute(null=True) city = UnicodeAttribute(null=True) nation = UnicodeAttribute(null=True) address = UnicodeAttribute(null=True)
class ParticipantAttribute(MapAttribute): name = UnicodeAttribute() ready = BooleanAttribute() admin = BooleanAttribute() token = UnicodeAttribute()
class OrganizationModel(GenericModel): class Meta(GenericMeta): table_name = os.getenv('TABLE_ORGANIZATIONS', 'd-organizations') columns = ( ('id', UnicodeAttribute(hash_key=True)), # ('active', BooleanAttribute()), ('name', UnicodeAttribute()), ('classification', UnicodeAttribute(null=True)), ('logo', UnicodeAttribute(null=True)), ('description', UnicodeAttribute(null=True)), ('motto', UnicodeAttribute(null=True)), ('mission_statement', UnicodeAttribute(null=True)), ('founded', UnicodeAttribute(null=True)), ('ceo', UnicodeAttribute(null=True)), ('annual_net_income', NumberAttribute(null=True)), ('net_profit', NumberAttribute(null=True)), ('annual_sales_actual', NumberAttribute(null=True)), ('net_worth', NumberAttribute(null=True)), ('email', UnicodeAttribute()), ('address', UnicodeAttribute(null=True)), ('company_type', UnicodeAttribute(null=True)), ('duns_number', NumberAttribute(null=True)), ('num_employees_this_site', NumberAttribute(null=True)), ('num_employees_all_sites', NumberAttribute(null=True)), ('one_year_employee_growth', NumberAttribute(null=True)), ('company_website', UnicodeAttribute(null=True)), ('irs_ein', UnicodeAttribute(null=True)), ('latitude', NumberAttribute(null=True)), ('longitude', NumberAttribute(null=True)), ('location_type', UnicodeAttribute(null=True)), ('year_of_founding', NumberAttribute(null=True)), ('minority_or_women_owned', BooleanAttribute(null=True)), ('phone_number', UnicodeAttribute(null=True)), ('prescreen_score', UnicodeAttribute(null=True)), ('primary_industry', UnicodeAttribute(null=True)), ('primary_naics_code', UnicodeAttribute(null=True)), ('primary_sic_code', UnicodeAttribute(null=True)), ('subsidiary_status', BooleanAttribute(null=True)), ('tags', UnicodeSetAttribute(null=True)), ('examples', UnicodeSetAttribute(null=True)), ('sdg_keys', UnicodeSetAttribute(null=True)), ('similar_companies', UnicodeSetAttribute(null=True)), ) for column in columns: locals()[column[0]] = column[1] @staticmethod def get_slug(name): """ The slug is a URL-friendly identifier for an organization. Converts 'My Cool Company' into 'my-cool-company' """ name = name.lower() name = re.sub(r'[\W_]$', '', name) return re.sub(r'[\W_]+', '-', name)
class Cacher(Model): """ cache for function """ cacheKey = UnicodeAttribute(hash_key=True) data = JSONAttribute(default={}) compressedData = BinaryAttribute(null=True) timestamp = NumberAttribute() def __repr__(self): return json.dumps({ 'cacheKey': self.cacheKey, 'data': self.data, 'timestamp': self.timestamp }) @staticmethod def hashValue(inputDict: dict): return hashlib.sha256(json.dumps(inputDict).encode()).hexdigest() @classmethod def getCache(cls, input: (dict, str), timeout=86400, verbose=False, compression=True): # check cache for value cache = next(cls.query(cls.hashValue(input)), None) if cache and (datetime.now().timestamp() - cache.timestamp < timeout): logging.debug('log found') if not compression: return cache.data try: return cls.decompress(cache.compressedData) except: logging.exception( 'error decompressiong, perhaps data is not compressed?') return cache.data else: logging.warning('cache not found or expired') return None @classmethod def addCache(cls, input: (dict, str), output: (dict, str), compression=True): cache = cls( cacheKey=cls.hashValue(input), data=output if not compression else {}, timestamp=datetime.now().timestamp(), compressedData=cls.compress(output) if compression else None) try: return cache.save() except Exception as e: logging.exception(f'{e}') @staticmethod def compress(inputDict: dict, method=zlib) -> bin: return zlib.compress(json.dumps(inputDict).encode()) @staticmethod def decompress(data: bin, method=zlib) -> dict: return json.loads(zlib.decompress(data).decode()) @classmethod def deleteCache(cls, input: (dict, str)): try: r = next(cls.query(cls.hashValue(input))).delete() logging.exception('deleted') return r except Exception as e: logging.exception('maybe log does exist') return e
class OAuthToken(Model): """ Stores token data from some OAuth provider """ ALIVE = ALIVE DEAD = DEAD access_token = UnicodeAttribute(hash_key=True) refresh_token = UnicodeAttribute(null=True) token_type = UnicodeAttribute(null=True) # Consistency would be too easy expires_in = NumberAttribute(null=True) expires_at = NumberAttribute(null=True) scope = UnicodeAttribute(null=True) user_info = JSONAttribute(null=True) state_index = TokensByState() state = UnicodeAttribute(default=ALIVE) updated_at = UTCDateTimeAttribute() created_at = UTCDateTimeAttribute(range_key=True) ttl = TTLAttribute(null=True) def save(self, *args, **kwargs): timestamp = timezone.now() if not self.created_at: self.created_at = timestamp self.updated_at = timestamp super().save(*args, **kwargs) def update(self, *args, **kwargs): self.updated_at = timezone.now() super().save(*args, **kwargs) def set_updated_at(self, *args, **kwargs): self.updated_at = timezone.now() def set_expiration(self): self.ttl = datetime.timedelta(days=30) @property def session_data(self): return dict( access_token=self.access_token, token_type=self.token_type, refresh_token=self.refresh_token, expires_at=self.expires_at, expires_in=self.expires_in, ) @classmethod def create_if_non_existent(cls): if not cls.exists(): cls.create_table(read_capacity_units=1, write_capacity_units=1, wait=True) class Meta: table_name = settings.OAUTH_TOKEN_TABLE_NAME region = settings.AWS_REGION
class Event(Model): class Meta: table_name = "event" id = UnicodeAttribute(hash_key=True) value = NumberAttribute(null=True)
class OutboundRequest(MapAttribute): body = UnicodeAttribute() headers = ListAttribute(of=HeaderAttribute)
class WebHookEventModel(Model): event_id = UnicodeAttribute(hash_key=True) sent_system = ListAttribute(default=list)
def test_should_string_convert_string(): assert_attribute_conversion(UnicodeAttribute(), graphene.String)
class SubHubAccountModel(Model): user_id = UnicodeAttribute(hash_key=True) cust_id = UnicodeAttribute(null=True) origin_system = UnicodeAttribute() customer_status = UnicodeAttribute()
class TableWithIndex(Model): Meta = make_meta(table_name='with_index') userid = UnicodeAttribute(hash_key=True) index = Index()
class Buyer(MapAttribute): first_name = UnicodeAttribute() last_name = UnicodeAttribute() email_address = UnicodeAttribute() phone_number = UnicodeAttribute()
class CustomAttrMap(MapAttribute): overridden_number_attr = NumberAttribute(attr_name="number_attr") overridden_unicode_attr = UnicodeAttribute(attr_name="unicode_attr")
class PaymentMethod(MapAttribute): card_number = UnicodeAttribute() expiration = UnicodeAttribute() ccv = NumberAttribute() card_type = UnicodeAttribute()
class SubSubMapAttribute(SubMapAttribute): bar = UnicodeAttribute(attr_name='dyn_bar')
class GeneralCredentialModel(Model): class Meta(BlindCredential.Meta): pass id = UnicodeAttribute(hash_key=True) credential_keys = NewUnicodeSetAttribute(default=set([]), null=True)