Exemple #1
0
 def test_import_users_missing_required_hash(self, user_mgt_app):
     users = [
         auth.ImportUserRecord(uid='user1', password_hash=b'password'),
         auth.ImportUserRecord(uid='user2'),
     ]
     with pytest.raises(ValueError):
         auth.import_users(users, app=user_mgt_app)
Exemple #2
0
 def test_import_users_with_hash(self, user_mgt_app):
     _, recorder = _instrument_user_manager(user_mgt_app, 200, '{}')
     users = [
         auth.ImportUserRecord(uid='user1', password_hash=b'password'),
         auth.ImportUserRecord(uid='user2'),
     ]
     hash_alg = auth.UserImportHash.scrypt(b'key',
                                           rounds=8,
                                           memory_cost=14,
                                           salt_separator=b'sep')
     result = auth.import_users(users, hash_alg=hash_alg, app=user_mgt_app)
     assert result.success_count == 2
     assert result.failure_count is 0
     assert result.errors == []
     expected = {
         'users': [{
             'localId': 'user1',
             'passwordHash': _user_import.b64_encode(b'password')
         }, {
             'localId': 'user2'
         }],
         'hashAlgorithm':
         'SCRYPT',
         'signerKey':
         _user_import.b64_encode(b'key'),
         'rounds':
         8,
         'memoryCost':
         14,
         'saltSeparator':
         _user_import.b64_encode(b'sep'),
     }
     self._check_rpc_calls(recorder, expected)
def import_users():
    # [START build_user_list]
    # Up to 1000 users can be imported at once.
    users = [
        auth.ImportUserRecord(uid='uid1',
                              email='*****@*****.**',
                              password_hash=b'password_hash_1',
                              password_salt=b'salt1'),
        auth.ImportUserRecord(uid='uid2',
                              email='*****@*****.**',
                              password_hash=b'password_hash_2',
                              password_salt=b'salt2'),
    ]
    # [END build_user_list]

    # [START import_users]
    hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret_key')
    try:
        result = auth.import_users(users, hash_alg=hash_alg)
        print('Successfully imported {0} users. Failed to import {1} users.'.
              format(result.success_count, result.failure_count))
        for err in result.errors:
            print('Failed to import {0} due to {1}'.format(
                users[err.index].uid, err.reason))
    except exceptions.FirebaseError:
        # Some unrecoverable error occurred that prevented the operation from running.
        pass
Exemple #4
0
 def test_import_users_error(self, user_mgt_app):
     _, recorder = _instrument_user_manager(
         user_mgt_app, 200, """{"error": [
         {"index": 0, "message": "Some error occured in user1"},
         {"index": 2, "message": "Another error occured in user3"}
     ]}""")
     users = [
         auth.ImportUserRecord(uid='user1'),
         auth.ImportUserRecord(uid='user2'),
         auth.ImportUserRecord(uid='user3'),
     ]
     result = auth.import_users(users, app=user_mgt_app)
     assert result.success_count == 1
     assert result.failure_count == 2
     assert len(result.errors) == 2
     err = result.errors[0]
     assert err.index == 0
     assert err.reason == 'Some error occured in user1'
     err = result.errors[1]
     assert err.index == 2
     assert err.reason == 'Another error occured in user3'
     expected = {
         'users': [{
             'localId': 'user1'
         }, {
             'localId': 'user2'
         }, {
             'localId': 'user3'
         }]
     }
     self._check_rpc_calls(recorder, expected)
Exemple #5
0
 def test_import_users(self, user_mgt_app):
     _, recorder = _instrument_user_manager(user_mgt_app, 200, '{}')
     users = [
         auth.ImportUserRecord(uid='user1'),
         auth.ImportUserRecord(uid='user2'),
     ]
     result = auth.import_users(users, app=user_mgt_app)
     assert result.success_count == 2
     assert result.failure_count is 0
     assert result.errors == []
     expected = {'users': [{'localId': 'user1'}, {'localId': 'user2'}]}
     self._check_rpc_calls(recorder, expected)
Exemple #6
0
def import_with_scrypt():
    # [START import_with_scrypt]
    users = [
        auth.ImportUserRecord(
            uid='some-uid',
            email='*****@*****.**',
            password_hash=b'password_hash',
            password_salt=b'salt'
        ),
    ]

    # All the parameters below can be obtained from the Firebase Console's "Users"
    # section. Base64 encoded parameters must be decoded into raw bytes.
    hash_alg = auth.UserImportHash.scrypt(
        key=base64.b64decode('base64_secret'),
        salt_separator=base64.b64decode('base64_salt_separator'),
        rounds=8,
        memory_cost=14
    )
    try:
        result = auth.import_users(users, hash_alg=hash_alg)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
Exemple #7
0
def test_import_users_with_password(api_key):
    uid, email = _random_id()
    password_hash = base64.b64decode(
        'V358E8LdWJXAO7muq0CufVpEOXaj8aFiC7T/rcaGieN04q/ZPJ08WhJEHGjj9lz/2TT+/86N5VjVoc5DdBhBiw=='
    )
    user = auth.ImportUserRecord(uid=uid,
                                 email=email,
                                 password_hash=password_hash,
                                 password_salt=b'NaCl')

    scrypt_key = base64.b64decode(
        'jxspr8Ki0RYycVU8zykbdLGjFQ3McFUH0uiiTvC8pVMXAn210wjLNmdZJzxUECKbm0QsEmYUSDzZvpjeJ9WmXA=='
    )
    salt_separator = base64.b64decode('Bw==')
    scrypt = auth.UserImportHash.scrypt(key=scrypt_key,
                                        salt_separator=salt_separator,
                                        rounds=8,
                                        memory_cost=14)
    result = auth.import_users([user], hash_alg=scrypt)
    try:
        assert result.success_count == 1
        assert result.failure_count == 0
        saved_user = auth.get_user(uid)
        assert saved_user.email == email
        id_token = _sign_in_with_password(email, 'password', api_key)
        assert len(id_token) > 0
    finally:
        auth.delete_user(uid)
Exemple #8
0
 def test_all_params(self):
     providers = [auth.UserProvider(uid='test', provider_id='google.com')]
     metadata = auth.UserMetadata(100, 150)
     user = auth.ImportUserRecord(uid='test',
                                  email='*****@*****.**',
                                  photo_url='https://test.com/user.png',
                                  phone_number='+1234567890',
                                  display_name='name',
                                  user_metadata=metadata,
                                  password_hash=b'password',
                                  password_salt=b'NaCl',
                                  custom_claims={'admin': True},
                                  email_verified=True,
                                  disabled=False,
                                  provider_data=providers)
     expected = {
         'localId': 'test',
         'email': '*****@*****.**',
         'photoUrl': 'https://test.com/user.png',
         'phoneNumber': '+1234567890',
         'displayName': 'name',
         'createdAt': 100,
         'lastLoginAt': 150,
         'passwordHash': _user_import.b64_encode(b'password'),
         'salt': _user_import.b64_encode(b'NaCl'),
         'customAttributes': json.dumps({'admin': True}),
         'emailVerified': True,
         'disabled': False,
         'providerUserInfo': [{
             'rawId': 'test',
             'providerId': 'google.com'
         }],
     }
     assert user.to_dict() == expected
def import_without_password():
    # [START import_without_password]
    users = [
        auth.ImportUserRecord(
            uid='some-uid',
            display_name='John Doe',
            email='*****@*****.**',
            photo_url='http://www.example.com/12345678/photo.png',
            email_verified=True,
            phone_number='+11234567890',
            custom_claims={'admin': True},  # set this user as admin
            provider_data=[  # user with Google provider
                auth.UserProvider(
                    uid='google-uid',
                    email='*****@*****.**',
                    display_name='John Doe',
                    photo_url='http://www.example.com/12345678/photo.png',
                    provider_id='google.com')
            ],
        ),
    ]
    try:
        result = auth.import_users(users)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
Exemple #10
0
 def test_custom_claims(self, claims):
     user = auth.ImportUserRecord(uid='test', custom_claims=claims)
     assert user.custom_claims == claims
     json_claims = json.dumps(claims) if isinstance(claims,
                                                    dict) else claims
     expected = {'localId': 'test', 'customAttributes': json_claims}
     assert user.to_dict() == expected
Exemple #11
0
 def test_email_verified(self, email_verified):
     user = auth.ImportUserRecord(uid='test', email_verified=email_verified)
     assert user.email_verified == email_verified
     assert user.to_dict() == {
         'localId': 'test',
         'emailVerified': email_verified
     }
Exemple #12
0
def clone_auth(src, dst):
    print("\nCloning users...")
    print(
        "WARNING: PLEASE MANUALLY EDIT \"Sign-in method\" AND \"Templates\" FROM FIREBASE CONSOLE"
    )

    hash_alg = auth.UserImportHash.bcrypt()
    user_list = auth.list_users(max_results=1000, app=src)

    import_list = []
    for user in user_list.users:
        iuser = auth.ImportUserRecord(
            user.uid, user.email, user.email_verified, user.display_name,
            user.phone_number, user.photo_url, user.disabled,
            user.user_metadata, None, user.custom_claims,
            bytes(user.password_hash.encode('ascii')),
            bytes(user.password_salt.encode('ascii')))
        import_list.append(iuser)

    print("\tCloning " + str(len(user_list.users)) + " users...")
    try:
        result = auth.import_users(import_list, hash_alg=hash_alg, app=dst)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)

    while user_list.has_next_page:
        user_list = user_list.get_next_page()

        import_list = []
        for user in user_list.users:
            iuser = auth.ImportUserRecord(
                user.uid, user.email, user.email_verified, user.display_name,
                user.phone_number, user.photo_url, user.disabled,
                user.user_metadata, None, user.custom_claims,
                bytes(user.password_hash.encode('ascii')),
                bytes(user.password_salt.encode('ascii')))
            import_list.append(iuser)

        print("\tCloning " + str(len(user_list.users)) + " users...")
        try:
            result = auth.import_users(import_list, hash_alg=hash_alg, app=dst)
            for err in result.errors:
                print('Failed to import user:'******'Error importing users:', error)
Exemple #13
0
    def reduce(key, values):
        # The reduce() function must be static, so we manually create a "cls"
        # variable instead of changing the function into a classmethod.
        cls = PopulateFirebaseAccountsOneOffJob

        if key == cls.POPULATED_KEY:
            yield (cls.AUDIT_KEY, len(values))
            return
        elif key in (cls.SUPER_ADMIN_ACK, cls.SYSTEM_COMMITTER_ACK):
            yield (key, values)
            return

        # NOTE: This is only sorted to make unit testing easier.
        user_fields = sorted(ast.literal_eval(v) for v in values)
        user_records = [
            firebase_auth.ImportUserRecord(
                uid=auth_id,
                email=email,
                email_verified=True,
                custom_claims=('{"role":"%s"}' %
                               feconf.FIREBASE_ROLE_SUPER_ADMIN
                               if user_is_super_admin else None))
            for auth_id, _, email, user_is_super_admin in user_fields
        ]

        # The Firebase Admin SDK places a hard-limit on the number of users that
        # can be "imported" in a single call. To compensate, we break up the
        # users into chunks.
        offsets = python_utils.RANGE(
            0, len(user_records), cls.MAX_USERS_FIREBASE_CAN_IMPORT_PER_CALL)
        results = (cls.populate_firebase(
            [r for r in record_group
             if r is not None]) for record_group in utils.grouper(
                 user_records, cls.MAX_USERS_FIREBASE_CAN_IMPORT_PER_CALL))

        assocs_to_create = []
        for offset, (result, exception) in python_utils.ZIP(offsets, results):
            if exception is not None:
                yield (cls.ERROR_KEY, repr(exception))
            else:
                successful_indices = set(
                    python_utils.RANGE(result.success_count +
                                       result.failure_count))
                for error in result.errors:
                    successful_indices.remove(error.index)
                    debug_info = 'Import user_id=%r failed: %s' % (
                        user_fields[offset + error.index][1], error.reason)
                    yield (cls.ERROR_KEY, debug_info)
                assocs_to_create.extend(
                    auth_domain.AuthIdUserIdPair(*user_fields[offset + i][:2])
                    for i in successful_indices)

        if assocs_to_create:
            firebase_auth_services.associate_multi_auth_ids_with_user_ids(
                assocs_to_create)
            yield (cls.SUCCESS_KEY, len(assocs_to_create))
def import_with_hmac_tenant(tenant_client):
    # [START import_with_hmac_tenant]
    users = [
        auth.ImportUserRecord(uid='uid1',
                              email='*****@*****.**',
                              password_hash=b'password_hash_1',
                              password_salt=b'salt1'),
        auth.ImportUserRecord(uid='uid2',
                              email='*****@*****.**',
                              password_hash=b'password_hash_2',
                              password_salt=b'salt2'),
    ]

    hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret')
    try:
        result = tenant_client.import_users(users, hash_alg=hash_alg)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
Exemple #15
0
def test_import_users(sample_tenant):
    client = tenant_mgt.auth_for_tenant(sample_tenant.tenant_id)
    user = auth.ImportUserRecord(uid=_random_uid(), email=_random_email())
    result = client.import_users([user])
    try:
        assert result.success_count == 1
        assert result.failure_count == 0
        saved_user = client.get_user(user.uid)
        assert saved_user.email == user.email
    finally:
        client.delete_user(user.uid)
Exemple #16
0
def test_import_users():
    uid, email = _random_id()
    user = auth.ImportUserRecord(uid=uid, email=email)
    result = auth.import_users([user])
    try:
        assert result.success_count == 1
        assert result.failure_count == 0
        saved_user = auth.get_user(uid)
        assert saved_user.email == email
    finally:
        auth.delete_user(uid)
    def test_import_users(self, tenant_mgt_app):
        client = tenant_mgt.auth_for_tenant('tenant-id', app=tenant_mgt_app)
        recorder = _instrument_user_mgt(client, 200, '{}')
        users = [
            auth.ImportUserRecord(uid='user1'),
            auth.ImportUserRecord(uid='user2'),
        ]

        result = client.import_users(users)

        assert isinstance(result, auth.UserImportResult)
        assert result.success_count == 2
        assert result.failure_count == 0
        assert result.errors == []
        self._assert_request(recorder, '/accounts:batchCreate', {
            'users': [{
                'localId': 'user1'
            }, {
                'localId': 'user2'
            }],
        })
Exemple #18
0
def signup():
    if 'photo' in request.files:
        photo = request.files['photo']
    else:
        photo = request.form['photo']
        photo = photo.replace('data:image/jpeg;base64,', '')
        photo = BytesIO(base64.b64decode(photo))

    email = request.form['email']
    password = request.form['password']
    uid = str(uuid.uuid4())
    salt = bcrypt.gensalt()
    password_hash = bcrypt.hashpw(password.encode('utf8'), salt)

    upload_config = TransferConfig(use_threads=False)

    image_name = uid + ".jpg"

    result = s3_client.upload_fileobj(photo,
                                      s3_bucket_name,
                                      image_name,
                                      ExtraArgs={
                                          "ACL": "public-read",
                                          "ContentType": "image/jpeg"
                                      },
                                      Config=upload_config)

    photo_url = "https://s3-ap-northeast-1.amazonaws.com/awesome-transit-photo/" + \
        image_name

    ref = db.reference().child('user').child(uid)
    ref.set({"photo_url": photo_url, "balance": 10000, "email": email})

    result = reko_client.index_faces(
        CollectionId=face_collection_name,
        DetectionAttributes=["DEFAULT"],
        ExternalImageId=uid,
        Image=dict(S3Object=dict(Bucket=s3_bucket_name, Name=image_name)))

    user = auth.ImportUserRecord(uid,
                                 email=email,
                                 photo_url=photo_url,
                                 password_hash=password_hash,
                                 password_salt=salt)

    result = auth.import_users([user], hash_alg=auth.UserImportHash.bcrypt())

    return jsonify(dict(reuslt=True))
def import_with_bcrypt():
    # [START import_with_bcrypt]
    users = [
        auth.ImportUserRecord(uid='some-uid',
                              email='*****@*****.**',
                              password_hash=b'password_hash',
                              password_salt=b'salt'),
    ]

    hash_alg = auth.UserImportHash.bcrypt()
    try:
        result = auth.import_users(users, hash_alg=hash_alg)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
def import_with_pbkdf():
    # [START import_with_pbkdf]
    users = [
        auth.ImportUserRecord(uid='some-uid',
                              email='*****@*****.**',
                              password_hash=b'password_hash',
                              password_salt=b'salt'),
    ]

    hash_alg = auth.UserImportHash.pbkdf2_sha256(rounds=100000)
    try:
        result = auth.import_users(users, hash_alg=hash_alg)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
def new_user_with_provider() -> auth.UserRecord:
    uid4, email4 = _random_id()
    google_uid, google_email = _random_id()
    import_user1 = auth.ImportUserRecord(uid=uid4,
                                         email=email4,
                                         provider_data=[
                                             auth.UserProvider(
                                                 uid=google_uid,
                                                 provider_id='google.com',
                                                 email=google_email,
                                             )
                                         ])
    user_import_result = auth.import_users([import_user1])
    assert user_import_result.success_count == 1
    assert user_import_result.failure_count == 0

    user = auth.get_user(uid4)
    yield user
    auth.delete_user(user.uid)
def import_with_standard_scrypt():
    # [START import_with_standard_scrypt]
    users = [
        auth.ImportUserRecord(uid='some-uid',
                              email='*****@*****.**',
                              password_hash=b'password_hash',
                              password_salt=b'salt'),
    ]

    hash_alg = auth.UserImportHash.standard_scrypt(memory_cost=1024,
                                                   parallelization=16,
                                                   block_size=8,
                                                   derived_key_length=64)
    try:
        result = auth.import_users(users, hash_alg=hash_alg)
        for err in result.errors:
            print('Failed to import user:'******'Error importing users:', error)
Exemple #23
0
def migrate_users():
    try:
        connection = mysql.connector.connect(host='db',
                                             database='migrate_users',
                                             user='******',
                                             password='******')
        if connection.is_connected():
            cursor = connection.cursor()
            query = "SELECT username, email, password, id FROM user_migrate WHERE uid IS NULL ORDER BY id ASC LIMIT 1000"
            cursor.execute(query)
            records = cursor.fetchall()
            users = []
            for row in records:
                uid = secrets.token_hex(16)
                users.append(
                    auth.ImportUserRecord(
                        uid=uid,
                        display_name=row[0],
                        email=row[1],
                        password_hash=bytes(row[2], encoding='utf-8'),
                        password_salt=bytes(row[2][:28], encoding='utf-8')))
                update_query = "UPDATE user_migrate SET uid = %s WHERE id = %s"
                cursor.execute(update_query, (uid, row[3]))
                connection.commit()
            hash_alg = auth.UserImportHash.bcrypt()
            try:
                result = auth.import_users(users, hash_alg=hash_alg)
                for err in result.errors:
                    print('Failed to import user:'******'user migrated !')
            except exceptions.FirebaseError as error:
                print('Error importing users:', error)
    except Error as e:
        print("Error while connecting to MySQL", e)
    finally:
        if (connection.is_connected()):
            cursor.close()
            connection.close()
Exemple #24
0
    def reduce(key, values):
        if key == POPULATED_KEY:
            yield (AUDIT_KEY, len(values))
            return
        elif key == SYSTEM_COMMITTER_ACK:
            yield (SYSTEM_COMMITTER_ACK, values)
            return

        try:
            # NOTE: "app" is the term Firebase uses for the "entry point" to the
            # Firebase SDK. Oppia only has one server, so it only needs to
            # instantiate one app.
            firebase_connection = firebase_admin.initialize_app()
        except Exception as exception:
            yield (WARNING_KEY, repr(exception))
            return

        # NOTE: This is only sorted to make unit testing easier.
        user_fields = sorted(ast.literal_eval(v) for v in values)
        user_records = [
            firebase_auth.ImportUserRecord(uid=auth_id,
                                           email=email,
                                           email_verified=True)
            for auth_id, _, email in user_fields
        ]

        # The Firebase Admin SDK places a hard-limit on the number of users that
        # can be "imported" in a single call. To compensate, we break up the
        # users into chunks.
        offsets = python_utils.RANGE(0, len(user_records),
                                     MAX_USERS_FIREBASE_CAN_IMPORT_PER_CALL)
        results = (_populate_firebase(
            [record for record in record_group if record])
                   for record_group in _grouper(
                       user_records, MAX_USERS_FIREBASE_CAN_IMPORT_PER_CALL))

        assocs_to_create = []
        for offset, (result, exception) in python_utils.ZIP(offsets, results):
            if exception is not None:
                yield (FAILURE_KEY, repr(exception))
            else:
                successful_indices = set(
                    python_utils.RANGE(result.success_count +
                                       result.failure_count))
                for error in result.errors:
                    successful_indices.remove(error.index)
                    debug_info = (
                        'Import user_id=%r failed: %s' %
                        (user_fields[offset + error.index][1], error.reason))
                    yield (FAILURE_KEY, debug_info)
                assocs_to_create.extend(
                    auth_domain.AuthIdUserIdPair(*user_fields[offset + i][:2])
                    for i in successful_indices)

        if assocs_to_create:
            firebase_auth_services.associate_multi_auth_ids_with_user_ids(
                assocs_to_create)
            yield (SUCCESS_KEY, len(assocs_to_create))

        try:
            # NOTE: This is not dangerous. We are just deleting the resources
            # used to form a connection to Firebase servers.
            firebase_admin.delete_app(firebase_connection)
        except Exception as exception:
            yield (WARNING_KEY, repr(exception))
Exemple #25
0
 def test_disabled(self, disabled):
     user = auth.ImportUserRecord(uid='test', disabled=disabled)
     assert user.disabled == disabled
     assert user.to_dict() == {'localId': 'test', 'disabled': disabled}
Exemple #26
0
 def test_too_many_users(self, user_mgt_app):
     users = [
         auth.ImportUserRecord(uid='test{0}'.format(i)) for i in range(1001)
     ]
     with pytest.raises(ValueError):
         auth.import_users(users, app=user_mgt_app)
Exemple #27
0
 def test_invalid_args(self, args):
     with pytest.raises(ValueError):
         auth.ImportUserRecord(uid='test', **args)
Exemple #28
0
 def test_invalid_uid(self, arg):
     with pytest.raises(ValueError):
         auth.ImportUserRecord(uid=arg)
Exemple #29
0
 def test_uid(self):
     user = auth.ImportUserRecord(uid='test')
     assert user.uid == 'test'
     assert user.custom_claims is None
     assert user.user_metadata is None
     assert user.to_dict() == {'localId': 'test'}
Exemple #30
0
def seed_firebase():
    """Prepares Oppia and Firebase to run the SeedFirebaseOneOffJob.

    NOTE: This function is idempotent.

    TODO(#11462): Delete this handler once the Firebase migration logic is
    rollback-safe and all backup data is using post-migration data.
    """
    seed_model = auth_models.FirebaseSeedModel.get(
        auth_models.ONLY_FIREBASE_SEED_MODEL_ID, strict=False)
    if seed_model is None:  # Exactly 1 seed model must exist.
        auth_models.FirebaseSeedModel(
            id=auth_models.ONLY_FIREBASE_SEED_MODEL_ID).put()

    user_ids_with_admin_email = [
        key.id() for key in user_models.UserSettingsModel.query(
            user_models.UserSettingsModel.email ==
            feconf.ADMIN_EMAIL_ADDRESS).iter(keys_only=True)
    ]
    assoc_by_user_id_models = [
        model for model in auth_models.UserAuthDetailsModel.get_multi(
            user_ids_with_admin_email)
        if model is not None and model.gae_id != feconf.SYSTEM_COMMITTER_ID
    ]
    if len(assoc_by_user_id_models) != 1:
        raise Exception(
            '%s must correspond to exactly 1 user (excluding user_id=%s), but '
            'found user_ids=[%s]' %
            (feconf.ADMIN_EMAIL_ADDRESS, feconf.SYSTEM_COMMITTER_ID, ', '.join(
                m.id for m in assoc_by_user_id_models)))
    else:
        assoc_by_user_id_model = assoc_by_user_id_models[0]
        user_id = assoc_by_user_id_model.id

    auth_id = assoc_by_user_id_model.firebase_auth_id
    if auth_id is None:
        auth_id = user_id[4:] if user_id.startswith('uid_') else user_id
        assoc_by_user_id_model.firebase_auth_id = auth_id
        assoc_by_user_id_model.update_timestamps(
            update_last_updated_time=False)
        assoc_by_user_id_model.put()

    assoc_by_auth_id_model = (auth_models.UserIdByFirebaseAuthIdModel.get(
        auth_id, strict=False))
    if assoc_by_auth_id_model is None:
        auth_models.UserIdByFirebaseAuthIdModel(id=auth_id,
                                                user_id=user_id).put()
    elif assoc_by_auth_id_model.user_id != user_id:
        assoc_by_auth_id_model.user_id = user_id
        assoc_by_auth_id_model.update_timestamps(
            update_last_updated_time=False)
        assoc_by_auth_id_model.put()

    custom_claims = '{"role":"%s"}' % feconf.FIREBASE_ROLE_SUPER_ADMIN

    try:
        user = firebase_auth.get_user_by_email(feconf.ADMIN_EMAIL_ADDRESS)
    except firebase_auth.UserNotFoundError:
        create_new_firebase_account = True
    else:
        if user.uid != auth_id:
            firebase_auth.update_user(user.uid, disabled=True)
            firebase_auth.delete_user(user.uid)
            create_new_firebase_account = True
        else:
            firebase_auth.set_custom_user_claims(user.uid, custom_claims)
            create_new_firebase_account = False

    if create_new_firebase_account:
        firebase_auth.import_users([
            firebase_auth.ImportUserRecord(auth_id,
                                           email=feconf.ADMIN_EMAIL_ADDRESS,
                                           custom_claims=custom_claims),
        ])