@@ -6,11 +6,15 @@ defmodule Algora.Accounts do
66 alias Algora.Accounts.Identity
77 alias Algora.Accounts.User
88 alias Algora.Bounties.Bounty
9+ alias Algora.Contracts.Contract
910 alias Algora.Github
1011 alias Algora.Organizations
1112 alias Algora.Organizations.Member
1213 alias Algora.Payments.Transaction
1314 alias Algora.Repo
15+ alias Algora.Workspace.Contributor
16+ alias Algora.Workspace.Installation
17+ alias Algora.Workspace.Repository
1418
1519 require Algora.SQL
1620
@@ -246,7 +250,7 @@ defmodule Algora.Accounts do
246250 @ doc """
247251 Registers a user from their GitHub information.
248252 """
249- def register_github_user ( primary_email , info , emails , token ) do
253+ def register_github_user ( current_user , primary_email , info , emails , token ) do
250254 query =
251255 from ( u in User ,
252256 left_join: i in Identity ,
@@ -257,10 +261,16 @@ defmodule Algora.Accounts do
257261 select: { u , i }
258262 )
259263
260- case Repo . one ( query ) do
264+ account =
265+ case Repo . all ( query ) do
266+ [ ] -> nil
267+ [ { user , identity } ] -> { user , identity }
268+ records -> Enum . find ( records , fn { user , _ } -> user . id == current_user . id end )
269+ end
270+
271+ case account do
261272 nil -> create_user ( info , primary_email , emails , token )
262- { user , nil } -> update_user ( user , info , primary_email , emails , token )
263- { user , _identity } -> update_github_token ( user , token )
273+ { user , identity } -> update_user ( user , identity , info , primary_email , emails , token )
264274 end
265275 end
266276
@@ -274,15 +284,74 @@ defmodule Algora.Accounts do
274284 |> Repo . insert ( )
275285 end
276286
277- def update_user ( user , info , primary_email , emails , token ) do
278- with { :ok , _ } <-
279- user
280- |> Identity . github_registration_changeset ( info , primary_email , emails , token )
281- |> Repo . insert ( ) do
282- user
283- |> User . github_registration_changeset ( info , primary_email , emails , token )
284- |> Repo . update ( )
285- end
287+ def update_user ( user , identity , info , primary_email , emails , token ) do
288+ old_user = Repo . get_by ( User , provider: "github" , provider_id: to_string ( info [ "id" ] ) )
289+
290+ identity_changeset = Identity . github_registration_changeset ( user , info , primary_email , emails , token )
291+
292+ user_changeset = User . github_registration_changeset ( user , info , primary_email , emails , token )
293+
294+ Repo . transact ( fn ->
295+ delete_result =
296+ if identity do
297+ Repo . delete ( identity )
298+ else
299+ { :ok , nil }
300+ end
301+
302+ migrate_result =
303+ if old_user && old_user . id != user . id do
304+ { :ok , old_user } =
305+ old_user
306+ |> change ( provider: nil , provider_id: nil , provider_login: nil , provider_meta: nil )
307+ |> Repo . update ( )
308+
309+ # TODO: enqueue job
310+ migrate_user ( old_user , user )
311+
312+ { :ok , old_user }
313+ else
314+ { :ok , nil }
315+ end
316+
317+ with { :ok , _ } <- delete_result ,
318+ { :ok , _ } <- migrate_result ,
319+ { :ok , _ } <- Repo . insert ( identity_changeset ) do
320+ Repo . update ( user_changeset )
321+ end
322+ end )
323+ end
324+
325+ def migrate_user ( old_user , new_user ) do
326+ Repo . update_all (
327+ from ( r in Repository , where: r . user_id == ^ old_user . id ) ,
328+ set: [ user_id: new_user . id ]
329+ )
330+
331+ Repo . update_all (
332+ from ( c in Contributor , where: c . user_id == ^ old_user . id ) ,
333+ set: [ user_id: new_user . id ]
334+ )
335+
336+ Repo . update_all (
337+ from ( c in Contract , where: c . contractor_id == ^ old_user . id ) ,
338+ set: [ contractor_id: new_user . id ]
339+ )
340+
341+ Repo . update_all (
342+ from ( i in Installation , where: i . owner_id == ^ old_user . id ) ,
343+ set: [ owner_id: new_user . id ]
344+ )
345+
346+ Repo . update_all (
347+ from ( i in Installation , where: i . provider_user_id == ^ old_user . id ) ,
348+ set: [ provider_user_id: new_user . id ]
349+ )
350+
351+ Repo . update_all (
352+ from ( i in Installation , where: i . connected_user_id == ^ old_user . id ) ,
353+ set: [ connected_user_id: new_user . id ]
354+ )
286355 end
287356
288357 # def get_user_by_provider_email(provider, email) when provider in [:github] do
@@ -352,19 +421,6 @@ defmodule Algora.Accounts do
352421 end
353422 end
354423
355- defp update_github_token ( % User { } = user , new_token ) do
356- identity =
357- Repo . one! ( from ( i in Identity , where: i . user_id == ^ user . id and i . provider == "github" ) )
358-
359- { :ok , _ } =
360- identity
361- |> change ( )
362- |> put_change ( :provider_token , new_token )
363- |> Repo . update ( )
364-
365- { :ok , Repo . preload ( user , :identities , force: true ) }
366- end
367-
368424 def last_context ( nil ) , do: "nil"
369425
370426 def last_context ( % User { last_context: nil } = user ) do
@@ -413,8 +469,20 @@ defmodule Algora.Accounts do
413469
414470 def get_last_context_user ( % User { } = user ) do
415471 case last_context ( user ) do
416- "personal" -> user
417- last_context -> get_user_by_handle ( last_context )
472+ "personal" ->
473+ user
474+
475+ "preview/" <> ctx ->
476+ case String . split ( ctx , "/" ) do
477+ [ id , _repo_owner , _repo_name ] -> get_user ( id )
478+ _ -> nil
479+ end
480+
481+ "repo/" <> _repo_full_name ->
482+ user
483+
484+ last_context ->
485+ get_user_by_handle ( last_context )
418486 end
419487 end
420488
0 commit comments