@@ -91,6 +91,7 @@ of this software and associated documentation files (the "Software"), to deal
91
91
import java .util .HashSet ;
92
92
import java .util .Set ;
93
93
import java .util .logging .Logger ;
94
+ import java .util .logging .Level ;
94
95
import javax .annotation .Nonnull ;
95
96
import javax .annotation .Nullable ;
96
97
@@ -107,12 +108,15 @@ public class GithubSecurityRealm extends AbstractPasswordBasedSecurityRealm impl
107
108
private static final String DEFAULT_API_URI = "https://api.github.com" ;
108
109
private static final String DEFAULT_ENTERPRISE_API_SUFFIX = "/api/v3" ;
109
110
private static final String DEFAULT_OAUTH_SCOPES = "read:org,user:email,repo" ;
111
+ private static final Boolean DEFAULT_FORCE_GITHUB_EMAIL = false ;
110
112
111
113
private String githubWebUri ;
112
114
private String githubApiUri ;
113
115
private String clientID ;
114
116
private Secret clientSecret ;
115
117
private String oauthScopes ;
118
+ private String emailDomains ;
119
+ private Boolean forceGithubEmail ;
116
120
private String [] myScopes ;
117
121
118
122
/**
@@ -123,20 +127,39 @@ public class GithubSecurityRealm extends AbstractPasswordBasedSecurityRealm impl
123
127
* @param clientID The client ID for the created OAuth Application.
124
128
* @param clientSecret The client secret for the created GitHub OAuth Application.
125
129
* @param oauthScopes A comma separated list of OAuth Scopes to request access to.
130
+ * @param emailDomains An optional comma separated list of domain(s) to select for email
131
+ * @param forceGithubEmail Force the email from github to override the one in the profile
126
132
*/
127
133
@ DataBoundConstructor
128
134
public GithubSecurityRealm (String githubWebUri ,
129
135
String githubApiUri ,
130
136
String clientID ,
131
137
String clientSecret ,
132
- String oauthScopes ) {
138
+ String oauthScopes ,
139
+ String emailDomains ,
140
+ Boolean forceGithubEmail ) {
133
141
super ();
134
142
135
143
this .githubWebUri = Util .fixEmptyAndTrim (githubWebUri );
136
144
this .githubApiUri = Util .fixEmptyAndTrim (githubApiUri );
137
145
this .clientID = Util .fixEmptyAndTrim (clientID );
138
146
setClientSecret (Util .fixEmptyAndTrim (clientSecret ));
139
147
this .oauthScopes = Util .fixEmptyAndTrim (oauthScopes );
148
+ this .emailDomains = emailDomains .trim ();
149
+ this .forceGithubEmail = forceGithubEmail ;
150
+ }
151
+
152
+ /**
153
+ This method is deprecated.
154
+ @deprecated use GithubSecurityRealm(githubWebUri, githubApiUri, clientID, clientSecret, oauthScopes, emailDomains, forceGithubEmail)
155
+ */
156
+ @ Deprecated
157
+ public GithubSecurityRealm (String githubWebUri ,
158
+ String githubApiUri ,
159
+ String clientID ,
160
+ String clientSecret ,
161
+ String oauthScopes ) {
162
+ this (githubWebUri , githubApiUri , clientID , clientSecret , oauthScopes , "" , false );
140
163
}
141
164
142
165
private GithubSecurityRealm () { }
@@ -186,6 +209,20 @@ private void setOauthScopes(String oauthScopes) {
186
209
this .oauthScopes = oauthScopes ;
187
210
}
188
211
212
+ /**
213
+ * @param emailDomains the emailDomains to set
214
+ */
215
+ private void setEmailDomains (String emailDomains ) {
216
+ this .emailDomains = emailDomains ;
217
+ }
218
+
219
+ /**
220
+ * @param forceGithubEmail the forceGithubEmail to set
221
+ */
222
+ private void setForceGithubEmail (Boolean forceGithubEmail ) {
223
+ this .forceGithubEmail = forceGithubEmail ;
224
+ }
225
+
189
226
/**
190
227
* Checks the security realm for a GitHub OAuth scope.
191
228
* @param scope A scope to check for in the security realm.
@@ -244,6 +281,20 @@ public void marshal(Object source, HierarchicalStreamWriter writer,
244
281
writer .setValue (realm .getOauthScopes ());
245
282
writer .endNode ();
246
283
284
+ writer .startNode ("emailDomains" );
285
+ writer .setValue (realm .getEmailDomains ());
286
+ writer .endNode ();
287
+
288
+ writer .startNode ("forceGithubEmail" );
289
+ //TODO: Is there a better way to do this?
290
+ if (realm .getForceGithubEmail ()) {
291
+ writer .setValue ("true" );
292
+ }
293
+ else {
294
+ writer .setValue ("false" );
295
+ }
296
+ writer .endNode ();
297
+
247
298
}
248
299
249
300
public Object unmarshal (HierarchicalStreamReader reader ,
@@ -270,6 +321,10 @@ public Object unmarshal(HierarchicalStreamReader reader,
270
321
realm .setGithubApiUri (DEFAULT_API_URI );
271
322
}
272
323
324
+ if (realm .getForceGithubEmail () == null ) {
325
+ realm .setForceGithubEmail (DEFAULT_FORCE_GITHUB_EMAIL );
326
+ }
327
+
273
328
return realm ;
274
329
}
275
330
@@ -289,6 +344,15 @@ private void setValue(GithubSecurityRealm realm, String node,
289
344
realm .setGithubApiUri (value );
290
345
} else if (node .toLowerCase ().equals ("oauthscopes" )) {
291
346
realm .setOauthScopes (value );
347
+ } else if (node .toLowerCase ().equals ("emaildomains" )) {
348
+ realm .setEmailDomains (value );
349
+ } else if (node .toLowerCase ().equals ("forcegithubemail" )) {
350
+ if (value .toLowerCase ().equals ("true" )){
351
+ realm .setForceGithubEmail (true );
352
+ }
353
+ else {
354
+ realm .setForceGithubEmail (false );
355
+ }
292
356
} else {
293
357
throw new ConversionException ("Invalid node value = " + node );
294
358
}
@@ -333,6 +397,20 @@ public String getOauthScopes() {
333
397
return oauthScopes ;
334
398
}
335
399
400
+ /**
401
+ * @return the emailDomains
402
+ */
403
+ public String getEmailDomains () {
404
+ return emailDomains ;
405
+ }
406
+
407
+ /**
408
+ * @return the forceGithubEmail
409
+ */
410
+ public Boolean getForceGithubEmail () {
411
+ return forceGithubEmail ;
412
+ }
413
+
336
414
public HttpResponse doCommenceLogin (StaplerRequest request , @ Header ("Referer" ) final String referer )
337
415
throws IOException {
338
416
request .getSession ().setAttribute (REFERER_ATTRIBUTE ,referer );
@@ -383,17 +461,40 @@ public HttpResponse doFinishLogin(StaplerRequest request)
383
461
GithubSecretStorage .put (u , accessToken );
384
462
385
463
u .setFullName (self .getName ());
386
- // Set email from github only if empty
387
- if (!u .getProperty (Mailer .UserProperty .class ).hasExplicitlyConfiguredAddress ()) {
464
+ // Set email from github only if empty or forceGithubEmail flag is set
465
+ if (forceGithubEmail || !u .getProperty (Mailer .UserProperty .class ).hasExplicitlyConfiguredAddress ()) {
388
466
if (hasScope ("user" ) || hasScope ("user:email" )) {
389
467
String primary_email = null ;
390
- for (GHEmail e : self .getEmails2 ()) {
391
- if (e .isPrimary ()) {
392
- primary_email = e .getEmail ();
468
+ String domain_email = null ;
469
+ if (emailDomains != null ) {
470
+ LOGGER .log (Level .FINE , "Searching for email of github user \" " + u .getId () + "\" that match domain(s) \" " + emailDomains + "\" " );
471
+ for (String emailDomain : emailDomains .split ("," )) {
472
+ for (GHEmail e : self .getEmails2 ()) {
473
+ LOGGER .log (Level .FINE , "Checking if email \" " + e .getEmail () + "\" matches domain \" " + emailDomain + "\" for github user \" " + u .getId () + "\" " );
474
+ if (e .getEmail ().endsWith ("@" + emailDomain )) {
475
+ domain_email = e .getEmail ();
476
+ LOGGER .log (Level .FINE , "Email \" " + e .getEmail () + "\" matches domain \" " + emailDomain + "\" for github user \" " + u .getId () + "\" " );
477
+ break ;
478
+ }
479
+ }
480
+ if (domain_email != null ) {
481
+ LOGGER .log (Level .FINE , "Setting email for github user \" " + u .getId () + "\" to \" " + domain_email + "\" due to matching domain in domain list" );
482
+ u .addProperty (new Mailer .UserProperty (domain_email ));
483
+ break ;
484
+ }
393
485
}
394
486
}
395
- if (primary_email != null ) {
396
- u .addProperty (new Mailer .UserProperty (primary_email ));
487
+ if (domain_email == null ) {
488
+ LOGGER .log (Level .FINE , "Getting primary email for github user \" " + u .getId () + "\" " );
489
+ for (GHEmail e : self .getEmails2 ()) {
490
+ LOGGER .log (Level .FINE , "Checking if email \" " + e .getEmail () + "\" is primary email for github user \" " + u .getId () + "\" " );
491
+ if (e .isPrimary ()) {
492
+ primary_email = e .getEmail ();
493
+ LOGGER .log (Level .FINE , "Setting email for github user \" " + u .getId () + "\" to primary address \" " + primary_email + "\" " );
494
+ u .addProperty (new Mailer .UserProperty (primary_email ));
495
+ break ;
496
+ }
497
+ }
397
498
}
398
499
} else {
399
500
u .addProperty (new Mailer .UserProperty (auth .getGitHub ().getMyself ().getEmail ()));
@@ -600,6 +701,10 @@ public String getDefaultOauthScopes() {
600
701
return DEFAULT_OAUTH_SCOPES ;
601
702
}
602
703
704
+ public Boolean getDefaultForceGithubEmail () {
705
+ return DEFAULT_FORCE_GITHUB_EMAIL ;
706
+ }
707
+
603
708
public DescriptorImpl () {
604
709
super ();
605
710
// TODO Auto-generated constructor stub
@@ -700,7 +805,9 @@ public boolean equals(Object object){
700
805
this .getGithubApiUri ().equals (obj .getGithubApiUri ()) &&
701
806
this .getClientID ().equals (obj .getClientID ()) &&
702
807
this .getClientSecret ().equals (obj .getClientSecret ()) &&
703
- this .getOauthScopes ().equals (obj .getOauthScopes ());
808
+ this .getOauthScopes ().equals (obj .getOauthScopes ()) &&
809
+ this .getEmailDomains ().equals (obj .getEmailDomains ()) &&
810
+ this .getForceGithubEmail ().equals (obj .getForceGithubEmail ());
704
811
} else {
705
812
return false ;
706
813
}
0 commit comments