Ejemplo n.º 1
0
def get_or_create_user(email, user_org):
    email = email.lower()

    user = models.User.get_by_email(email)

    # TODO: Remove this when all users are backfilled
    if user and (not user.domain_type or not user.organization):
        user.domain_type = _extract_domain_type(email)

        if not user.organization:
            user.organization = user.extract_organization()

        user.put()

    if not user:
        user = models.User(email=email,
                           domain_type=_extract_domain_type(email))
        user.organization = user.extract_organization()
        user.put()

        enqueue_event(
            'user.created', 'user',
            convert_entity_to_dict(user, ['id', 'email', 'organization']))

    return user
Ejemplo n.º 2
0
def queue_event(followed_at, shortlink_id, destination, accessed_via, email=None):
  enqueue_event('link_follow.created',
                'link_follow',
                {'link_id': shortlink_id,
                 'user_email': email or current_user.email,
                 'access_method': accessed_via,
                 'destination': destination},
                followed_at)
Ejemplo n.º 3
0
def delete(link_id):
  existing_link = g.link

  logging.info('Deleting link: %s' % (convert_entity_to_dict(existing_link, PUBLIC_KEYS)))

  existing_link.delete()

  enqueue_event('link.deleted',
                'link',
                convert_entity_to_dict(existing_link, PUBLIC_KEYS, get_field_conversion_fns()))

  return jsonify({})
Ejemplo n.º 4
0
def delete(link_id):
  existing_link = check_authorization(link_id)

  if not existing_link:
    return abort(403)

  logging.info('Deleting link: %s' % (convert_entity_to_dict(existing_link, PUBLIC_KEYS)))

  existing_link.delete()

  enqueue_event('link.deleted',
                'link',
                convert_entity_to_dict(existing_link, PUBLIC_KEYS, get_field_conversion_fns()))

  return jsonify({})
Ejemplo n.º 5
0
def upsert_short_link(organization, owner, namespace, shortpath, destination, updated_link_object):
  shortpath = shortpath.strip().lower().strip('/')
  destination = _encode_ascii_incompatible_chars(destination.strip())

  if not shortpath:
    raise LinkCreationException('You must provide a path')

  PATH_RESTRICTIONS_ERROR = 'Keywords can include only letters, numbers, hyphens, "/", and "%s" placeholders'

  if shortpath != re.sub('[^0-9a-zA-Z\-\/%]', '', shortpath):
    raise LinkCreationException(PATH_RESTRICTIONS_ERROR)

  check_namespaces(organization, namespace, shortpath)

  if organization != get_organization_id_for_email(owner):
    raise LinkCreationException("The go link's owner must be in the go link's organization")

  shortpath_parts = shortpath.split('/')
  if len(shortpath_parts) > 1:
    placeholder_found = False

    for part in shortpath_parts[1:]:
      if part == '%s':
        placeholder_found = True
      elif placeholder_found:
        raise LinkCreationException('After the first "%s" placeholder, you can only have additional placeholders')

  if '%' in shortpath:
    if '%' in shortpath and shortpath.count('%') != shortpath.count('%s'):
      raise LinkCreationException(PATH_RESTRICTIONS_ERROR)

    if '%s' in shortpath.split('/')[0]:
      raise LinkCreationException('"%s" placeholders must come after a "/". Example: "jira/%s"')

    if shortpath.count('%s') != destination.count('%s'):
      raise LinkCreationException('The keyword and the destination must have the same number of "%s" placeholders')

  if not updated_link_object:
    existing_link, _ = get_shortlink(organization, namespace, shortpath)

    if existing_link:
      error_message = 'That go link already exists. %s/%s points to %s' % (namespace,
                                                                           shortpath,
                                                                           existing_link.destination_url)

      if existing_link.shortpath != shortpath:
        error_message = 'A conflicting go link already exists. %s/%s points to %s' % (namespace,
                                                                                      existing_link.shortpath,
                                                                                      existing_link.destination_url)

      raise LinkCreationException(error_message)

    if '%s' in shortpath:
      conflicting_link = find_conflicting_link(organization, namespace, shortpath)

      if conflicting_link:
        raise LinkCreationException('A conflicting go link already exists. %s/%s points to %s'
                                    % (namespace, conflicting_link.shortpath, conflicting_link.destination_url))

  # Note: urlparse('128.90.0.1:8080/start').scheme returns '128.90.0.1'. Hence the additional checking.
  destination_url_scheme = urlparse(destination).scheme
  if (not destination_url_scheme
      or not destination_url_scheme.strip()
      or not destination.startswith(destination_url_scheme + '://')):
    # default to HTTP (see Slack discussion)
    destination = 'http://' + destination

  if type(validators.url(destination)) is ValidationFailure:
    raise LinkCreationException('You must provide a valid destination URL')

  if updated_link_object:
    link = updated_link_object
  else:
    link_kwargs = {'organization': organization,
                   'owner': owner,
                   'namespace': namespace,
                   'shortpath': shortpath,
                   'destination_url': destination,
                   'shortpath_prefix': shortpath.split('/')[0]}
    link = models.ShortLink(**link_kwargs)

  link.put()

  link_dict = convert_entity_to_dict(link, ['owner', 'shortpath', 'destination_url', 'organization'])
  link_dict['id'] = link.get_id()

  enqueue_event('link.%s' % ('updated' if updated_link_object else 'created'),
                'link',
                link_dict)
  return link
Ejemplo n.º 6
0
def upsert_short_link(organization, creator, shortpath, destination,
                      updated_link_object):
    shortpath = shortpath.strip().lower().strip('/')
    destination = _encode_ascii_incompatible_chars(destination.strip())

    # TODO: Cache this.
    user = get_or_create_user(creator, organization)
    if not user.accepted_terms_at:
        user.accepted_terms_at = datetime.datetime.utcnow()
        user.put()

    if not shortpath:
        raise LinkCreationException('You must provide a path')

    PATH_RESTRICTIONS_ERROR = 'Keywords can include only letters, numbers, hyphens, "/", and "%s" placeholders'

    if shortpath != re.sub('[^0-9a-zA-Z\-\/%]', '', shortpath):
        raise LinkCreationException(PATH_RESTRICTIONS_ERROR)

    shortpath_parts = shortpath.split('/')
    if len(shortpath_parts) > 1:
        for part in shortpath_parts[1:]:
            if part != '%s':
                raise LinkCreationException(
                    'Keywords can have only "%s" placeholders after the first "/". Ex: "drive/%s"'
                )

    if '%' in shortpath:
        if '%' in shortpath and shortpath.count('%') != shortpath.count('%s'):
            raise LinkCreationException(PATH_RESTRICTIONS_ERROR)

        if '%s' in shortpath.split('/')[0]:
            raise LinkCreationException(
                '"%s" placeholders must come after a "/". Example: "jira/%s"')

        if shortpath.count('%s') != destination.count('%s'):
            raise LinkCreationException(
                'The keyword and the destination must have the same number of "%s" placeholders'
            )

    if not updated_link_object:
        existing_link, _ = get_shortlink(organization, shortpath)

        if existing_link:
            raise LinkCreationException(
                'That go link already exists. go/%s points to %s' %
                (shortpath, existing_link.destination_url))

    # Note: urlparse('128.90.0.1:8080/start').scheme returns '128.90.0.1'. Hence the additional checking.
    destination_url_scheme = urlparse(destination).scheme
    if (not destination_url_scheme or not destination_url_scheme.strip()
            or not destination.startswith(destination_url_scheme + '://')):
        # default to HTTP (see Slack discussion)
        destination = 'http://' + destination

    if type(validators.url(destination)) is ValidationFailure:
        raise LinkCreationException('You must provide a valid destination URL')

    if updated_link_object:
        link = updated_link_object
    else:
        link_kwargs = {
            'organization': organization,
            'owner': creator,
            'shortpath': shortpath,
            'destination_url': destination,
            'shortpath_prefix': shortpath.split('/')[0]
        }
        link = models.ShortLink(**link_kwargs)

    link.put()

    link_dict = convert_entity_to_dict(
        link, ['owner', 'shortpath', 'destination_url', 'organization'])
    link_dict['id'] = link.get_id()

    enqueue_event(
        'link.%s' % ('updated' if updated_link_object else 'created'), 'link',
        link_dict)
    return link