def register_permissions(permissions): for permission in permissions: try: db_session.add(Permission(permission=permission)) db_session.commit() except IntegrityError: db_session.rollback()
def create_admin(admins): banner(BLUE, "Admin User") s = input( "Do you want to create a new admin user" " (you can later use the create_user.py script to create users)? [Y/n]: " ) if s not in {"", "y", "yes"}: return while True: try: member = member_entity.create( dict( firstname=input("First name: "), lastname=input("Last name: "), email=input("Email: "), unhashed_password=getpass("Password: "******"Addmin new menber {member_id} to admin group.") admins.members.append(db_session.query(Member).get(member_id)) db_session.commit() break except Exception as e: # This may fail when for example the password was too weak print(e) print( "Something went wrong while creating the new user. Please try again." )
def create_permission(self, **kwargs): obj = dict( permission=random_str(), ) obj.update(kwargs) self.permission = Permission(**obj) db_session.add(self.permission) db_session.commit() return self.permission
def create_box(self, **kwargs): obj = dict( member_id=self.member.member_id, box_label_id=randint(1e9, 9e9), session_token=random_str(), ) obj.update(kwargs) self.box = Box(**obj) db_session.add(self.box) db_session.commit() return self.box
def create_span(self, **kwargs): if 'member' in kwargs: member = kwargs.pop('member') else: member = self.member obj = self.obj.create_span(**kwargs) self.span = Span(**obj, member=member) db_session.add(self.span) db_session.commit() return self.span
def delete(self, entity_id, commit=True): entity = db_session.query(self.model).get(entity_id) if not entity: raise NotFound( "Could not find any entity with specified parameters.") if not entity.deleted_at: entity.deleted_at = datetime.utcnow() if commit: db_session.commit()
def create_key(self, **kwargs): if 'member' in kwargs: member = kwargs.pop('member') else: member = self.member obj = self.obj.create_key(**kwargs) self.key = Key(**obj, member=member) db_session.add(self.key) db_session.commit() return self.key
def create_token_with_permission(self, permission): """ Return a logged in token that has a user with the given permission. """ member = self.db.create_member() group = self.db.create_group() group.members.append(member) p = db_session.query(Permission).filter_by( permission=permission).first() group.permissions.append(p) res = create_access_token("", "", member.member_id) db_session.commit() return res['access_token']
def create_password_reset_token(self, member=None, **kwargs): member = member or self.member obj = dict( member_id=member.member_id, token=random_str(), ) obj.update(**kwargs) self.password_reset_token = PasswordResetToken(**obj) db_session.add(self.password_reset_token) db_session.commit() return self.password_reset_token
def create_access_token(self, **kwargs): obj = dict( user_id=TEST_SERVICE_USER_ID, access_token=random_str(), browser=f'a-browser-{random_str()}', ip=f'{randint(0, 255)}.{randint(0, 255)}.{randint(0, 255)}.{randint(0, 255)}', expires=self.test.datetime(days=1), ) obj.update(kwargs) self.access_token = AccessToken(**obj) db_session.add(self.access_token) db_session.commit() return self.access_token
def admin_group(): banner(BLUE, "Adding Admin Permissions") logger.info(f"Adding permissions: {ALL_PERMISSIONS}") register_permissions(ALL_PERMISSIONS) logger.info("Creating admin group.") admins = get_or_create(Group, name='admins', defaults=dict(title='Admins')) for permission in db_session.query(Permission): admins.permissions.append(permission) db_session.commit() return admins
def _create_internal(self, data, commit=True): """ Internal create to make it easier for subclasses to manipulated data before create. """ input_data = self.to_model(data) self.validate_all(input_data) if not input_data: raise UnprocessableEntity("Can not create using empty data.") entity = self.model(**input_data) db_session.add(entity) if commit: db_session.commit() else: db_session.flush() # Flush to get id of created entity. return entity
def create_message(self, member=None, **kwargs): member = member or self.member obj = dict( member=member, subject=random_str(), body=self.fake.bs(), recipient=member.email if member else self.fake.email(), status=Message.QUEUED, ) obj.update(**kwargs) self.message = Message(**obj) db_session.add(self.message) db_session.commit() return self.member
def create_shop_products(): banner(BLUE, "Creating Fake Shop Products") display_order = db_session.query(func.max( ProductCategory.display_order)).scalar() or 0 get_or_create(ProductCategory, name='Medlemskap', defaults=dict(display_order=display_order + 1)) get_or_create(ProductCategory, name='Förbrukning', defaults=dict(display_order=display_order + 2)) get_or_create(ProductCategory, name='Verktyg', defaults=dict(display_order=display_order + 3)) get_or_create(ProductCategory, name='Övrigt', defaults=dict(display_order=display_order + 4)) db_session.commit()
def _update_internal(self, entity_id, data, commit=True): """ Internal update to make it easier for subclasses to manipulated data before update. """ input_data = self.to_model(data) self.validate_present(input_data) if not input_data: raise UnprocessableEntity("Can not update using empty data.") entity = db_session.query(self.model).get(entity_id) if not entity: raise NotFound( "Could not find any entity with specified parameters.") for k, v in input_data.items(): setattr(entity, k, v) if commit: db_session.commit() return self.to_obj(entity)
def create_message(self, data, commit=True): # Validate and fetch recipients. recipients = data.pop('recipients', []) if not isinstance(recipients, list): raise UnprocessableEntity("Recipients should be a list.") member_ids = set() for recipient in recipients: type_ = recipient.get('type') if type_ not in ('member', 'group'): raise UnprocessableEntity(what=BAD_VALUE, message='Recipient type should be member or group') try: id_ = natural1(recipient.get('id')) except (ValueError, TypeError): raise UnprocessableEntity(what=BAD_VALUE, message=f'Recipient id should be positive int.') if type_ == 'member': member_ids.add(id_) else: member_ids.update( {i for i, in db_session.query(member_group.c.member_id).filter(member_group.c.group_id == id_)} ) members = db_session.query(Member).filter(Member.member_id.in_(member_ids)).all() if len(members) != len(member_ids): raise UnprocessableEntity('Recipient id is missing in the database.') for member in members: message = self._create_internal({ **data, 'recipient': member.email, 'member_id': member.member_id, 'status': 'queued' }, commit=False) if commit: db_session.commit() return message
def send_messages(key, domain, sender, to_override, limit): query = db_session.query(Message) query = query.filter(Message.status == Message.QUEUED) query = query.limit(limit) for message in query: to = message.recipient msg = f"sending {message.id} to {to}" if to_override: msg += f" (overriding to {to_override})" to = to_override msg += f": {message.subject}" logger.info(msg) response = requests.post( f"https://api.mailgun.net/v3/{domain}/messages", auth=('api', key), data={ 'from': sender, 'to': to, 'subject': message.subject, 'html': message.body, }) if response.ok: message.status = Message.SENT message.sent_at = datetime.utcnow() db_session.add(message) db_session.commit() else: message.status = Message.FAILED db_session.add(message) db_session.commit() logger.error( f"failed to send {message.id} to {to}: {response.content.decode('utf-8')}" )
def send_membership(self): membership_reminder() db_session.commit()
def commit_fail_transaction(transaction): transaction.status = Transaction.FAILED db_session.add(transaction) db_session.commit()
def create_group(self, **kwargs): obj = self.obj.create_group(**kwargs) self.group = Group(**obj) db_session.add(self.group) db_session.commit() return self.group
def authenticate_request(): """ Update global object with user_id and user permissions using token from request header. """ # Make sure user_id and permissions is always set. g.user_id = None g.permissions = tuple() # logger.info("DATA " + repr(request.get_data())) # logger.info("HEADERS " + repr(request.headers)) # logger.info("ARGS " + repr(request.args)) # logger.info("FORM " + repr(request.form)) # logger.info("JSON " + repr(request.json)) authorization = request.headers.get('Authorization', None) if authorization is None: return bearer = 'Bearer ' if not authorization.startswith(bearer): raise Unauthorized("Unauthorized, can't find credentials.", fields="bearer", what=REQUIRED) token = authorization[len(bearer):].strip() access_token = db_session.query(AccessToken).get(token) if not access_token: raise Unauthorized("Unauthorized, invalid access token.", fields="bearer", what=BAD_VALUE) now = datetime.utcnow() if access_token.expires < now: db_session.query(AccessToken).filter( AccessToken.expires < now).delete() raise Unauthorized("Unauthorized, expired access token.", fields="bearer", what=EXPIRED) if access_token.permissions is None: if access_token.user_id < 0: permissions = SERVICE_PERMISSIONS.get(access_token.user_id, []) elif access_token.user_id > 0: permissions = { p for _, p in get_member_permissions(access_token.user_id) } permissions.add(USER) else: raise BadRequest( "Bad token.", log= f"access_token {access_token.access_token} has user_id 0, this should never happend" ) access_token.permissions = ','.join(permissions) access_token.ip = request.remote_addr access_token.browser = request.user_agent.string access_token.expires = datetime.utcnow() + timedelta( seconds=access_token.lifetime) g.user_id = access_token.user_id g.session_token = access_token.access_token g.permissions = access_token.permissions.split(',') # Commit token validation to make it stick even if request fails later. db_session.commit()
autoflush=False, bind=engine) logger.info( f'checking for emails to send every {args.sleep} seconds, limit is {args.limit}' ) key = config.get('MAILGUN_KEY', log_value=False) domain = config.get('MAILGUN_DOMAIN') sender = config.get('MAILGUN_FROM') to_override = config.get('MAILGUN_TO_OVERRIDE') last_quiz_check = time.time() while True: sleep(args.sleep) try: labaccess_reminder(render_template) membership_reminder() if time.time() - last_quiz_check > 20: # This check is kinda slow (takes maybe 100 ms) # so don't do it as often. It's not time critical anyway. last_quiz_check = time.time() quiz_reminders() db_session.commit() send_messages(key, domain, sender, to_override, args.limit) db_session.commit() except DatabaseError as e: logger.warning(f"failed to do db query. ignoring: {e}") finally: db_session.remove()
def create_member(self, **kwargs): obj = self.obj.create_member(**kwargs) self.member = Member(**obj, member_number=self.get_member_number()) db_session.add(self.member) db_session.commit() return self.member
def view_wrapper(*args, **kwargs): try: has_permission = (permission == PUBLIC or permission in g.permissions) if not has_permission: raise Forbidden( message= f"'{permission}' permission is required for this operation." ) Arg.fill_args(params, kwargs) data = f(*args, **kwargs) if flat_return: result = jsonify({**data, 'status': status}), code else: result = jsonify({ 'status': status, 'data': data }), code if commit and not commit_on_error: db_session.commit() except IntegrityError as e: if isinstance(e.orig, pymysql.err.IntegrityError): # This parsing of db errors is very sketchy, but there are tests for it so at least we know # if it stops working. errno, error = e.orig.args if errno == DUP_ENTRY: m = re.match(r".*?'([^']*)'.*?'([^']*)'.*", error) if m: value = m.group(1) index = m.group(2) try: fields = fields_by_index[index] raise UnprocessableEntity( f"Duplicate '{fields}', '{value}' already exists.", what=NOT_UNIQUE, fields=fields) except KeyError: logger.warning( f"index {index} is missing in index to fields mapping" ) raise UnprocessableEntity( f"Duplicate '{value}' not allowed.", what=NOT_UNIQUE) else: raise UnprocessableEntity(f"Duplicate entry.", what=NOT_UNIQUE) if errno == BAD_NULL_ERROR: m = re.match(r".*?'([^']*)'.*", error) if m: field = m.group(1) else: field = None raise UnprocessableEntity( f"'{field}' is required." if field else "Required field missing.", fields=field, what=REQUIRED) raise UnprocessableEntity( "Could not save entity using the sent data.", log=f"unrecoginized integrity error: {str(e)}") finally: if commit_on_error: db_session.commit() return result
def send_labaccess(self): labaccess_reminder(render_template) db_session.commit()
def create_category(self, **kwargs): obj = self.obj.create_category(**kwargs) self.category = ProductCategory(**obj) db_session.add(self.category) db_session.commit() return self.category