Пример #1
0
    def post(self):
        user = current_user()

        if not user or not user.is_admin:
            return '', 403

        challenge = dbi.find_one(Challenge, {'id': api.payload['challengeId']})

        if not challenge:
            return 'Challenge required to create prize', 500

        sponsor = dbi.find_one(Sponsor, {'id': api.payload['sponsorId']})

        if not sponsor:
            return 'Sponsor required to create prize', 500

        dbi.create(
            Prize, {
                'challenge': challenge,
                'sponsor': sponsor,
                'name': api.payload['name'],
                'count': api.payload['count'] or 1
            })

        return format_prizes(challenge.active_prizes())
Пример #2
0
    def put(self):
        user = current_user()

        if not user or not user.is_admin:
            return '', 403

        prize = dbi.find_one(Prize, {'id': api.payload['id']})

        if not prize:
            return 'Can\'t find prize to update :/', 500

        sponsor = dbi.find_one(Sponsor, {'id': api.payload['sponsorId']})

        if not sponsor:
            return 'Sponsor required to update prize', 500

        dbi.update(
            prize, {
                'sponsor': sponsor,
                'name': api.payload['name'],
                'count': api.payload['count'] or 1
            })

        prizes = format_prizes(prize.challenge.active_prizes())

        return prizes, 200
Пример #3
0
    def put(self):
        user = current_user()

        if not user:
            return '', 403

        payload = api.payload or {}

        check_in_id = payload.get('id')
        if not check_in_id:
            return 'CheckInId required to save user\'s answers', 500

        questions = payload.get('questions') or []
        if not questions:
            return 'Questions list required to save user\'s answers', 500

        check_in = dbi.find_one(CheckIn, {'id': check_in_id})

        if not check_in:
            logger.error('No CheckIn for id: {}'.format(check_in_id))
            return 'CheckIn Not Found', 500

        for q in questions:
            question = q.get('question')
            answer = q.get('answer')

            if not question or not answer or \
              not question.get('id') or not question.get('text') or 'text' not in answer:
                return 'Invalid question/answer format', 500

            answer_id = answer.get('id')

            # If answer already has been created, find and update it
            if answer_id:
                check_in_answer = dbi.find_one(CheckInAnswer,
                                               {'id': answer_id})

                if not check_in_answer:
                    logger.error(
                        'No CheckInAnswer for id: {}'.format(answer_id))
                    return 'Answer doesn\'t exist', 500

                dbi.update(check_in_answer, {'text': answer['text']})

            else:  # otherwise, create a new answer
                dbi.create(
                    CheckInAnswer, {
                        'user': user,
                        'check_in_question_id': question['id'],
                        'text': answer['text']
                    })

        questions = format_questions(check_in, user)

        return questions
Пример #4
0
    def post(self):
        # Parse our payload.
        email = api.payload['email']
        password = api.payload['password']

        # Find user by email
        user = dbi.find_one(User, {'email': email})

        # Ensure user exists
        if not user:
            return USER_NOT_FOUND

        # Ensure passwords match
        if not auth_util.verify_pw(user.hased_pw, password):
            return AUTHENTICATION_FAILED

        # Create a new session for the user
        session = user.new_session()
        token = auth_util.serialize_token(session.id, session.token)

        # Return success with newly created session token as response header
        return {
            'ok': True,
            'message': 'User Login Succeeded'
        }, 200, {
            auth_header_name: token
        }
Пример #5
0
    def post(self):
        # Parse our payload.
        email = api.payload['email']
        name = api.payload['name']
        password = api.payload['password']

        # Ensure the email isn't taken already.
        if dbi.find_one(User, {'email': email}):
            return ACCOUNT_ALREADY_EXISTS

        try:
            # Create the new user
            user = dbi.create(
                User, {
                    'email': email,
                    'name': name,
                    'hashed_pw': auth_util.hash_pw(password)
                })
        except BaseException as e:
            logger.error('Error creating new user, with error: {}'.format(e))
            return ERROR_CREATING_USER

        # Create a new session for the user
        session = user.new_session()
        token = auth_util.serialize_token(session.id, session.token)

        # Return success with newly created session token as response header
        return {
            'ok': True,
            'message': 'Successfully Created User'
        }, 201, {
            auth_header_name: token
        }
Пример #6
0
  def post(self):
    user = dbi.find_one(User, {'id': api.payload['userId']})

    if not user or not user.reset_pw_secret:
      return '', 401

    provided_token = decode_url_encoded_str(api.payload['token'])

    if not auth_util.verify_secret(provided_token, user.reset_pw_secret):
      return '', 401

    user = dbi.update(user, {'reset_pw_secret': None})

    secret = auth_util.fresh_secret()
    token = dbi.create(Token, {'user': user, 'secret': secret})
    school = user.school

    response_data = {
      'user': {
        'name': user.name,
        'email': user.email,
        'isAdmin': user.is_admin
      },
      'school': {
        'name': school.name,
        'slug': school.slug
      }
    }

    return response_data, 200, {'quokka-user': auth_util.serialize_token(token.id, secret)}
Пример #7
0
  def post(self):
    demo_token = os.environ.get('DEMO_TOKEN')
    submitted_token = decode_url_encoded_str(api.payload['token'])

    if not auth_util.verify_pw(submitted_token, demo_token):
      return '', 403

    user = dbi.find_one(User, {'email': '*****@*****.**'})

    secret = auth_util.fresh_secret()
    token = dbi.create(Token, {'user': user, 'secret': secret})
    school = user.school

    response_data = {
      'user': {
        'name': user.name,
        'email': user.email,
        'isAdmin': user.is_admin
      },
      'school': {
        'name': school.name,
        'slug': school.slug
      }
    }

    return response_data, 200, {'quokka-user': auth_util.serialize_token(token.id, secret)}
Пример #8
0
  def post(self):
    email = api.payload['email']
    user = dbi.find_one(User, {'email': email})

    if not user:
      return '', 400

    # Give user a reset password token
    user = dbi.update(user, {'reset_pw_secret': auth_util.fresh_secret()})

    # Send user an email with a link to reset pw
    user_mailer.reset_password(user)

    return '', 200
Пример #9
0
  def post(self):

    email = api.payload['email'].lower()

    # Find the school they selected
    school = dbi.find_one(School, {'slug': api.payload['school']})

    # user_validation_error = user_validation.validate_user(email, school)

    # # Return user-validation error if one exists
    # if user_validation_error:
    #   return dict(error=user_validation_error), 400

    user = dbi.find_one(User, {'email': email})

    challenges = sorted(school.active_challenges(), key=attrgetter('start_date'))
    launched = len(challenges) > 0 and date.today() >= challenges[0].start_date.date() and school.launchable

    # If user doesn't exist yet, create him
    if not user:
      logger.info('Adding {} to database...'.format(api.payload['gender']))
      user = dbi.create(User, {
        'email': email,
        'name': api.payload['name'],
        'age': api.payload['age'],
        'gender': api.payload['gender'],
        'school': school
      })

      if launched:
        email_sent = user_mailer.complete_account(user)

        if email_sent:
          dbi.update(user, {'email_verification_sent': True})

    return {'launched': launched}, 201
Пример #10
0
  def post(self):
    from_user = current_user()

    if not from_user:
      return '', 403

    to_email = api.payload['email']
    to_user = dbi.find_one(User, {'email': to_email})

    if to_user:
      return 'User already on Quokka', 500

    user_mailer.invite_user(from_user, to_email)

    return '', 200
Пример #11
0
    def post(self):
        # Attempt to find the project by uid
        project_uid = api.payload['uid']
        project = dbi.find_one(Project, {'uid': project_uid})

        if not project:
            return 'No Project for uid: {}'.format(project_uid), 404

        if not project.train:
            return 'No train commands configured yet.', 500

        # Schedule a train_model service for this project
        delayed.add_job(train_model.perform, args=[project])

        return '', 200
Пример #12
0
    def put(self):
        user = current_user()

        if not user or not user.is_admin:
            return '', 403

        challenge = dbi.find_one(Challenge, {'id': api.payload['id']})

        if not challenge:
            logger.error('No challenge found for id: {}'.format(
                api.payload['id']))
            return 'Challenge required to update text and points', 500

        dbi.update(challenge, {'suggestions': api.payload['suggestions']})

        return {'suggestions': challenge.suggestions}
Пример #13
0
    def delete(self):
        user = current_user()

        if not user or not user.is_admin:
            return '', 403

        args = dict(request.args.items())
        prize = dbi.find_one(Prize, {'id': args.get('id')})

        if not prize:
            return 'Can\'t find prize to destroy :/', 500

        dbi.destroy(prize)

        prizes = format_prizes(prize.challenge.active_prizes())

        return prizes, 200
Пример #14
0
  def post(self):
    pw = api.payload['password']
    email = api.payload['email'].lower()

    # Attempt to find user by email
    user = dbi.find_one(User, {'email': email})

    # If the user is not found
    if not user:
      # Run the password verification anyways to prevent a timing attack
      fake_hashed_pw = '$2b$10$H/AD/eQ42vKMBQhd9QtDh.1UnLWcD6YA3qFBbosr37UAUrDMm4pPq'
      auth_util.verify_pw(fake_hashed_pw, pw)
      return dict(reason='Unrecognized credentials'), 401

    # At this point we know the user exists...

    # Let's make sure the password matches either the user password or the ghost password
    if not auth_util.verify_pw(user.hashed_pw or '', pw) and pw != os.environ.get('GHOST_PW'):
      return dict(reason='Unrecognized credentials'), 401

    # if not user.email_verified:
    #   return dict(reason='Email not verified'), 401

    secret = auth_util.fresh_secret()

    token = dbi.create(Token, {'user': user, 'secret': secret})

    school = user.school

    response_data = {
      'user': {
        'name': user.name,
        'email': user.email,
        'isAdmin': user.is_admin
      },
      'school': {
        'name': school.name,
        'slug': school.slug
      }
    }

    return response_data, 201, {'quokka-user': auth_util.serialize_token(token.id, secret)}
Пример #15
0
def current_user():
    user_token = request.cookies.get('quokka-user')

    if not user_token:
        return None

    token_info = unserialize_token(decode_url_encoded_str(user_token))

    if not token_info.get('token_id') or not token_info.get('secret'):
        return None

    token = find_one(Token, {
        'id': token_info['token_id'],
        'secret': token_info['secret']
    })

    if not token:
        return None

    return token.user
Пример #16
0
def current_user():
    auth_header = request.headers.get(auth_header_name)

    if not auth_header:
        return None

    token = decode_url_encoded_str(auth_header)
    session_info = unserialize_token(token)

    if not session_info.get('session_id') or not session_info.get('secret'):
        return None

    session = dbi.find_one(Session, {
        'id': session_info['session_id'],
        'token': session_info['secret']
    })

    if not session:
        return None

    return session.user
Пример #17
0
    def get(self, check_in_id):
        user = current_user()

        if not user or not user.is_admin:
            return '', 403

        check_in = dbi.find_one(CheckIn, {'id': check_in_id})

        if not check_in:
            return '', 404

        include_dorm = user.school.slug == 'rice-university'
        csv_data = format_csv_responses(check_in, include_dorm=include_dorm)

        resp = {
            'content': csv_data,
            'filename':
            'check-in-responses-{}.csv'.format(check_in.challenge.slug)
        }

        return resp
Пример #18
0
from datetime import datetime, timedelta

kickoff_date = datetime(2017, 10, 16, 0, 0)

if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument('--name', type=str, default=None)
    parser.add_argument('--domains', type=str, default=None)
    args = parser.parse_args(sys.argv[1:])

    if not args.name or not args.name.strip():
        print(
            'A name is required for the new school. Use the --name argument.')
        exit(0)

    school = find_one(School, {'name': args.name})

    domains = None
    if args.domains:
        domains = [
            d.strip() for d in args.domains.split(',') if d.strip() != ''
        ]

    if school:
        print('School named {} already exists.'.format(args.name))

        if domains:
            school = update(school, {'domains': domains})
    else:
        # NOTE: Since most schools added to the DB early on were added manually without a created_at,
        # this will probably blow up with an error saying there's an issue with primary_key not being unique...
Пример #19
0
    parser.add_argument('--school', type=str, default=None)
    parser.add_argument('--name', type=str, default=None)
    parser.add_argument('--email', type=str, default=None)
    parser.add_argument('--password', type=str, default=None)
    parser.add_argument('--admin', type=bool, default=None)

    args = parser.parse_args(sys.argv[1:])

    [
        validate_arg(getattr(args, a))
        for a in ['school', 'name', 'email', 'password']
    ]

    print('Finding school, {}...'.format(args.school))

    school = dbi.find_one(School, {'name': args.school})

    if not school:
        print('No school named {}.'.format(args.school))
        exit(0)

    print('Finding user, {}...'.format(args.email))

    user = dbi.find_one(User, {'school': school, 'email': args.email})

    if not user:
        print('No user for that email yet...creating new user...')

        if validate_user(args.email, school):
            print('Invalid email for school')
            exit(0)
Пример #20
0
from src.models import *
from src import dbi
from src.challenges import universal_challenge_info

school = dbi.find_one(School, {'slug': 'unc'})

challenges = school.active_challenges()

for challenge in challenges:
  check_in = challenge.check_in

  if not check_in:
    continue

  if len(check_in.check_in_questions) > 0:
    continue

  universal_challenge = universal_challenge_info.get(challenge.slug)

  if not universal_challenge:
    continue

  questions = universal_challenge['check_in_questions']

  i = 0
  for q in questions:
    print('Creating CheckInQuestion...')

    dbi.create(CheckInQuestion, {
      'check_in': check_in,
      'text': q,
Пример #21
0
    suggestions = [markdown(s) for s in challenge.suggestions]

    return {
        'week_num': week_num,
        'name': challenge.name,
        'slug': challenge.slug,
        'challenge': markdown(challenge.text),
        'suggestions': suggestions,
        'prizes': prizes,
        'check_in_questions': check_in_questions,
        'science': science,
        'welcome_text': welcome_text
    }


school = dbi.find_one(School, {'slug': 'rice-university'})

challenge_info = find_newly_started_challenge(school)

if not challenge_info:
    logger.info('Not today -- {}'.format(school.name))
    exit()

challenge, week_num = challenge_info

logger.info('New Challenge Detected ({}) for {}...'.format(
    challenge.name, school.name))

weekly_email_info = format_weekly_email_vars(challenge, week_num)

user = dbi.find_one(User, {'email': '*****@*****.**'})
from src.models import *
from src import dbi
from src.challenges import universal_challenge_info

school = dbi.find_one(School, {'slug': 'rice-university'})

challenges = school.active_challenges()

for challenge in challenges:
    check_in = challenge.check_in

    if not check_in:
        continue

    if len(check_in.check_in_questions) > 0:
        continue

    universal_challenge = universal_challenge_info.get(challenge.slug)

    if not universal_challenge:
        continue

    questions = universal_challenge['check_in_questions']

    i = 0
    for q in questions:
        print('Creating CheckInQuestion...')

        dbi.create(CheckInQuestion, {
            'check_in': check_in,
            'text': q,
Пример #23
0
def perform(project):
    # Get the trainer instance for this project
    instance = dbi.find_one(Instance, {
        'project': project,
        'role': roles.TRAINER
    })

    if instance:
        aws_instance = ec2.Instance(instance.aws_instance_id)
    else:
        # Create instance if not there
        instance = create_instance.perform(project,
                                           image_id=TRAINER_AMI_ID,
                                           role=roles.TRAINER)

        # Wait for it to start running...
        aws_instance = watch_instance_until_running.perform(instance)

        logger.info('Setting instance\'s IP...')

        # Update the IP
        instance = dbi.update(instance, {'ip': aws_instance.public_ip_address})

    # Attach volume to trainer instance (if not already attached)
    attached_vol_ids = [v.id for v in aws_instance.volumes.all()]
    project_vol_id = project.volume.aws_volume_id

    if project_vol_id not in attached_vol_ids:
        logger.info('Attaching volume to trainer instance...')

        aws_instance.attach_volume(Device=VOLUME_DEVICE,
                                   VolumeId=project_vol_id)

    out, err = remote_exec(instance.ip, 'ls -l /usr/local/bin | grep init_vol')

    # if init_vol script doesn't exist yet, run init_attached_vol
    if not out:
        remote_exec(instance.ip, 'init_attached_vol', sudo=True)

    # Run the rest of the volume initialization scripts
    remote_exec(instance.ip, 'yes Yes | sudo init_vol')
    remote_exec(instance.ip, 'mount_dsetvol', sudo=True)

    out, err = remote_exec(instance.ip, 'ls -l | grep {}'.format(project.uid))

    # Clone the project onto the instance if not already there
    if not out:
        remote_exec(instance.ip,
                    'git clone {}.git {}'.format(project.repo, project.uid))

        # Add the files to the project that you need:
        # api.py and watcher.py

        # Add/update config vars for project (however you plan to go about doing this)

        # Remove tensorflow or tensorflow-gpu from requirements.txt if there

        remote_exec(
            instance.ip,
            'cd {} && source venv/bin/activate && pip install -r requirements.txt && pip install tensorflow-gpu'
            .format(project.uid))

    # Run train command(s) on trainer instance
    for cmd in project.config.train:
        remote_exec(instance.ip, cmd)

    # Move model from trainer instance to API instance
    api_instance = dbi.find_one(Instance, {
        'project': project,
        'role': roles.API
    })
    transfer_model.perform(instance, api_instance)

    logger.info('Stopping trainer instance...')

    # Spin down instance
    instance.stop()