示例#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 post(self):
    user = current_user()

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

    school = user.school

    sponsor_name = api.payload['name']

    logo_name = '{}-{}'.format(slugify(sponsor_name, separator='-', to_lower=True), uuid4().hex)

    try:
      # TODO: Once you have apscheduler, run this as a delayed job
      logo = upload_image(
        data=api.payload['logo'],
        name=logo_name,
        location='sponsors/'
      )
    except BaseException:
      logger.error('Error uploading image to S3')
      return 'Error uploading provided image', 500

    dbi.create(Sponsor, {
      'school': school,
      'name': sponsor_name,
      'logo': logo,
      'url': api.payload['url']
    })

    sponsors = format_sponsors(school.sponsors)

    return sponsors, 201
示例#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 perform(path, project):
    logger.info('Reading config...')

    with open(path) as f:
        config_yaml = yaml.load(f)

    return create(Config, {'project': project, 'config': config_yaml})
示例#5
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)}
示例#6
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
        }
示例#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 perform(repo):
    logger.info('Creating project: {}...'.format(repo))

    # Create new Project for repo
    project = dbi.create(Project, {'repo': repo})

    logger.info('Cloning repo...')

    # Clone the repo locally to access its files
    tmp_repo_dir = '{}/{}'.format(tmp_dir, project.uid)
    os.system('git clone {} {}'.format(repo, tmp_repo_dir))

    # Get a Config model instance from the project's .gab.yml file
    config_path = '{}/{}'.format(tmp_repo_dir, GAB_FILE)
    config = config_from_file.perform(config_path, project)

    logger.info('Determining volume size...')

    # Figure out which size volume you will need to hold the dataset
    dataset_size = gb2gib(get_file_size(config.dataset_loc))  # in GiB
    vol_size = int(math.ceil(dataset_size)) + 1  # adding extra GiB in volume

    # Create EC2 Volume and DB representation
    volume = create_volume.perform(project, vol_size)

    # Create EC2 API Instance and DB representation
    instance = create_instance.perform(project,
                                       image_id=API_AMI_ID,
                                       role=roles.API)

    # Wait until instance is running
    aws_instance = watch_instance_until_running.perform(instance)

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

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

    logger.info('Attaching volume to API instance...')

    # Attach Volume to API Instance
    aws_instance.attach_volume(Device=VOLUME_DEVICE,
                               VolumeId=volume.aws_volume_id)

    # Initialize the newly attached volume on the instance
    init_attached_volume.perform(instance, config)

    logger.info('Dettaching volume from API instance...')

    # Detach the volume
    aws_instance.detach_volume(Device=VOLUME_DEVICE,
                               VolumeId=volume.aws_volume_id)

    remote_exec(instance.ip, 'git clone {} project'.format(repo))
示例#9
0
def perform(project, size):
    logger.info('Creating volume...')

    # Create ec2 volume to hold the dataset
    aws_volume = ec2.create_volume(size=size, tagname=project.uid)

    return create(
        Volume, {
            'aws_volume_id': aws_volume.id,
            'project': project,
            'size': aws_volume.size
        })
示例#10
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)}
示例#11
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
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,
            'order': i
        })

        i += 1
示例#13
0
 def new_session(self):
     return dbi.create(Session, {'user': self})
示例#14
0
    def post(self):
        # NOTE: Very aware this endpoint makes a shit-ton of queries and most everything should
        # be eager loaded, but I don't have time to figure all that syntax bullshit out right now for
        # properly eager loading. TODO: Refactor this
        user = current_user()

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

        school = user.school
        challenges = sorted(school.active_challenges(),
                            key=attrgetter('start_date'))

        # Get challenge to assign winners for
        challenge = [
            c for c in challenges if c.id == api.payload['challenge_id']
        ]

        # Make sure challenge exists...
        if challenge:
            challenge = challenge[0]
        else:
            return 'Challenge Not Found', 404

        # If challenge hasn't started yet, error out
        if challenge.start_date.date() > date.today():
            return '', 401

        # Get prizes for this challenge
        prizes = sorted(dbi.find_all(Prize, {'challenge': challenge}),
                        key=attrgetter('id'))
        prize_ids = [p.id for p in prizes]

        # Error out if winners have already been chosen for this challenge
        if dbi.find_all(Winner, {'prize_id': prize_ids}):
            return 'Winners already chosen for this challenge', 500

        # Get reference to all prizes across all challenges for this school
        school_prizes = dbi.find_all(
            Prize, {'challenge_id': [c.id for c in challenges]})

        # Get list of all past winners for this school
        past_winners = []
        for p in school_prizes:
            past_winners += p.winners

        # Find user_ids for all past winners
        past_winner_user_ids = [
            u.id for u in dbi.find_all(
                User, {'id': [w.user_id for w in past_winners]})
        ]

        # Get all check_in_question_ids for this check_in and sort them
        question_ids = [q.id for q in challenge.check_in.check_in_questions]
        question_ids.sort()

        # Find ALL check_in_answers related to these check_in_questions
        answers = dbi.find_all(CheckInAnswer,
                               {'check_in_question_id': question_ids})

        # Create a map of user_id to list of check_in_question_ids that they answered for this check_in
        # Ex: {1: [2, 3, 4]} --> we'll then compare [2, 3, 4] to question_ids to see if they match
        user_ids_to_question_ids = {}
        for a in answers:
            if a.user_id not in user_ids_to_question_ids:
                user_ids_to_question_ids[a.user_id] = [a.check_in_question_id]
            else:
                user_ids_to_question_ids[a.user_id].append(
                    a.check_in_question_id)

        # Find users who:
        # (1) haven't been selected as winners in the past
        # (2) have answered all check_in_questions for this check_in
        potential_winner_user_ids = []
        for k, v in user_ids_to_question_ids.items():
            v.sort()
            if k not in past_winner_user_ids and v == question_ids:
                potential_winner_user_ids.append(k)

        if not potential_winner_user_ids:
            return 'No users currently eligible for prizes -- either everyone has already won or no one has filled out check-ins', 400

        potential_winning_users = dbi.find_all(
            User,
            {
                'id': potential_winner_user_ids,
                'is_admin': False  # admins can't win
            })

        prize_ids_for_winners = []
        for p in prizes:
            prize_ids_for_winners += ([p.id] * p.count)

        # Random prize assignment
        shuffle(prize_ids_for_winners)

        winning_users = random_subset(potential_winning_users,
                                      len(prize_ids_for_winners))

        i = 0
        for u in winning_users:
            winner = dbi.create(Winner, {
                'user': u,
                'prize_id': prize_ids_for_winners[i]
            })

            # Send the winner an email congratulating him/her
            challenge_mailer.congratulate_winner(challenge, winner.prize, u,
                                                 school)

            i += 1

        data = formatted_winners(challenges)

        return data
示例#15
0
        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)

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

    print('Updating name and password for user...')

    hashed_pw = hash_pw(args.password)

    dbi.update(user, {
        'name': args.name,
        'hashed_pw': hashed_pw,
        'is_admin': bool(args.admin)
    })

    print('Successfully upserted user!'.format(args.email))
示例#16
0
    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...
        # This is because it somehow doesn't "see" the other school records that were manually added and then
        # tries to create this record with a primary_id of 1, which obviously won't work. Options at this point:
        # (1) See if adding fake created_at datetimes for the schools that don't have them will fix this.
        # (2) Add the school with a SQL INSERT before running this script
        print('Creating school, {}...'.format(args.name))

        if not domains:
            print(
                'Domains are required to create a new school. Use the --domains argument.'
            )
            exit(0)

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

    sorted_challenges = []
    for k, v in universal_challenge_info.items():
        if v.get('custom'):
            continue

        v['slug'] = k
        sorted_challenges.append(v)

    sorted_challenges = sorted(sorted_challenges,
                               key=itemgetter('defaultIndex'))

    challenges = find_all(Challenge, {'school': school})

    print('Creating challenges for school...')