@@ -165,19 +165,28 @@ def from_identifier(cls, id: None) -> None: ...
165
165
@classmethod
166
166
def from_identifier (cls , id : int | str ) -> "Actor" : ...
167
167
168
+ @overload
169
+ @classmethod
170
+ def from_identifier (cls , id : int | str , organization_id : int ) -> "Actor" : ...
171
+
168
172
@classmethod
169
- def from_identifier (cls , id : str | int | None ) -> "Actor | None" :
173
+ def from_identifier (
174
+ cls , id : str | int | None , organization_id : int | None = None
175
+ ) -> "Actor | None" :
170
176
"""
171
177
Parse an actor identifier into an Actor
172
178
173
179
Forms `id` can take:
174
180
1231 -> look up User by id
175
181
"1231" -> look up User by id
176
182
"user:1231" -> look up User by id
183
+ "user:maiseythedog" -> look up user by username
177
184
"team:1231" -> look up Team by id
185
+ "team:team-name" -> look up Team by name (must provide organization_id)
178
186
"maiseythedog" -> look up User by username
179
187
"[email protected] " -> look up User by primary email
180
188
"""
189
+ from sentry .models .team import Team
181
190
from sentry .users .services .user .service import user_service
182
191
183
192
if not id :
@@ -192,10 +201,25 @@ def from_identifier(cls, id: str | int | None) -> "Actor | None":
192
201
return cls (id = int (id ), actor_type = ActorType .USER )
193
202
194
203
if id .startswith ("user:" ):
195
- return cls (id = int (id [5 :]), actor_type = ActorType .USER )
204
+ remainder = id [5 :]
205
+ if remainder .isdigit ():
206
+ return cls (id = int (remainder ), actor_type = ActorType .USER )
207
+ # pass this on to get to the user lookup below
208
+ id = remainder
196
209
197
210
if id .startswith ("team:" ):
198
- return cls (id = int (id [5 :]), actor_type = ActorType .TEAM )
211
+ remainder = id [5 :]
212
+ if remainder .isdigit ():
213
+ return cls (id = int (remainder ), actor_type = ActorType .TEAM )
214
+
215
+ if organization_id is not None :
216
+ try :
217
+ team = Team .objects .get (name = remainder , organization_id = organization_id )
218
+ return cls (id = team .id , actor_type = ActorType .TEAM )
219
+ except Team .DoesNotExist :
220
+ pass
221
+
222
+ raise cls .InvalidActor (f"Unable to resolve team name: { remainder } " )
199
223
200
224
try :
201
225
user = user_service .get_by_username (username = id )[0 ]
@@ -280,7 +304,7 @@ def parse_and_validate_actor(actor_identifier: str | None, organization_id: int)
280
304
return None
281
305
282
306
try :
283
- actor = Actor .from_identifier (actor_identifier )
307
+ actor = Actor .from_identifier (actor_identifier , organization_id )
284
308
except Exception :
285
309
raise serializers .ValidationError (
286
310
"Could not parse actor. Format should be `type:id` where type is `team` or `user`."
0 commit comments