@@ -8,21 +8,27 @@ defmodule Livebook.ZTA.LivebookTeams do
88
99 @ behaviour NimbleZTA
1010
11- @ impl true
11+ @ exp_timestamp_sec System . os_time ( :second ) + 3 * 3600
12+
13+ @ impl NimbleZTA
1214 def child_spec ( opts ) do
1315 % { id: __MODULE__ , start: { __MODULE__ , :start_link , [ opts ] } }
1416 end
1517
1618 def start_link ( opts ) do
1719 name = Keyword . fetch! ( opts , :name )
18- identity_key = Keyword . fetch! ( opts , :identity_key )
19- team = Livebook.Hubs . fetch_hub! ( identity_key )
20+ id = Keyword . fetch! ( opts , :identity_key )
21+ team = Livebook.Hubs . fetch_hub! ( id )
22+
23+ if :ets . whereis ( __MODULE__ ) == :undefined do
24+ :ets . new ( __MODULE__ , [ :named_table , :public , :set , read_concurrency: true ] )
25+ end
2026
2127 NimbleZTA . put ( name , team )
2228 :ignore
2329 end
2430
25- @ impl true
31+ @ impl NimbleZTA
2632 def authenticate ( name , conn , _opts ) do
2733 team = NimbleZTA . get ( name )
2834
@@ -53,7 +59,10 @@ defmodule Livebook.ZTA.LivebookTeams do
5359
5460 defp handle_request ( conn , team , % { "teams_identity" => _ , "code" => code } ) do
5561 with { :ok , access_token } <- retrieve_access_token ( team , code ) ,
56- { :ok , metadata } <- get_user_info ( team , access_token ) do
62+ { :ok , payload } <- Teams.Requests . get_user_info ( team , access_token ) do
63+ metadata = build_metadata ( team . id , payload )
64+ :ets . insert ( __MODULE__ , { access_token , { @ exp_timestamp_sec , metadata } } )
65+
5766 { conn
5867 |> put_session ( :livebook_teams_access_token , access_token )
5968 |> redirect ( to: conn . request_path )
@@ -99,7 +108,6 @@ defmodule Livebook.ZTA.LivebookTeams do
99108 % { "livebook_teams_access_token" => access_token } ->
100109 validate_access_token ( conn , team , access_token )
101110
102- # it means, we couldn't reach to Teams server
103111 % { "teams_error" => true } ->
104112 { conn
105113 |> put_status ( :bad_request )
@@ -124,13 +132,6 @@ defmodule Livebook.ZTA.LivebookTeams do
124132 end
125133 end
126134
127- defp validate_access_token ( conn , team , access_token ) do
128- case get_user_info ( team , access_token ) do
129- { :ok , metadata } -> { conn , metadata }
130- _ -> request_user_authentication ( conn )
131- end
132- end
133-
134135 defp retrieve_access_token ( team , code ) do
135136 with { :ok , % { "access_token" => access_token } } <-
136137 Teams.Requests . retrieve_access_token ( team , code ) do
@@ -167,9 +168,31 @@ defmodule Livebook.ZTA.LivebookTeams do
167168 { conn |> html ( html_document ) |> halt ( ) , nil }
168169 end
169170
170- defp get_user_info ( team , access_token ) do
171- with { :ok , payload } <- Teams.Requests . get_user_info ( team , access_token ) do
172- { :ok , build_metadata ( team . id , payload ) }
171+ defp validate_access_token ( conn , team , access_token ) do
172+ case Teams.Requests . get_user_info ( team , access_token ) do
173+ { :ok , payload } ->
174+ { conn , build_metadata ( team . id , payload ) }
175+
176+ :econnrefused ->
177+ data = :ets . lookup_element ( __MODULE__ , access_token , 2 , nil )
178+
179+ case { System . os_time ( :second ) , data } do
180+ { current_timestamp , { exp , metadata } } when current_timestamp <= exp ->
181+ { conn , metadata }
182+
183+ { _ , entry } ->
184+ entry && :ets . delete ( __MODULE__ , access_token )
185+
186+ { conn
187+ |> put_status ( :service_unavailable )
188+ |> put_view ( LivebookWeb.ErrorHTML )
189+ |> render ( "503.html" )
190+ |> halt ( ) , nil }
191+ end
192+
193+ _otherwise ->
194+ :ets . delete ( __MODULE__ , access_token )
195+ request_user_authentication ( conn )
173196 end
174197 end
175198
0 commit comments