1212import com .auth0 .jwt .exceptions .JWTVerificationException ;
1313import io .javalin .Javalin ;
1414import io .javalin .http .Context ;
15- import io .javalin .http .ForbiddenResponse ;
16- import io .javalin .http .RedirectResponse ;
1715
1816import java .util .Base64 ;
1917
2018public class Main {
2119 static final long ONE_HOUR_IN_SECONDS = 3600 ; // 60 * 60
20+ static final long ONE_MINUTE_IN_SECONDS = 60 ;
2221
23- public static boolean userIsAllowed (OpenIdInfo info ) {
22+ public static boolean userIsAllowed (OpenIdInfo info ) {
2423 String whitelist = Config .userMailWhitelist ();
2524
2625 if (whitelist == null || whitelist .length () == 0 ) {
2726 // allow any user
2827 return true ;
2928 }
3029
31- if (
32- info == null || info .email () == null || info .email ().length () == 0
33- ) {
30+ if (info == null || info .email () == null || info .email ().length () == 0 ) {
3431 throw new Error ("Unexpected parameters for 'userIsAllowed'" );
3532 }
3633
3734 String [] allowed = whitelist .split (";" );
3835
39- for (String s : allowed ) {
36+ for (String s : allowed ) {
4037 if (s .equalsIgnoreCase (info .email ())) {
4138 return true ;
4239 }
@@ -54,83 +51,63 @@ public static void main(String[] args) {
5451 System .out .println ("Warning: local accounts are enabled, this is not safe for production!" );
5552 System .out .println ("********************" );
5653 app .post ("/login/local" , ctx -> {
57- try {
58- String sub = ctx .formParam ("sub" );
59- if (sub == null || sub .isBlank ()) throw new RuntimeException ("Please provide a username" );
60- String name = sub ;
61- String email = sub + "@example.com" ;
62- String organisation = "Example organisation" ;
63- OpenIdInfo localInfo = new OpenIdInfo (sub , name , email , organisation );
64-
65- AccountInfo accountInfo = new PostgrestAccount ().account (localInfo , OpenidProvider .local );
66- boolean isAdmin = isAdmin (email );
67- createAndSetToken (ctx , accountInfo , isAdmin );
68- } catch (RuntimeException ex ) {
69- ex .printStackTrace ();
70- ctx .redirect ("/login/failed" );
71- }
54+ String sub = ctx .formParam ("sub" );
55+ if (sub == null || sub .isBlank ()) throw new RuntimeException ("Please provide a username" );
56+ String name = sub ;
57+ String email = sub + "@example.com" ;
58+ String organisation = "Example organisation" ;
59+ OpenIdInfo localInfo = new OpenIdInfo (sub , name , email , organisation );
60+
61+ AccountInfo accountInfo = new PostgrestAccount ().account (localInfo , OpenidProvider .local );
62+ boolean isAdmin = isAdmin (email );
63+ createAndSetToken (ctx , accountInfo , isAdmin );
7264 });
7365 }
7466
7567 if (Config .isSurfConextEnabled ()) {
7668 app .post ("/login/surfconext" , ctx -> {
77- try {
78- String code = ctx .formParam ("code" );
79- String redirectUrl = Config .surfconextRedirect ();
80- OpenIdInfo surfconextInfo = new SurfconextLogin (code , redirectUrl ).openidInfo ();
81-
82- if (!userIsAllowed (surfconextInfo )) {
83- throw new RuntimeException ("User is not whitelisted" );
84- }
85-
86- AccountInfo accountInfo = new PostgrestAccount ().account (surfconextInfo , OpenidProvider .surfconext );
87- String email = surfconextInfo .email ();
88- boolean isAdmin = isAdmin (email );
89- createAndSetToken (ctx , accountInfo , isAdmin );
90- } catch (RuntimeException ex ) {
91- ex .printStackTrace ();
92- ctx .redirect ("/login/failed" );
69+ String code = ctx .formParam ("code" );
70+ String redirectUrl = Config .surfconextRedirect ();
71+ OpenIdInfo surfconextInfo = new SurfconextLogin (code , redirectUrl ).openidInfo ();
72+
73+ if (!userIsAllowed (surfconextInfo )) {
74+ throw new RsdAuthenticationException ("Your email address (" + surfconextInfo .email () + ") is not whitelisted." );
9375 }
76+
77+ AccountInfo accountInfo = new PostgrestAccount ().account (surfconextInfo , OpenidProvider .surfconext );
78+ String email = surfconextInfo .email ();
79+ boolean isAdmin = isAdmin (email );
80+ createAndSetToken (ctx , accountInfo , isAdmin );
9481 });
9582 }
9683
9784 if (Config .isHelmholtzEnabled ()) {
9885 app .get ("/login/helmholtzaai" , ctx -> {
99- try {
100- String code = ctx .queryParam ("code" );
101- String redirectUrl = Config .helmholtzAaiRedirect ();
102- OpenIdInfo helmholtzInfo = new HelmholtzAaiLogin (code , redirectUrl ).openidInfo ();
103-
104- if (!userIsAllowed (helmholtzInfo )) {
105- throw new RuntimeException ("User is not whitelisted" );
106- }
107-
108- AccountInfo accountInfo = new PostgrestAccount ().account (helmholtzInfo , OpenidProvider .helmholtz );
109- String email = helmholtzInfo .email ();
110- boolean isAdmin = isAdmin (email );
111- createAndSetToken (ctx , accountInfo , isAdmin );
112- } catch (RuntimeException ex ) {
113- ex .printStackTrace ();
114- ctx .redirect ("/login/failed" );
86+ String code = ctx .queryParam ("code" );
87+ String redirectUrl = Config .helmholtzAaiRedirect ();
88+ OpenIdInfo helmholtzInfo = new HelmholtzAaiLogin (code , redirectUrl ).openidInfo ();
89+
90+ if (!userIsAllowed (helmholtzInfo )) {
91+ throw new RsdAuthenticationException ("Your email address (" + helmholtzInfo .email () + ") is not whitelisted." );
11592 }
93+
94+ AccountInfo accountInfo = new PostgrestAccount ().account (helmholtzInfo , OpenidProvider .helmholtz );
95+ String email = helmholtzInfo .email ();
96+ boolean isAdmin = isAdmin (email );
97+ createAndSetToken (ctx , accountInfo , isAdmin );
11698 });
11799 }
118100
119101 if (Config .isOrcidEnabled ()) {
120102 app .get ("/login/orcid" , ctx -> {
121- try {
122- String code = ctx .queryParam ("code" );
123- String redirectUrl = Config .orcidRedirect ();
124- OpenIdInfo orcidInfo = new OrcidLogin (code , redirectUrl ).openidInfo ();
125-
126- AccountInfo accountInfo = new PostgrestCheckOrcidWhitelistedAccount (new PostgrestAccount ()).account (orcidInfo , OpenidProvider .orcid );
127- String email = orcidInfo .email ();
128- boolean isAdmin = isAdmin (email );
129- createAndSetToken (ctx , accountInfo , isAdmin );
130- } catch (RuntimeException ex ) {
131- ex .printStackTrace ();
132- ctx .redirect ("/login/failed" );
133- }
103+ String code = ctx .queryParam ("code" );
104+ String redirectUrl = Config .orcidRedirect ();
105+ OpenIdInfo orcidInfo = new OrcidLogin (code , redirectUrl ).openidInfo ();
106+
107+ AccountInfo accountInfo = new PostgrestCheckOrcidWhitelistedAccount (new PostgrestAccount ()).account (orcidInfo , OpenidProvider .orcid );
108+ String email = orcidInfo .email ();
109+ boolean isAdmin = isAdmin (email );
110+ createAndSetToken (ctx , accountInfo , isAdmin );
134111 });
135112 }
136113
@@ -156,6 +133,17 @@ public static void main(String[] args) {
156133 ctx .status (400 );
157134 ctx .json ("{\" message\" : \" invalid JWT\" }" );
158135 });
136+
137+ app .exception (RsdAuthenticationException .class , (ex , ctx ) -> {
138+ setLoginFailureCookie (ctx , ex .getMessage ());
139+ ctx .redirect ("/login/failed" );
140+ });
141+
142+ app .exception (RuntimeException .class , (ex , ctx ) -> {
143+ ex .printStackTrace ();
144+ setLoginFailureCookie (ctx , "Something unexpected went wrong, please try again or contact us." );
145+ ctx .redirect ("/login/failed" );
146+ });
159147 }
160148
161149 static boolean isAdmin (String email ) {
@@ -173,6 +161,10 @@ static void setJwtCookie(Context ctx, String token) {
173161 ctx .header ("Set-Cookie" , "rsd_token=" + token + "; Secure; HttpOnly; Path=/; SameSite=Lax; Max-Age=" + ONE_HOUR_IN_SECONDS );
174162 }
175163
164+ static void setLoginFailureCookie (Context ctx , String message ) {
165+ ctx .header ("Set-Cookie" , "rsd_login_failure_message=" + message + "; Secure; Path=/login/failed; SameSite=Lax; Max-Age=" + ONE_MINUTE_IN_SECONDS );
166+ }
167+
176168 static void setRedirectFromCookie (Context ctx ) {
177169 String returnPath = ctx .cookie ("rsd_pathname" );
178170 if (returnPath != null && !returnPath .isBlank ()) {
0 commit comments