@@ -91,6 +91,7 @@ of this software and associated documentation files (the "Software"), to deal
9191import java .util .HashSet ;
9292import java .util .Set ;
9393import java .util .logging .Logger ;
94+ import java .util .logging .Level ;
9495import javax .annotation .Nonnull ;
9596import javax .annotation .Nullable ;
9697
@@ -107,12 +108,15 @@ public class GithubSecurityRealm extends AbstractPasswordBasedSecurityRealm impl
107108 private static final String DEFAULT_API_URI = "https://api.github.com" ;
108109 private static final String DEFAULT_ENTERPRISE_API_SUFFIX = "/api/v3" ;
109110 private static final String DEFAULT_OAUTH_SCOPES = "read:org,user:email,repo" ;
111+ private static final Boolean DEFAULT_FORCE_GITHUB_EMAIL = false ;
110112
111113 private String githubWebUri ;
112114 private String githubApiUri ;
113115 private String clientID ;
114116 private Secret clientSecret ;
115117 private String oauthScopes ;
118+ private String emailDomains ;
119+ private Boolean forceGithubEmail ;
116120 private String [] myScopes ;
117121
118122 /**
@@ -123,20 +127,39 @@ public class GithubSecurityRealm extends AbstractPasswordBasedSecurityRealm impl
123127 * @param clientID The client ID for the created OAuth Application.
124128 * @param clientSecret The client secret for the created GitHub OAuth Application.
125129 * @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
126132 */
127133 @ DataBoundConstructor
128134 public GithubSecurityRealm (String githubWebUri ,
129135 String githubApiUri ,
130136 String clientID ,
131137 String clientSecret ,
132- String oauthScopes ) {
138+ String oauthScopes ,
139+ String emailDomains ,
140+ Boolean forceGithubEmail ) {
133141 super ();
134142
135143 this .githubWebUri = Util .fixEmptyAndTrim (githubWebUri );
136144 this .githubApiUri = Util .fixEmptyAndTrim (githubApiUri );
137145 this .clientID = Util .fixEmptyAndTrim (clientID );
138146 setClientSecret (Util .fixEmptyAndTrim (clientSecret ));
139147 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 );
140163 }
141164
142165 private GithubSecurityRealm () { }
@@ -186,6 +209,20 @@ private void setOauthScopes(String oauthScopes) {
186209 this .oauthScopes = oauthScopes ;
187210 }
188211
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+
189226 /**
190227 * Checks the security realm for a GitHub OAuth scope.
191228 * @param scope A scope to check for in the security realm.
@@ -244,6 +281,20 @@ public void marshal(Object source, HierarchicalStreamWriter writer,
244281 writer .setValue (realm .getOauthScopes ());
245282 writer .endNode ();
246283
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+
247298 }
248299
249300 public Object unmarshal (HierarchicalStreamReader reader ,
@@ -270,6 +321,10 @@ public Object unmarshal(HierarchicalStreamReader reader,
270321 realm .setGithubApiUri (DEFAULT_API_URI );
271322 }
272323
324+ if (realm .getForceGithubEmail () == null ) {
325+ realm .setForceGithubEmail (DEFAULT_FORCE_GITHUB_EMAIL );
326+ }
327+
273328 return realm ;
274329 }
275330
@@ -289,6 +344,15 @@ private void setValue(GithubSecurityRealm realm, String node,
289344 realm .setGithubApiUri (value );
290345 } else if (node .toLowerCase ().equals ("oauthscopes" )) {
291346 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+ }
292356 } else {
293357 throw new ConversionException ("Invalid node value = " + node );
294358 }
@@ -333,6 +397,20 @@ public String getOauthScopes() {
333397 return oauthScopes ;
334398 }
335399
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+
336414 public HttpResponse doCommenceLogin (StaplerRequest request , @ Header ("Referer" ) final String referer )
337415 throws IOException {
338416 request .getSession ().setAttribute (REFERER_ATTRIBUTE ,referer );
@@ -383,17 +461,40 @@ public HttpResponse doFinishLogin(StaplerRequest request)
383461 GithubSecretStorage .put (u , accessToken );
384462
385463 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 ()) {
388466 if (hasScope ("user" ) || hasScope ("user:email" )) {
389467 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+ }
393485 }
394486 }
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+ }
397498 }
398499 } else {
399500 u .addProperty (new Mailer .UserProperty (auth .getGitHub ().getMyself ().getEmail ()));
@@ -600,6 +701,10 @@ public String getDefaultOauthScopes() {
600701 return DEFAULT_OAUTH_SCOPES ;
601702 }
602703
704+ public Boolean getDefaultForceGithubEmail () {
705+ return DEFAULT_FORCE_GITHUB_EMAIL ;
706+ }
707+
603708 public DescriptorImpl () {
604709 super ();
605710 // TODO Auto-generated constructor stub
@@ -700,7 +805,9 @@ public boolean equals(Object object){
700805 this .getGithubApiUri ().equals (obj .getGithubApiUri ()) &&
701806 this .getClientID ().equals (obj .getClientID ()) &&
702807 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 ());
704811 } else {
705812 return false ;
706813 }
0 commit comments