Partially support federated login

Two things:
1. I've never attempted to support this before.
2. It seems surprisingly and perhaps deceptively simpler than what I
   expected. I'm unsure what to do once Google's API authenticates the user. I
   currently look-up the user's role, trips, etc. using their email address. The
   role is stored in the Accounts table alongside username, email, password. I
   will speak with the interviewer tomorrow about this.
This commit is contained in:
William Carroll 2020-08-02 21:27:08 +01:00
parent d6b91b93cb
commit b9ed4a2dc1
4 changed files with 59 additions and 17 deletions

View file

@ -13,19 +13,7 @@
<div id="mount"></div> <div id="mount"></div>
<script> <script>
function onSignIn(googleUser) { function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile(); console.log(googleUser);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
}
function signOut() {
console.log('Signing out!');
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function() {
console.log('User signed out.');
});
} }
var app = Elm.Main.init({node: document.getElementById("mount")}); var app = Elm.Main.init({node: document.getElementById("mount")});
@ -33,6 +21,18 @@
app.ports.printPage.subscribe(function() { app.ports.printPage.subscribe(function() {
window.print(); window.print();
}); });
app.ports.googleSignIn.subscribe(function() {
var auth2 = gapi.auth2.getAuthInstance();
var googleUser = auth2.signIn();
});
app.ports.googleSignOut.subscribe(function() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function() {
console.log('Google user successfully signed out.');
});
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -10,6 +10,16 @@ import UI
import Utils import Utils
googleSignIn : Html State.Msg
googleSignIn =
div
[ class "g-signin2"
, attribute "onsuccess" "onSignIn"
, onClick State.GoogleSignIn
]
[]
loginForm : State.Model -> Html State.Msg loginForm : State.Model -> Html State.Msg
loginForm model = loginForm model =
div div
@ -111,11 +121,28 @@ loginForm model =
] ]
, case model.loginTab of , case model.loginTab of
State.LoginForm -> State.LoginForm ->
UI.simpleButton { handleClick = State.AttemptLogin, label = "Login" } div [ [ "flex", "space-around" ] |> Tailwind.use |> class ]
[ UI.simpleButton
{ handleClick = State.AttemptLogin
, label = "Login"
}
, div [ [ "pl-4" ] |> Tailwind.use |> class ] [ googleSignIn ]
]
State.SignUpForm -> State.SignUpForm ->
if String.length model.username > 0 && String.length model.email > 0 && String.length model.password > 0 then if
UI.simpleButton { handleClick = State.AttemptSignUp, label = "Sign up" } List.all identity
[ String.length model.username > 0
, String.length model.email > 0
, String.length model.password > 0
]
then
div []
[ UI.simpleButton
{ handleClick = State.AttemptSignUp
, label = "Sign up"
}
]
else else
UI.disabledButton { label = "Sign up" } UI.disabledButton { label = "Sign up" }

View file

@ -43,6 +43,8 @@ type Msg
| ClearErrors | ClearErrors
| ToggleLoginForm | ToggleLoginForm
| PrintPage | PrintPage
| GoogleSignIn
| GoogleSignOut
| UpdateInviteEmail String | UpdateInviteEmail String
| UpdateInviteRole (Maybe Role) | UpdateInviteRole (Maybe Role)
| ReceiveTodaysDate Date.Date | ReceiveTodaysDate Date.Date
@ -608,6 +610,12 @@ adminHome flags url key =
port printPage : () -> Cmd msg port printPage : () -> Cmd msg
port googleSignIn : () -> Cmd msg
port googleSignOut : () -> Cmd msg
{-| The initial state for the application. {-| The initial state for the application.
-} -}
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
@ -732,6 +740,12 @@ update msg model =
PrintPage -> PrintPage ->
( model, printPage () ) ( model, printPage () )
GoogleSignIn ->
( model, googleSignIn () )
GoogleSignOut ->
( model, googleSignOut () )
UpdateInviteEmail x -> UpdateInviteEmail x ->
( { model | inviteEmail = x }, Cmd.none ) ( { model | inviteEmail = x }, Cmd.none )

View file

@ -98,7 +98,8 @@ baseButton { label, enabled, handleClick, extraClasses } =
"cursor-not-allowed" "cursor-not-allowed"
, "text-white" , "text-white"
, "font-bold" , "font-bold"
, "py-2" , "py-1"
, "shadow-lg"
, "px-4" , "px-4"
, "rounded" , "rounded"
, "focus:outline-none" , "focus:outline-none"