Esempio n. 1
0
  def testTurnOnRecaptchaIfRecaptchaWasOffAndFailedAttemptsOverMax(self):
    """Test recaptcha turns on if it was off and went over max failed login."""
    # Add enough failed attempts to the DB after start datetime to hit max.
    for x in range(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA):
      models.FailedLoginAttempt.create()

    # Set the config to show recaptcha with an end datetime of now.
    config = ufo.get_user_config()
    config.should_show_recaptcha = False
    config.save()
    test_datetime = datetime.datetime.now()

    should_show_recaptcha, failed_attempts_count = auth.determine_if_recaptcha_should_be_turned_on_or_off()
    self.assertTrue(should_show_recaptcha)
    self.assertEquals(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA,
                      failed_attempts_count)
    self.assertEquals(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA,
                      len(models.FailedLoginAttempt.get_all()))
    config = ufo.get_user_config()
    self.assertTrue(config.should_show_recaptcha)
    self.assertTrue(config.recaptcha_start_datetime >= test_datetime)
    self.assertTrue(config.recaptcha_end_datetime >= test_datetime)
    new_delta = config.recaptcha_end_datetime - config.recaptcha_start_datetime
    default_delta = datetime.timedelta(
        minutes=auth.INITIAL_RECAPTCHA_TIMEFRAME_MINUTES)
    self.assertEquals(default_delta, new_delta)
Esempio n. 2
0
def add_user():
  """Gets the requested users on get and stores new user(s) on post.

  This one handler does get and post for add user. The get method is handled
  by _render_user_add with the parameters for get_all, group_key, and user_key
  each passed along. The post method is handled here by inserting the new user
  or users into the database and redirecting to the user_list page.

  Returns:
    A list of the requested users for a get or redirects to the user_list page
    after inserting users for a post.
  """
  if flask.request.method == 'GET':
    get_all = flask.request.args.get('get_all')
    group_key = flask.request.args.get('group_key')
    user_key = flask.request.args.get('user_key')
    return _get_users_to_add(get_all, group_key, user_key)

  manual = flask.request.form.get('manual')
  users_list = json.loads(flask.request.form.get('users'))
  config = ufo.get_user_config()
  for submitted_user in users_list:
    db_user = models.User()
    db_user.name = submitted_user['name']
    db_user.email = submitted_user['email']
    db_user.domain = config.domain if manual is None else None
    # Save on each user so that we can let the database check if the
    # uniqueness constraint is fulfilled.  i.e don't batch this because
    # if one user is added more than once then the whole session will fail.
    try:
      db_user.save()
    except custom_exceptions.UnableToSaveToDB as e:
      flask.abort(e.code, e.message)

  return user_list()
Esempio n. 3
0
def _make_chrome_policy_json():
  """Generates the json string of chrome policy based on values in the db.

  This policy string has the following form:

  {
    "validProxyServers": {"Value": map_of_proxy_server_ips_to_public_key},
    "enforceProxyServerValidity": {"Value": boolean}
  }

  Returns:
    A json string of current chrome policy.
  """
  proxy_servers = models.ProxyServer.query.all()
  proxy_server_dict = {}
  for server in proxy_servers:
    proxy_server_dict[server.ip_address] = (
        server.get_public_key_as_authorization_file_string())
  proxy_server_value_dict = {"Value" : proxy_server_dict}

  config = ufo.get_user_config()
  config_value_dict = {"Value" : config.proxy_server_validity}

  policy_dictionary = {
      "validProxyServers": proxy_server_value_dict,
      "enforceProxyServerValidity": config_value_dict,
  }

  return json.dumps(policy_dictionary)
def setup_admin():
  """Create the first admin in the system from the setup page.

  Returns:
    A json message indicating a redirect to login if successful.
  """
  config = ufo.get_user_config()
  if config.isConfigured:
    flask.abort(403,
                ufo.get_json_message('cantSetAdminAfterInitialSetupError'))

  admin_email = flask.request.form.get('admin_email', None)
  admin_password = flask.request.form.get('admin_password', None)

  if admin_email is None or admin_password is None:
    flask.abort(403, ufo.get_json_message('noAdministratorError'))

  admin_user = models.AdminUser(email=admin_email)
  admin_user.set_password(admin_password)
  admin_user.save()

  config.isConfigured = True
  config.should_show_recaptcha = False
  config.save()

  response_json = json.dumps(({'shouldRedirect': True}))
  return flask.Response(ufo.XSSI_PREFIX + response_json,
                        headers=ufo.JSON_HEADERS)
Esempio n. 5
0
def _make_chrome_policy_json():
    """Generates the json string of chrome policy based on values in the db.

  This policy string has the following form:

  {
    "validProxyServers": {"Value": map_of_proxy_server_ips_to_public_key},
    "enforceProxyServerValidity": {"Value": boolean}
  }

  Returns:
    A json string of current chrome policy.
  """
    proxy_servers = models.ProxyServer.query.all()
    proxy_server_dict = {}
    for server in proxy_servers:
        proxy_server_dict[server.ip_address] = (
            server.get_public_key_as_authorization_file_string())
    proxy_server_value_dict = {"Value": proxy_server_dict}

    config = ufo.get_user_config()
    config_value_dict = {"Value": config.proxy_server_validity}

    policy_dictionary = {
        "validProxyServers": proxy_server_value_dict,
        "enforceProxyServerValidity": config_value_dict,
    }

    return json.dumps(policy_dictionary)
  def GetUsers(self):
    """Get the users of a domain.

    Returns:
      A list of users.

    Raises:
      googleapiclient.errors.HttpError on failure to find the domain.
    """
    config = ufo.get_user_config()
    users = []
    page_token = ''
    while True:
      request = self.service.users().list(domain=config.domain,
                                          maxResults=500,
                                          pageToken=page_token,
                                          projection='full',
                                          orderBy='email')
      result = request.execute(num_retries=NUM_RETRIES)
      users += result['users']
      if 'nextPageToken' in result:
        page_token = result['nextPageToken']
      else:
        break

    return users
    def GetUsers(self):
        """Get the users of a domain.

    Returns:
      A list of users.

    Raises:
      googleapiclient.errors.HttpError on failure to find the domain.
    """
        config = ufo.get_user_config()
        users = []
        page_token = ''
        while True:
            request = self.service.users().list(domain=config.domain,
                                                maxResults=500,
                                                pageToken=page_token,
                                                projection='full',
                                                orderBy='email')
            result = request.execute(num_retries=NUM_RETRIES)
            users += result['users']
            if 'nextPageToken' in result:
                page_token = result['nextPageToken']
            else:
                break

        return users
Esempio n. 8
0
def setup_admin():
    """Create the first admin in the system from the setup page.

  Returns:
    A json message indicating a redirect to login if successful.
  """
    config = ufo.get_user_config()
    if config.isConfigured:
        flask.abort(403,
                    ufo.get_json_message('cantSetAdminAfterInitialSetupError'))

    admin_email = flask.request.form.get('admin_email', None)
    admin_password = flask.request.form.get('admin_password', None)

    if admin_email is None or admin_password is None:
        flask.abort(403, ufo.get_json_message('noAdministratorError'))

    admin_user = models.AdminUser(email=admin_email)
    admin_user.set_password(admin_password)
    admin_user.save()

    config.isConfigured = True
    config.should_show_recaptcha = False
    config.save()

    response_json = json.dumps(({'shouldRedirect': True}))
    return flask.Response(ufo.XSSI_PREFIX + response_json,
                          headers=ufo.JSON_HEADERS)
Esempio n. 9
0
def setup_oauth():
    """Setup oauth for the apps domain.

  Returns:
    A json message indicating success or a flask abort with 403 for oauth
    exceptions.
  """
    oauth_code = flask.request.form.get('oauth_code', None)
    if oauth_code is None:
        flask.abort(403, ufo.get_json_message('noOauthCodeError'))

    config = ufo.get_user_config()
    flow = oauth.getOauthFlow()
    credentials = None
    domain = flask.request.form.get('domain', None)

    try:
        credentials = flow.step2_exchange(oauth_code)
    except oauth2client.client.FlowExchangeError as e:
        flask.abort(403, e.message)

    apiClient = credentials.authorize(httplib2.Http())
    plusApi = discovery.build(serviceName='plus', version='v1', http=apiClient)
    adminApi = discovery.build(serviceName='admin',
                               version='directory_v1',
                               http=apiClient)

    profileResult = None
    try:
        profileResult = plusApi.people().get(userId='me').execute()
    except Exception as e:
        ufo.app.logger.error(e, exc_info=True)
        flask.abort(403, ufo.get_json_message('domainInvalidError'))

    if domain is None or domain != profileResult.get('domain', None):
        flask.abort(403, ufo.get_json_message('domainInvalidError'))

    user_id = profileResult['id']
    userResult = None
    try:
        userResult = adminApi.users().get(userKey=user_id).execute()
    except Exception as e:
        ufo.app.logger.error(e, exc_info=True)
        flask.abort(403, ufo.get_json_message('nonAdminAccessError'))

    if not userResult.get('isAdmin', False):
        flask.abort(403, ufo.get_json_message('nonAdminAccessError'))

    config.credentials = credentials.to_json()
    config.domain = domain
    flask.session['domain'] = domain
    config.save()

    response_dict = {'domain': domain, 'credentials': config.credentials}
    response_json = json.dumps((response_dict))
    return flask.Response(ufo.XSSI_PREFIX + response_json,
                          headers=ufo.JSON_HEADERS)
Esempio n. 10
0
def setup_oauth():
  """Setup oauth for the apps domain.

  Returns:
    A json message indicating success or a flask abort with 403 for oauth
    exceptions.
  """
  oauth_code = flask.request.form.get('oauth_code', None)
  if oauth_code is None:
    flask.abort(403, ufo.get_json_message('noOauthCodeError'))

  config = ufo.get_user_config()
  flow = oauth.getOauthFlow()
  credentials = None
  domain = flask.request.form.get('domain', None)

  try:
    credentials = flow.step2_exchange(oauth_code)
  except oauth2client.client.FlowExchangeError as e:
    flask.abort(403, e.message)

  apiClient = credentials.authorize(httplib2.Http())
  plusApi = discovery.build(serviceName='plus', version='v1', http=apiClient)
  adminApi = discovery.build(serviceName='admin', version='directory_v1',
                             http = apiClient)

  profileResult = None
  try:
    profileResult = plusApi.people().get(userId='me').execute()
  except Exception as e:
    ufo.app.logger.error(e, exc_info=True)
    flask.abort(403, ufo.get_json_message('domainInvalidError'))

  if domain is None or domain != profileResult.get('domain', None):
    flask.abort(403, ufo.get_json_message('domainInvalidError'))

  user_id = profileResult['id']
  userResult = None
  try:
    userResult = adminApi.users().get(userKey=user_id).execute()
  except Exception as e:
    ufo.app.logger.error(e, exc_info=True)
    flask.abort(403, ufo.get_json_message('nonAdminAccessError'))

  if not userResult.get('isAdmin', False):
    flask.abort(403, ufo.get_json_message('nonAdminAccessError'))

  config.credentials = credentials.to_json()
  config.domain = domain
  flask.session['domain'] = domain
  config.save()

  response_dict = {'domain': domain, 'credentials': config.credentials}
  response_json = json.dumps((response_dict))
  return flask.Response(ufo.XSSI_PREFIX + response_json,
                        headers=ufo.JSON_HEADERS)
Esempio n. 11
0
def getOauthFlow():
    config = ufo.get_user_config()
    # TODO give user an option to input their own and go through a different flow
    # to handle it
    return client.OAuth2WebServerFlow(
        client_id=ufo.app.config.get('SHARED_OAUTH_CLIENT_ID'),
        client_secret=ufo.app.config.get('SHARED_OAUTH_CLIENT_SECRET'),
        scope=util.scopes_to_string(OAUTH_SCOPES),
        redirect_uri='urn:ietf:wg:oauth:2.0:oob',
    )
Esempio n. 12
0
def getOauthFlow():
  config = ufo.get_user_config()
  # TODO give user an option to input their own and go through a different flow
  # to handle it
  return client.OAuth2WebServerFlow(
      client_id=ufo.app.config.get('SHARED_OAUTH_CLIENT_ID'),
      client_secret=ufo.app.config.get('SHARED_OAUTH_CLIENT_SECRET'),
      scope=util.scopes_to_string(OAUTH_SCOPES),
      redirect_uri='urn:ietf:wg:oauth:2.0:oob',
  )
Esempio n. 13
0
  def testEditSettings(self):
    """Test posting with modified settings updates in the db."""
    config = ufo.get_user_config()
    initial_proxy_server_config = config.proxy_server_validity
    initial_network_jail_config = config.network_jail_until_google_auth
    data_to_post = {
        'enforce_proxy_server_validity': json.dumps(not initial_proxy_server_config),
        'enforce_network_jail': json.dumps(not initial_network_jail_config),
    }

    resp = self.client.post(flask.url_for('edit_settings'),
                            data=data_to_post, follow_redirects=False)

    updated_config = ufo.get_user_config()
    self.assertEqual(not initial_proxy_server_config,
                     updated_config.proxy_server_validity)
    # Uncomment when network jail is available.
    #self.assertEqual(not initial_network_jail_config,
    #                 updated_config.network_jail_until_google_auth)
    self.assert_redirects(resp, flask.url_for('get_settings'))
  def sync_db_users_against_directory_service(self):
    """Checks whether the users currently in the DB are still valid.

    This gets all users in the DB, finds those that match the current domain,
    and compares them to those found in the domain in Google Directory Service.
    If a user in the DB is not the domain, then it is presumed to be deleted
    and will thus be removed from our DB.
    """
    ufo.app.logger.info('Starting user sync.')
    db_users = models.User.query.all()
    directory_users = {}
    config = ufo.get_user_config()
    with ufo.app.app_context():
      credentials = oauth.getSavedCredentials()
      # TODO this should handle the case where we do not have oauth
      if not credentials:
        ufo.app.logger.info('OAuth credentials not set up. Can\'t sync users.')
        return

      try:
        directory_service = google_directory_service.GoogleDirectoryService(
            credentials)
        directory_users = directory_service.GetUsersAsDictionary()

      except errors.HttpError as error:
        ufo.app.logger.info('Error encountered while requesting users from '
                            'directory service: ' + str(error))
        return

      for db_user in db_users:
        # Don't worry about users from another domain since they won't show up.
        if db_user.domain != config.domain:
          ufo.app.logger.info('User ' + db_user.email + ' did not match the  '
                              'current domain. Ignoring in directory service.')
          continue

        # Lookup user in dictionary based on email field.
        directory_user = directory_users.get(db_user.email, None)

        # TODO(eholder): Unit test the conditionals here.
        # Assume deleted if not found, so delete from our db.
        if directory_user is None:
          ufo.app.logger.info('User ' + db_user.email + ' was not found in '
                              'directory service.')
          self.perform_configured_action_on_user(config.user_delete_action,
                                                 db_user)
          continue

        if directory_user['suspended']:
          ufo.app.logger.info('User ' + db_user.email + ' was suspended in '
                              'directory service.')
          self.perform_configured_action_on_user(config.user_revoke_action,
                                                 db_user)
          continue
Esempio n. 15
0
def getSavedCredentials():
  credentials = getattr(flask.g, '_credentials', None)
  if not credentials:
    config = ufo.get_user_config()
    if not config.credentials:
      return None

    credentials = client.OAuth2Credentials.from_json(config.credentials)

    flask.g._credentials = credentials

  return credentials
Esempio n. 16
0
  def testRecaptchaStaysOffIfNotConfigured(self):
    """Test recaptcha does not turn on if not configured."""
    # Add enough failed attempts to the DB after start datetime to hit max.
    for x in range(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA):
      models.FailedLoginAttempt.create()

    # Set the config to show recaptcha with an end datetime of now.
    config = ufo.get_user_config()
    config.should_show_recaptcha = False
    config.save()
    ufo.RECAPTCHA_ENABLED_FOR_APP = False
    test_datetime = datetime.datetime.now()

    should_show_recaptcha, failed_attempts_count = auth.determine_if_recaptcha_should_be_turned_on_or_off()
    self.assertFalse(should_show_recaptcha)
    self.assertEquals(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA,
                      failed_attempts_count)
    self.assertEquals(ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA,
                      len(models.FailedLoginAttempt.get_all()))
    config = ufo.get_user_config()
    self.assertFalse(config.should_show_recaptcha)
Esempio n. 17
0
def getSavedCredentials():
    credentials = getattr(flask.g, '_credentials', None)
    if not credentials:
        config = ufo.get_user_config()
        if not config.credentials:
            return None

        credentials = client.OAuth2Credentials.from_json(config.credentials)

        flask.g._credentials = credentials

    return credentials
Esempio n. 18
0
def _make_settings_json():
  """Generates the json string of all settings based on values in the db.

  Returns:
    A json string of current server settings.
  """
  config = ufo.get_user_config()

  settings_dictionary = {
      "enforce_network_jail": config.network_jail_until_google_auth,
      "enforce_proxy_server_validity": config.proxy_server_validity,
  }

  return json.dumps(settings_dictionary)
Esempio n. 19
0
def _make_settings_json():
    """Generates the json string of all settings based on values in the db.

  Returns:
    A json string of current server settings.
  """
    config = ufo.get_user_config()

    settings_dictionary = {
        "enforce_network_jail": config.network_jail_until_google_auth,
        "enforce_proxy_server_validity": config.proxy_server_validity,
    }

    return json.dumps(settings_dictionary)
Esempio n. 20
0
    def testEditSettings(self):
        """Test posting with modified settings updates in the db."""
        config = ufo.get_user_config()
        initial_proxy_server_config = config.proxy_server_validity
        initial_network_jail_config = config.network_jail_until_google_auth
        data_to_post = {
            'enforce_proxy_server_validity':
            json.dumps(not initial_proxy_server_config),
            'enforce_network_jail':
            json.dumps(not initial_network_jail_config),
        }

        resp = self.client.post(flask.url_for('edit_settings'),
                                data=data_to_post,
                                follow_redirects=False)

        updated_config = ufo.get_user_config()
        self.assertEqual(not initial_proxy_server_config,
                         updated_config.proxy_server_validity)
        # Uncomment when network jail is available.
        #self.assertEqual(not initial_network_jail_config,
        #                 updated_config.network_jail_until_google_auth)
        self.assert_redirects(resp, flask.url_for('get_settings'))
Esempio n. 21
0
  def testTurnOffRecaptchaIfRecaptchaWasOnAndTimedOut(self):
    """Test recaptcha turns off if it was on and timed out."""
    start_datetime = datetime.datetime.now()

    # Add some failed attempts to the DB after start datetime.
    expected_count = 3
    for x in range(expected_count):
      models.FailedLoginAttempt.create()

    # Set the config to show recaptcha with an end datetime of now.
    config = ufo.get_user_config()
    config.should_show_recaptcha = True
    config.recaptcha_start_datetime = start_datetime
    config.recaptcha_end_datetime = datetime.datetime.now()
    config.save()

    should_show_recaptcha, failed_attempts_count = auth.determine_if_recaptcha_should_be_turned_on_or_off()

    self.assertFalse(should_show_recaptcha)
    self.assertEquals(expected_count, failed_attempts_count)
    self.assertEquals(0, len(models.FailedLoginAttempt.get_all()))
    config = ufo.get_user_config()
    self.assertFalse(config.should_show_recaptcha)
  def decorated(*args, **kwargs):
    """Requires that the user be logged in if the setup process has finished.

    Returns:
      A call to the decorated function if the setup process is incomplete or
      a user is logged in.

    Raises:
      NotLoggedIn: If the setup process is complete and a user is not logged in
      currently.
    """
    config = ufo.get_user_config()
    if not config.isConfigured:
      return f(*args, **kwargs)

    if is_user_logged_in():
      return f(*args, **kwargs)

    raise NotLoggedIn
def determine_if_recaptcha_should_be_turned_on_or_off():
  """Determines whether or not to show the recaptcha and updates the DB.

  Return:
    A tuple where the first entry is a boolean for whether or not to show
    recaptcha and the second entry is the count of failed login attempts.
  """
  config = ufo.get_user_config()
  failed_attempts_count = 0
  now = datetime.datetime.now()

  if not ufo.RECAPTCHA_ENABLED_FOR_APP:
    delta = datetime.timedelta(minutes=INITIAL_RECAPTCHA_TIMEFRAME_MINUTES)
    failed_attempts_count = models.FailedLoginAttempt.count_since_datetime(
        now - delta)
    return False, failed_attempts_count

  if config.should_show_recaptcha:
    failed_attempts_count = models.FailedLoginAttempt.count_since_datetime(
        config.recaptcha_start_datetime)
    if config.recaptcha_end_datetime < now:
      # This is the case when the recaptcha was on and timed out so turn it off
      config.should_show_recaptcha = False
      models.FailedLoginAttempt.delete_before_datetime(
          config.recaptcha_end_datetime)
    elif failed_attempts_count >= ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA:
      # This is the case when the recaptcha was on and has since seen more
      # failures over the threshold, so it needs to be extended.
      delta = (
          config.recaptcha_end_datetime - config.recaptcha_start_datetime)
      _turn_on_recaptcha(config, now, delta * 2)
  else:
    delta = datetime.timedelta(minutes=INITIAL_RECAPTCHA_TIMEFRAME_MINUTES)
    failed_attempts_count = models.FailedLoginAttempt.count_since_datetime(
        now - delta)
    if failed_attempts_count >= ufo.MAX_FAILED_LOGINS_BEFORE_RECAPTCHA:
      # This is the case when I need to turn on recaptcha initially.
      _turn_on_recaptcha(config, now, delta)

  config.save()
  return config.should_show_recaptcha, failed_attempts_count
Esempio n. 24
0
def login():
    """Logs a user into the management server.

  Returns:
    A redirect to the login page if there is any problem with the current user
    or a redirect to the landing page if everything checks out.
  """
    if is_user_logged_in():
        return flask.redirect(flask.url_for('landing'))

    if flask.request.method == 'GET':
        return _handle_login_get()

    email = flask.request.form.get('email')
    password = flask.request.form.get('password')

    user = models.AdminUser.get_by_email(email)
    if user is None:
        return flask.redirect(
            flask.url_for('login', error='No valid user found.'))

    # TODO(eholder): Add a functional test to verify that recaptcha does trigger,
    # but the test must be at the end since we won't be able to login afterwards.
    config = ufo.get_user_config()
    if (ufo.RECAPTCHA_ENABLED_FOR_APP and config.should_show_recaptcha
            and not ufo.RECAPTCHA.verify()):
        models.FailedLoginAttempt.create()
        return flask.redirect(flask.url_for('login',
                                            error='Failed recaptcha.'))

    if not user.does_password_match(password):
        models.FailedLoginAttempt.create()
        return flask.redirect(flask.url_for('login',
                                            error='Invalid password.'))

    flask.session['email'] = user.email
    flask.session['domain'] = config.domain

    return flask.redirect(flask.url_for('landing'))
Esempio n. 25
0
def edit_settings():
  """Receives the posted form for editing the policy config values.

  The new policy config values are stored in the database.

  Returns:
    A redirect back to display chrome policy with will display the new values.
  """
  # TODO(eholder): Move the display of config values and the edit handlers to
  # something more sensible once UI review tells us what that should be. I'm
  # envisioning a settings or options page which is underneath the overall
  # Setup link. For now, I just want these settings to be edittable somewhere.

  config = ufo.get_user_config()
  # Uncomment the network jail when it's available.
  proxy_server_string = flask.request.form.get('enforce_proxy_server_validity')
  #network_jail_string = flask.request.form.get('enforce_network_jail')
  config.proxy_server_validity = json.loads(proxy_server_string)
  #config.network_jail_until_google_auth = json.loads(network_jail_string)

  config.save()

  return flask.redirect(flask.url_for('get_settings'))
Esempio n. 26
0
def login():
  """Logs a user into the management server.

  Returns:
    A redirect to the login page if there is any problem with the current user
    or a redirect to the landing page if everything checks out.
  """
  if is_user_logged_in():
    return flask.redirect(flask.url_for('landing'))

  if flask.request.method == 'GET':
    return _handle_login_get()

  email = flask.request.form.get('email')
  password = flask.request.form.get('password')

  user = models.AdminUser.get_by_email(email)
  if user is None:
    return flask.redirect(flask.url_for('login', error='No valid user found.'))

  # TODO(eholder): Add a functional test to verify that recaptcha does trigger,
  # but the test must be at the end since we won't be able to login afterwards.
  config = ufo.get_user_config()
  if (ufo.RECAPTCHA_ENABLED_FOR_APP and config.should_show_recaptcha and
      not ufo.RECAPTCHA.verify()):
    models.FailedLoginAttempt.create()
    return flask.redirect(flask.url_for('login', error='Failed recaptcha.'))

  if not user.does_password_match(password):
    models.FailedLoginAttempt.create()
    return flask.redirect(flask.url_for('login', error='Invalid password.'))

  flask.session['email'] = user.email
  flask.session['domain'] = config.domain
  flask.session['isConfigured'] = config.isConfigured

  return flask.redirect(flask.url_for('landing'))
Esempio n. 27
0
def edit_settings():
    """Receives the posted form for editing the policy config values.

  The new policy config values are stored in the database.

  Returns:
    A redirect back to display chrome policy with will display the new values.
  """
    # TODO(eholder): Move the display of config values and the edit handlers to
    # something more sensible once UI review tells us what that should be. I'm
    # envisioning a settings or options page which is underneath the overall
    # Setup link. For now, I just want these settings to be edittable somewhere.

    config = ufo.get_user_config()
    # Uncomment the network jail when it's available.
    proxy_server_string = flask.request.form.get(
        'enforce_proxy_server_validity')
    #network_jail_string = flask.request.form.get('enforce_network_jail')
    config.proxy_server_validity = json.loads(proxy_server_string)
    #config.network_jail_until_google_auth = json.loads(network_jail_string)

    config.save()

    return flask.redirect(flask.url_for('get_settings'))
Esempio n. 28
0
def setup():
  """Handle showing the user the setup page and processing the response.

  Returns:
    On get: a rendered setup page template with appropriate resources passed
    in. On post: a rendered setup page template with the error set in event of
    a known error, a 403 flask.abort in the event of a FlowExchangeError
    during oauth, or a redirect back to get the setup page on success.
  """

  config = ufo.get_user_config()
  flow = oauth.getOauthFlow()
  oauth_url = flow.step1_get_authorize_url()
  oauth_resources_dict = _get_oauth_configration_resources_dict(config,
                                                                oauth_url)

  if flask.request.method == 'GET':

    return flask.render_template(
        'setup.html',
        oauth_url=oauth_url,
        oauth_configuration_resources=json.dumps(oauth_resources_dict))

  credentials = None
  domain = flask.request.form.get('domain', None)
  if flask.request.form.get('oauth_code', None):
    try:
      credentials = flow.step2_exchange(flask.request.form['oauth_code'])
    except oauth2client.client.FlowExchangeError as e:
      flask.abort(403) # TODO better error

    apiClient = credentials.authorize(httplib2.Http())
    plusApi = discovery.build(serviceName='plus',
                              version='v1',
                              http=apiClient)
    adminApi = discovery.build(serviceName='admin',
                               version='directory_v1',
                               http = apiClient)

    try:
      profileResult = plusApi.people().get(userId='me').execute()

      if domain is None or domain != profileResult.get('domain', None):
        return flask.render_template(
            'setup.html', error=DOMAIN_INVALID_TEXT,
            oauth_configuration_resources=json.dumps(oauth_resources_dict))

      user_id = profileResult['id']
      userResult = adminApi.users().get(userKey=user_id).execute()
      if not userResult.get('isAdmin', False):
        return flask.render_template(
            'setup.html', error=NON_ADMIN_TEXT,
            oauth_configuration_resources=json.dumps(oauth_resources_dict))
    except Exception as e:
      ufo.app.logger.error(e, exc_info=True)
      return flask.render_template(
          'setup.html', error=str(e),
          oauth_configuration_resources=json.dumps(oauth_resources_dict))

  if not config.isConfigured:
    admin_email = flask.request.form.get('admin_email', None)
    admin_password = flask.request.form.get('admin_password', None)

    if admin_email is None or admin_password is None:
      return flask.render_template(
          'setup.html', error=NO_ADMINISTRATOR,
          oauth_configuration_resources=json.dumps(oauth_resources_dict))

    admin_user = models.AdminUser(email=admin_email)
    admin_user.set_password(admin_password)
    admin_user.save()

  # if credentials were set above, moved down here to give us a chance to error
  # out of admin user and password, could be moved inline with proper form
  # validation for that (we also don't want to create a user if another step
  # is going to fail)
  if credentials is not None:
    config.credentials = credentials.to_json()
    config.domain = domain
    flask.session['domain'] = domain

  config.isConfigured = True
  config.should_show_recaptcha = False
  config.save()

  return flask.redirect(flask.url_for('setup'))
Esempio n. 29
0
def setup():
    """Handle showing the user the setup page and processing the response.

  Returns:
    On get: a rendered setup page template with appropriate resources passed
    in. On post: a rendered setup page template with the error set in event of
    a known error, a 403 flask.abort in the event of a FlowExchangeError
    during oauth, or a redirect back to get the setup page on success.
  """

    config = ufo.get_user_config()
    flow = oauth.getOauthFlow()
    oauth_url = flow.step1_get_authorize_url()
    oauth_resources_dict = _get_oauth_configration_resources_dict(
        config, oauth_url)

    if flask.request.method == 'GET':

        return flask.render_template(
            'setup.html',
            oauth_url=oauth_url,
            oauth_configuration_resources=json.dumps(oauth_resources_dict))

    credentials = None
    domain = flask.request.form.get('domain', None)
    if flask.request.form.get('oauth_code', None):
        try:
            credentials = flow.step2_exchange(flask.request.form['oauth_code'])
        except oauth2client.client.FlowExchangeError as e:
            flask.abort(403)  # TODO better error

        apiClient = credentials.authorize(httplib2.Http())
        plusApi = discovery.build(serviceName='plus',
                                  version='v1',
                                  http=apiClient)
        adminApi = discovery.build(serviceName='admin',
                                   version='directory_v1',
                                   http=apiClient)

        try:
            profileResult = plusApi.people().get(userId='me').execute()

            if domain is None or domain != profileResult.get('domain', None):
                return flask.render_template(
                    'setup.html',
                    error=DOMAIN_INVALID_TEXT,
                    oauth_configuration_resources=json.dumps(
                        oauth_resources_dict))

            user_id = profileResult['id']
            userResult = adminApi.users().get(userKey=user_id).execute()
            if not userResult.get('isAdmin', False):
                return flask.render_template(
                    'setup.html',
                    error=NON_ADMIN_TEXT,
                    oauth_configuration_resources=json.dumps(
                        oauth_resources_dict))
        except Exception as e:
            ufo.app.logger.error(e, exc_info=True)
            return flask.render_template(
                'setup.html',
                error=str(e),
                oauth_configuration_resources=json.dumps(oauth_resources_dict))

    if not config.isConfigured:
        admin_email = flask.request.form.get('admin_email', None)
        admin_password = flask.request.form.get('admin_password', None)

        if admin_email is None or admin_password is None:
            return flask.render_template(
                'setup.html',
                error=NO_ADMINISTRATOR,
                oauth_configuration_resources=json.dumps(oauth_resources_dict))

        admin_user = models.AdminUser(email=admin_email)
        admin_user.set_password(admin_password)
        admin_user.save()

    # if credentials were set above, moved down here to give us a chance to error
    # out of admin user and password, could be moved inline with proper form
    # validation for that (we also don't want to create a user if another step
    # is going to fail)
    if credentials is not None:
        config.credentials = credentials.to_json()
        config.domain = domain
        flask.session['domain'] = domain

    config.isConfigured = True
    config.should_show_recaptcha = False
    config.save()

    return flask.redirect(flask.url_for('setup'))