Skip to content

Commit d149502

Browse files
mdtrotrillville
authored andcommitted
migration: backfill apitoken last characters (#63342)
Backfills the `token_last_characters` column on existing `ApiToken` entries. As of #62972, new `ApiToken` entries are being created with this column already populated with the correct values. This backfill will only impact old tokens created prior. Tracking Issue: #58918 Related RFC: getsentry/rfcs#32
1 parent 97f5611 commit d149502

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

migrations_lockfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ feedback: 0003_feedback_add_env
99
hybridcloud: 0009_make_user_id_optional_for_slug_reservation_replica
1010
nodestore: 0002_nodestore_no_dictfield
1111
replays: 0003_add_size_to_recording_segment
12-
sentry: 0631_add_priority_columns_to_groupedmessage
12+
sentry: 0632_apitoken_backfill_last_chars
1313
social_auth: 0002_default_auto_field
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Generated by Django 3.2.23 on 2024-01-17 16:06
2+
3+
from django.db import migrations
4+
5+
from sentry.new_migrations.migrations import CheckedMigration
6+
from sentry.utils.query import RangeQuerySetWrapperWithProgressBar
7+
8+
9+
def backfill_last_token_characters(apps, _):
10+
from sentry.models.apitoken import ApiToken
11+
12+
for api_token in RangeQuerySetWrapperWithProgressBar(ApiToken.objects.all()):
13+
if api_token.token_last_characters is None:
14+
last_four = api_token.token[-4:]
15+
api_token.token_last_characters = last_four
16+
api_token.save()
17+
18+
19+
class Migration(CheckedMigration):
20+
# This flag is used to mark that a migration shouldn't be automatically run in production. For
21+
# the most part, this should only be used for operations where it's safe to run the migration
22+
# after your code has deployed. So this should not be used for most operations that alter the
23+
# schema of a table.
24+
# Here are some things that make sense to mark as dangerous:
25+
# - Large data migrations. Typically we want these to be run manually by ops so that they can
26+
# be monitored and not block the deploy for a long period of time while they run.
27+
# - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
28+
# have ops run this and not block the deploy. Note that while adding an index is a schema
29+
# change, it's completely safe to run the operation after the code has deployed.
30+
is_dangerous = True
31+
32+
dependencies = [
33+
("sentry", "0631_add_priority_columns_to_groupedmessage"),
34+
]
35+
36+
operations = [
37+
migrations.RunPython(
38+
backfill_last_token_characters,
39+
migrations.RunPython.noop,
40+
hints={
41+
"tables": [
42+
"sentry_apitoken",
43+
]
44+
},
45+
),
46+
]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.db import router
2+
3+
from sentry.silo import unguarded_write
4+
from sentry.testutils.cases import TestMigrations
5+
from sentry.testutils.helpers import override_options
6+
7+
8+
class LastCharsApiTokenMigrationTest(TestMigrations):
9+
migrate_from = "0631_add_priority_columns_to_groupedmessage"
10+
migrate_to = "0632_apitoken_backfill_last_chars"
11+
connection = "control"
12+
13+
def setUp(self):
14+
from sentry.models.apitoken import ApiToken
15+
16+
with unguarded_write(using=router.db_for_write(ApiToken)):
17+
super().setUp()
18+
19+
@override_options({"apitoken.auto-add-last-chars": False})
20+
def setup_before_migration(self, apps):
21+
ApiToken = apps.get_model("sentry", "ApiToken")
22+
23+
self.api_token = ApiToken.objects.create(
24+
user_id=self.user.id,
25+
refresh_token=None,
26+
)
27+
self.api_token.save()
28+
29+
assert self.api_token.token_last_characters is None
30+
31+
def test(self):
32+
from sentry.models.apitoken import ApiToken
33+
34+
api_tokens = ApiToken.objects.all()
35+
for api_token in api_tokens:
36+
assert api_token.name is None
37+
assert api_token.token_last_characters == api_token.token[-4:]

0 commit comments

Comments
 (0)