-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor user specific validation to user classes
- Loading branch information
1 parent
a187985
commit 7d20c49
Showing
6 changed files
with
107 additions
and
93 deletions.
There are no files selected for viewing
89 changes: 53 additions & 36 deletions
89
src/main/java/jetbrains/buildServer/auth/oauth/GithubUser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,63 @@ | ||
package jetbrains.buildServer.auth.oauth; | ||
|
||
import okhttp3.OkHttpClient; | ||
import okhttp3.Request; | ||
import org.json.simple.JSONValue; | ||
import com.intellij.openapi.util.text.StringUtil; | ||
import org.apache.log4j.Logger; | ||
import org.json.simple.JSONArray; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.JSONValue; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.io.IOException; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.function.Supplier; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class GithubUser extends OAuthUser { | ||
|
||
private static final String ORGANIZATION_ENDPOINT = "https://api.github.com/user/orgs"; | ||
private final Map<Boolean, OkHttpClient> httpClients = new HashMap<>(); | ||
private final String[] organizations; | ||
|
||
public GithubUser(Map userData, String token, Boolean allowInsecureHttps) throws IOException { | ||
super(userData); | ||
this.organizations = fetchUserOrganizations(token, allowInsecureHttps); | ||
} | ||
|
||
public String[] getOrganizations() { | ||
return organizations; | ||
} | ||
|
||
private String[] fetchUserOrganizations(String token, Boolean allowInsecureHttps) throws IOException { | ||
Request orgRequest = new Request.Builder() | ||
.url(ORGANIZATION_ENDPOINT) | ||
.addHeader("Authorization","Bearer " + token) | ||
.build(); | ||
String response = getHttpClient(allowInsecureHttps).newCall(orgRequest).execute().body().string(); | ||
JSONArray parsedResponse = (JSONArray) JSONValue.parse(response); | ||
String[] orgs = new String[parsedResponse.size()]; | ||
for(int i = 0; i < parsedResponse.size(); i++) { | ||
JSONObject value = (JSONObject) parsedResponse.get(i); | ||
orgs[i] = (String) value.get("login"); | ||
} | ||
return orgs; | ||
} | ||
|
||
private OkHttpClient getHttpClient(Boolean allowInsecureHttps) { | ||
return httpClients.computeIfAbsent(allowInsecureHttps, HttpClientFactory::createClient); | ||
} | ||
private static final Logger log = Logger.getLogger(GithubUser.class); | ||
public static final String ORGANIZATION_ENDPOINT = "https://api.github.com/user/orgs"; | ||
private final Supplier<String> organizationSupplier; | ||
|
||
public GithubUser(Map userData, Supplier<String> organizationSupplier) { | ||
super(userData); | ||
this.organizationSupplier = organizationSupplier; | ||
} | ||
|
||
private Set<String> fetchUserOrganizations() { | ||
String response = organizationSupplier.get(); | ||
log.debug("Fetched user org data: " + response); | ||
Object parsedResponse = JSONValue.parse(response); | ||
if (parsedResponse instanceof JSONArray) { | ||
return ((List<Object>) parsedResponse) | ||
.stream() | ||
.filter(item -> item instanceof JSONObject) | ||
.map(item -> ((JSONObject) item).get("login")) | ||
.filter(Objects::nonNull) | ||
.map(Object::toString) | ||
.collect(Collectors.toSet()); | ||
} else { | ||
String message = ((JSONObject) parsedResponse).getOrDefault("message", "Incorrect response:" + response ).toString(); | ||
throw new IllegalStateException(message); | ||
} | ||
} | ||
|
||
@Override | ||
public void validate(AuthenticationSchemeProperties properties) throws Exception { | ||
super.validate(properties); | ||
// Check the organizations that the user belongs to for Github Oauth | ||
String orgs = properties.getOrganizations(); | ||
if (StringUtil.isNotEmpty(orgs)) { | ||
Set<String> userOrganizations = this.fetchUserOrganizations(); | ||
Set<String> configuredOrganizations = Stream.of(orgs.split(",")) | ||
.map(String::trim) | ||
.collect(Collectors.toSet()); | ||
|
||
configuredOrganizations.retainAll(userOrganizations); | ||
if (configuredOrganizations.isEmpty()) { | ||
throw new Exception("User's organization does not match with the ones specified in the oAuth settings"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters