def delete(user_email: str, session_id: bytes) -> None: """Delete the session from the database. Args: user_email: User's email in Cognito. session_id: The session id. Raises: `db.DatabaseError` if there was an error connecting to the database. """ sess_hash = _hex_hash(session_id) pk = db.PartitionKey(ent.Session, sess_hash) sk_session = db.SortKey(ent.Session, sess_hash) sk_user = db.SortKey(ent.User, user_email) # We create a session entity in the database while creating a # SESSION-USER relation to make sure that there can be no duplicate # session ids in the database. Can not use conditions for this purpose, # as those require knowing the primary (composite) key which we don't # without querying the database. get_table().transact_write_items([ db.DeleteArg(pk, sk_session), db.DeleteArg(pk, sk_user) ])
def is_valid(user_email: str, project_domain: str) -> bool: """Verify whether a user has an active subscription to a project. Args: user_email: The user's email address. project_domain: The project's domain name. Returns: True if the user has an activate subscription to the project. """ pk = db.PartitionKey(ent.User, user_email) sk_user = db.SortKey(ent.Sub, project_domain) sk_group = db.SortKey(ent.GroupSub, project_domain) pk_cond = cond.Key('PK').eq(str(pk)) sk_cond = cond.Key('SK').eq(str(sk_user)) | cond.Key('SK').eq(str(sk_group)) # noqa 501 key_cond = pk_cond & sk_cond query_arg = db.QueryArg(key_cond, attributes=['IsActive']) subs = get_table().query(query_arg) for s in subs: if s['IsActive']: return True else: return False
def create(user_email: str, session_id: bytes) -> None: """Store the session id in the database. Args: user_email: User's email in Cognito. session_id: New session id. Raises: `db.ConditionalCheckFailedError` if the session id already exists. `db.DatabasError` if there was an error connecting to the database. """ attributes: SessionAttributes = { 'ExpiresAt': _get_session_ttl() } sess_hash = _hex_hash(session_id) pk = db.PartitionKey(ent.Session, sess_hash) sk_session = db.SortKey(ent.Session, sess_hash) sk_user = db.SortKey(ent.User, user_email) # We create a session entity in the database while creating a # SESSION-USER relation to make sure that there can be no duplicate # session ids in the database. Can not use conditions for this purpose, # as those require knowing the primary (composite) key which we don't # without querying the database. get_table().transact_write_items([ db.InsertArg(pk, sk_session, attributes=attributes), db.InsertArg(pk, sk_user, attributes=attributes) ])
def fetch(group_name: str, project_domain: str, consistent: bool = False) \ -> Optional[GroupSubAttributes]: """Fetch subscription attributes for a group. Args: group_name: The user's email address. project_domain: The project's domain name. consistent: Whether the read should be strongly consistent. Returns: The subscription attributes if the subscription exists. Raises: `db.DatabaseError` if there was an error connecting to the Database. """ pk = db.PartitionKey(ent.Group, group_name) sk = db.SortKey(ent.GroupSub, project_domain) res = get_table().get(pk, sk, consistent=consistent, attributes=['IsActive']) if res is not None: return cast(GroupSubAttributes, res) else: return None
def _get_user_create_op(user_email: str, project_domain: str) -> db.InsertArg: pk = db.PartitionKey(ent.User, user_email) sk = db.SortKey(ent.Sub, project_domain) attr: SubAttributes = { 'IsActive': True } return db.InsertArg(pk, sk, attr)
def _get_trial_end_op(user_email: str, project_domain: str, trial_days: int) \ -> db.InsertArg: trial_end = get_trial_end_date(trial_days) pk = db.PartitionKey(ent.TrialEnd, trial_end) # Concatenation of values ensures uniqueness of item. sk = db.SortKey(ent.TrialEnd, f'{user_email}|{project_domain}') return db.InsertArg(pk, sk)
def fetch(user_email: str, project_domain: str, consistent: bool = False) \ -> Optional[SubAttributes]: """Fetch subscription attributes for a user. Args: user_email: User's email address that uniquely identifies them. project_domain: The project's domain name that uniquely identifies it. consistent: Whether the read should be strongly consistent. Returns: The subscription attributes if the subscription exists. Raises: `db.DatabaseError` if there was an error connecting to the Database. """ pk = db.PartitionKey(ent.User, user_email) sk = db.SortKey(ent.Sub, project_domain) res = get_table().get(pk, sk, consistent=consistent, attributes=['IsActive']) if res is not None: return cast(SubAttributes, res) else: return None
def setUp(self): super().setUp() self._client = MagicMock() self._mocks['_client'].return_value = self._client self._pk = db.PartitionKey(User, '*****@*****.**') self._sk = db.SortKey(Subscription, 'docs.example.com') self._sk_prefix = db.PrefixSortKey(Subscription)
def setUp(self): super().setUp() self._pk_2 = db.PartitionKey(User, '*****@*****.**') self._sk_2 = db.SortKey(Subscription, 'docs.bar.com') self._keys = [ db.PrimaryKey(self._pk, self._sk), db.PrimaryKey(self._pk_2, self._sk_2) ] self._table_name = 'my-table' self._table = Table(self._table_name)
def exists(project_domain: str) -> bool: """Check whether a project exists in the database. Args: project_domain: The project's domain name. Returns: True if the project exists. """ pk = db.PartitionKey(ent.Project, project_domain) sk = db.SortKey(ent.Project, project_domain) res = get_table().get(pk, sk) return bool(res)
def is_owner(group_name: str, user_email: str) -> bool: """Check whether a user is an owner of a group. Args: group_name: The group's name that uniquely identifies it. user_email: The user's email address. Returns: True if the user is the owner of the group. """ pk = db.PartitionKey(ent.Group, group_name) sk = db.SortKey(ent.Group, group_name) res = get_table().get(pk, sk, attributes=['OwnerEmail']) return res is not None and res['OwnerEmail'] == user_email
def fetch(project_domain: str) -> Optional[ProjectAttributes]: """Fetch project attributes based on domain name. Args: project_domain: The project's domain name. Returns: The project attributes if the project exists. """ pk = db.PartitionKey(ent.Project, project_domain) sk = db.SortKey(ent.Project, project_domain) res = get_table().get(pk, sk, attributes=['TrialDays']) if res is not None: return cast(ProjectAttributes, res) else: return None
def delete(user_email: str, project_domain: str) -> None: """Delete a subscription for a user. The subscription item is not removed from the database, but it's `IsActive` attribute is set to false. Args: user_email: User's email address that uniquely identifies them. project_domain: The project's domain name that uniquely identifies it. Raises: `db.DatabaseError` if there was an error connecting to the Database. """ # TODO (abiro) Stripe logic pk = db.PartitionKey(ent.User, user_email) sk = db.SortKey(ent.Sub, project_domain) attr: SubAttributes = { 'IsActive': False } get_table().update_attributes(pk, sk, attr)
def recreate(user_email: str, project_domain: str) -> None: """Recreate a subscription to a project for a user that has lapsed. There is no trial in this case. Args: user_email: User's email address that uniquely identifies them. project_domain: The project's domain name that uniquely identifies it. Raises: `db.DatabaseError` if there was an error connecting to the Database. """ # TODO (abiro) Stripe logic # TODO (abiro) Update instead of Put pk = db.PartitionKey(ent.User, user_email) sk = db.SortKey(ent.Sub, project_domain) attr: SubAttributes = { 'IsActive': True } get_table().update_attributes(pk, sk, attr)
else: scan = table.scan(ProjectionExpression='PK,SK') for item in scan['Items']: batch.delete_item(Key={'PK': item['PK'], 'SK': item['SK']}) logging.info('Starting integration tests') # We clear the DB instead of recreating it to save time. _clear_db(TABLE_NAME) table = db.Table(TABLE_NAME) # Users pk_alice = db.PartitionKey(User, '*****@*****.**') sk_alice = db.SortKey(User, '*****@*****.**') # Products pk_book = db.PartitionKey(Product, 'book') # Orders pk_order1 = db.PartitionKey(Order, '2020-02-21|order-1') sk_order1 = db.SortKey(Order, '2020-02-21|order-1') sk_order2 = db.SortKey(Order, '2020-02-21|order-2') logging.info('Testing insert') table.insert(pk_alice, sk_alice) logging.info('Testing update_attributes') table.update_attributes(pk_alice, sk_alice, {'MyJson': {'A': 1}})
def setUp(self): self._pk = db.PartitionKey(User, '*****@*****.**') self._sk = db.SortKey(Subscription, 'docs.example.com')
def setUp(self): self._pk = db.PartitionKey(User, '*****@*****.**') self._sk = db.SortKey(Subscription, 'mitpress.mit.edu') self._table_name = 'my-table' self._primary_index = db.PrimaryGlobalIndex()
def _get_group_create_op(group_name: str, project_domain: str) -> db.InsertArg: pk_gr = db.PartitionKey(ent.Group, group_name) sk_gr = db.SortKey(ent.GroupSub, project_domain) attr: GroupSubAttributes = {'IsActive': True} return db.InsertArg(pk_gr, sk_gr, attributes=attr)