Skip to content

Commit 1fc3e05

Browse files
Merge pull request #14 from larscheid-schmitzhermes/fix/correct-teams-api
call new teams api
2 parents 249c89f + 219a53a commit 1fc3e05

8 files changed

Lines changed: 54 additions & 87 deletions

File tree

Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM sonatype/nexus3:3.3.2
2+
USER root
3+
RUN mkdir -p /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin/1.1.0/
4+
COPY target/nexus3-github-oauth-plugin-1.1.0.jar /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin/1.1.0/
5+
COPY target/feature/feature.xml /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin/1.1.0/nexus3-github-oauth-plugin-1.1.0-features.xml
6+
COPY pom.xml /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin/1.1.0/nexus3-github-oauth-plugin-1.1.0.pom
7+
RUN echo '<?xml version="1.0" encoding="UTF-8"?><metadata><groupId>com.larscheidschmitzhermes</groupId><artifactId>nexus3-github-oauth-plugin</artifactId><versioning><release>1.1.0</release><versions><version>1.1.0</version></versions><lastUpdated>20170630132608</lastUpdated></versioning></metadata>' > /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin/maven-metadata-local.xml
8+
RUN echo "mvn\:com.larscheidschmitzhermes/nexus3-github-oauth-plugin/1.1.0 = 200" >> /opt/sonatype/nexus/etc/karaf/startup.properties

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ The following lines will:
4949
- add the plugin to the `karaf` `startup.properties`.
5050
```shell
5151
mkdir -p /opt/sonatype/nexus/system/com/larscheidschmitzhermes/ &&\
52-
wget -O /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin.zip https://github.com/larscheid-schmitzhermes/nexus3-github-oauth-plugin/releases/download/1.0.0/nexus3-github-oauth-plugin.zip &&\
52+
wget -O /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin.zip https://github.com/larscheid-schmitzhermes/nexus3-github-oauth-plugin/releases/download/1.1.0/nexus3-github-oauth-plugin.zip &&\
5353
unzip /opt/sonatype/nexus/system/com/larscheidschmitzhermes/nexus3-github-oauth-plugin.zip -d /opt/sonatype/nexus/system/com/larscheidschmitzhermes/ &&\
5454
echo "mvn\:com.larscheidschmitzhermes/nexus3-github-oauth-plugin/1.0.0 = 200" >> /opt/sonatype/nexus/etc/karaf/startup.properties
5555
```
@@ -73,6 +73,12 @@ github.principal.cache.ttl=PT1M
7373
#### 3. Restart Nexus
7474
Restart your Nexus instance to let it pick up your changes.
7575

76+
## Development
77+
78+
You can build the project with the integrated maven wrapper like so: `./mvnw clean package`
79+
80+
Use the [`Dockerfile`](Dockerfile) to quickly spin up a nexus with the plugin already preinstalled.
81+
7682
## Credits
7783

7884
The whole project is heavily influenced by the [nexus3-crowd-plugin](https://github.com/pingunaut/nexus3-crowd-plugin).

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
<groupId>com.larscheidschmitzhermes</groupId>
2222
<artifactId>nexus3-github-oauth-plugin</artifactId>
23-
<version>1.0.0</version>
23+
<version>1.1.0</version>
2424

2525
<name>${project.groupId}:${project.artifactId}</name>
2626
<packaging>bundle</packaging>

src/main/java/com/larscheidschmitzhermes/nexus3/github/oauth/plugin/api/GithubApiClient.java

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
import java.io.IOException;
44
import java.io.InputStreamReader;
5-
import java.net.URI;
6-
import java.net.URISyntaxException;
7-
import java.util.Collections;
8-
import java.util.HashSet;
95
import java.util.Set;
106
import java.util.concurrent.TimeUnit;
117
import java.util.stream.Collectors;
@@ -124,51 +120,24 @@ private GithubUser retrieveGithubUser(String loginName, char[] token) throws Git
124120
}
125121

126122
private Set<String> generateRolesFromGithubOrgMemberships(char[] token) throws GithubAuthenticationException{
127-
HttpGet orgsRequest = new HttpGet(configuration.getGithubOrgsUri());
128-
orgsRequest.addHeader(constructGithubAuthorizationHeader(token));
129-
HttpResponse orgsResponse;
123+
HttpGet teamsRequest = new HttpGet(configuration.getGithubUserTeamsUri());
124+
teamsRequest.addHeader(constructGithubAuthorizationHeader(token));
125+
HttpResponse teamsResponse;
130126

131-
Set<GithubOrg> orgs;
127+
Set<GithubTeam> teams;
132128
try {
133-
orgsResponse = client.execute(orgsRequest);
134-
orgs = mapper.readValue(new InputStreamReader(orgsResponse.getEntity().getContent()), new TypeReference<Set<GithubOrg>>() {
135-
});
129+
teamsResponse = client.execute(teamsRequest);
130+
teams = mapper.readValue(new InputStreamReader(teamsResponse.getEntity().getContent()), new TypeReference<Set<GithubTeam>>() {});
136131
} catch (IOException e) {
137-
orgsRequest.releaseConnection();
132+
teamsRequest.releaseConnection();
138133
throw new GithubAuthenticationException(e);
139134
}
140135

141-
Set<String> roles = new HashSet<>();
142-
143-
for (GithubOrg org : orgs) {
144-
roles.addAll(retrieveTeamMembershipsInOrg(org, token).stream().map(team -> mapGithubTeamToNexusRole(org, team)).collect(Collectors.toList()));
145-
}
146-
147-
return roles;
148-
}
149-
150-
private Set<GithubTeam> retrieveTeamMembershipsInOrg(GithubOrg org, char[] token) {
151-
HttpGet teamsRequest;
152-
try {
153-
teamsRequest = new HttpGet(new URI(org.getUrl() + configuration.getGithubTeamsInOrgPath()));
154-
} catch (URISyntaxException e) {
155-
LOGGER.warn("error creating uri" ,e);
156-
return Collections.emptySet();
157-
}
158-
teamsRequest.addHeader(constructGithubAuthorizationHeader(token));
159-
try {
160-
HttpResponse teamsResponse = client.execute(teamsRequest);
161-
return mapper.readValue(new InputStreamReader(teamsResponse.getEntity().getContent()), new TypeReference<Set<GithubTeam>>() {
162-
});
163-
} catch (IOException e) {
164-
teamsRequest.releaseConnection();
165-
LOGGER.warn("Failed to get teams in " + org.getUrl(),e);
166-
return Collections.emptySet();
167-
}
136+
return teams.stream().map(this::mapGithubTeamToNexusRole).collect(Collectors.toSet());
168137
}
169138

170-
private String mapGithubTeamToNexusRole(GithubOrg org, GithubTeam team) {
171-
return org.getLogin() + "/" + team.getName();
139+
private String mapGithubTeamToNexusRole(GithubTeam team) {
140+
return team.getOrganization().getLogin() + "/" + team.getName();
172141
}
173142

174143
private BasicHeader constructGithubAuthorizationHeader(char[] token) {

src/main/java/com/larscheidschmitzhermes/nexus3/github/oauth/plugin/api/GithubOrg.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
@JsonIgnoreProperties(ignoreUnknown = true)
66
public class GithubOrg {
77
private String login;
8-
private String url;
98

109
public String getLogin() {
1110
return login;
@@ -14,12 +13,4 @@ public String getLogin() {
1413
public void setLogin(String login) {
1514
this.login = login;
1615
}
17-
18-
public String getUrl() {
19-
return url;
20-
}
21-
22-
public void setUrl(String url) {
23-
this.url = url;
24-
}
2516
}

src/main/java/com/larscheidschmitzhermes/nexus3/github/oauth/plugin/api/GithubTeam.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@
66
public class GithubTeam {
77
private String name;
88

9+
private GithubOrg organization;
10+
911
public String getName() {
1012
return name;
1113
}
1214

1315
public void setName(String name) {
1416
this.name = name;
1517
}
18+
19+
public GithubOrg getOrganization() {
20+
return organization;
21+
}
22+
23+
public void setOrganization(GithubOrg organization) {
24+
this.organization = organization;
25+
}
1626
}

src/main/java/com/larscheidschmitzhermes/nexus3/github/oauth/plugin/configuration/GithubOauthConfiguration.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ public class GithubOauthConfiguration {
2121

2222
private static final String GITHUB_USER_PATH = "/user";
2323

24-
private static final String GITHUB_ORGS_PATH = "/user/orgs";
25-
26-
private static final String GITHUB_TEAMS_IN_ORG_PATH = "/teams";
24+
private static final String GITHUB_USER_TEAMS_PATH = "/user/teams";
2725

2826
private static final Duration DEFAULT_PRINCIPAL_CACHE_TTL = Duration.ofMinutes(1);
2927

@@ -52,18 +50,12 @@ public String getGithubApiUrl() {
5250
return configuration.getProperty(GITHUB_API_URL_KEY, DEFAULT_GITHUB_URL);
5351
}
5452

55-
public String getGithubTeamsInOrgPath() {
56-
return GITHUB_TEAMS_IN_ORG_PATH;
57-
}
58-
59-
public String getGithubOrgsUri() {
60-
return getGithubApiUrl() + GITHUB_ORGS_PATH;
61-
}
62-
6353
public String getGithubUserUri() {
6454
return getGithubApiUrl() + GITHUB_USER_PATH;
6555
}
6656

57+
public String getGithubUserTeamsUri() { return getGithubApiUrl() + GITHUB_USER_TEAMS_PATH; }
58+
6759
public Duration getPrincipalCacheTtl() {
6860
return Duration.parse(configuration.getProperty(GITHUB_PRINCIPAL_CACHE_TTL_KEY, DEFAULT_PRINCIPAL_CACHE_TTL.toString()));
6961
}

src/test/java/com/larscheidschmitzhermes/nexus3/github/oauth/plugin/GithubApiClientTest.java

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.ArrayList;
88
import java.util.List;
99

10-
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.configuration.GithubOauthConfiguration;
1110
import org.apache.http.HttpResponse;
1211
import org.apache.http.client.HttpClient;
1312
import org.apache.http.client.methods.HttpGet;
@@ -23,27 +22,25 @@
2322
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.api.GithubOrg;
2423
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.api.GithubTeam;
2524
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.api.GithubUser;
25+
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.configuration.GithubOauthConfiguration;
2626
import com.larscheidschmitzhermes.nexus3.github.oauth.plugin.configuration.MockGithubOauthConfiguration;
2727

2828
@RunWith(MockitoJUnitRunner.class)
2929
public class GithubApiClientTest {
3030
private MockGithubOauthConfiguration config = new MockGithubOauthConfiguration(Duration.ofDays(1));
3131
private ObjectMapper mapper = new ObjectMapper();
3232

33-
private List<GithubOrg> mockOrgs(){
34-
List<GithubOrg> orgs = new ArrayList<>();
33+
private List<GithubTeam> mockTeams(){
3534
GithubOrg org = new GithubOrg();
3635
org.setLogin("TEST-ORG");
37-
org.setUrl("www.example.com/test-org");
38-
orgs.add(org);
39-
return orgs;
40-
}
4136

42-
private List<GithubTeam> mockTeams(){
4337
List<GithubTeam> teams = new ArrayList<>();
38+
4439
GithubTeam team = new GithubTeam();
40+
team.setOrganization(org);
4541
team.setName("admin");
4642
teams.add(team);
43+
4744
return teams;
4845
}
4946

@@ -70,17 +67,14 @@ private HttpClient fullyFunctionalMockClient() throws IOException{
7067
return mockClient;
7168
}
7269
private void mockResponsesForGithubAuthRequest(HttpClient mockClient) throws IOException {
73-
HttpResponse mockOrgRespone = createMockResponse(mockOrgs());
7470
HttpResponse mockTeamResponse = createMockResponse(mockTeams());
7571
HttpResponse mockUserResponse = createMockResponse(mockUser("Hans Wurst"));
7672

7773
Mockito.when(mockClient.execute(Mockito.any())).thenAnswer(invocationOnMock -> {
7874
String uriString = ((HttpGet) invocationOnMock.getArguments()[0]).getURI().toString();
79-
if (uriString.equals(config.getGithubOrgsUri().toString())){
80-
return mockOrgRespone;
81-
}else if(uriString.matches(".*/teams.*")){
75+
if (uriString.equals(config.getGithubUserTeamsUri())) {
8276
return mockTeamResponse;
83-
}else if(uriString.equals(config.getGithubUserUri().toString())){
77+
} else if (uriString.equals(config.getGithubUserUri().toString())) {
8478
return mockUserResponse;
8579
}
8680
return null;
@@ -89,17 +83,14 @@ private void mockResponsesForGithubAuthRequest(HttpClient mockClient) throws IOE
8983

9084
private HttpClient mockClientWithNullUsername()throws IOException{
9185
HttpClient mockClient = Mockito.mock(HttpClient.class);
92-
HttpResponse mockOrgRespone = createMockResponse(mockOrgs());
9386
HttpResponse mockTeamResponse = createMockResponse(mockTeams());
9487
HttpResponse mockUserResponse = createMockResponse(mockUser(null));
9588

9689
Mockito.when(mockClient.execute(Mockito.any())).thenAnswer(invocationOnMock -> {
9790
String uriString = ((HttpGet) invocationOnMock.getArguments()[0]).getURI().toString();
98-
if (uriString.equals(config.getGithubOrgsUri().toString())){
99-
return mockOrgRespone;
100-
}else if(uriString.matches(".*/teams.*")){
91+
if (uriString.equals(config.getGithubUserTeamsUri())) {
10192
return mockTeamResponse;
102-
}else if(uriString.equals(config.getGithubUserUri().toString())){
93+
} else if (uriString.equals(config.getGithubUserUri().toString())){
10394
return mockUserResponse;
10495
}
10596
return null;
@@ -161,8 +152,8 @@ public void cachedPrincipalReturnsIfNotExpired() throws Exception {
161152
char[] token = "DUMMY".toCharArray();
162153
clientToTest.authz(login, token);
163154

164-
// We make 3 calls to Github for a single auth check
165-
Mockito.verify(mockClient, Mockito.times(3)).execute(Mockito.any(HttpGet.class));
155+
// We make 2 calls to Github for a single auth check
156+
Mockito.verify(mockClient, Mockito.times(2)).execute(Mockito.any(HttpGet.class));
166157
Mockito.verifyNoMoreInteractions(mockClient);
167158

168159
// This invocation should hit the cache and should not use the client
@@ -179,8 +170,8 @@ public void principalCacheHonorsTtl() throws Exception {
179170
char[] token = "DUMMY".toCharArray();
180171

181172
clientToTest.authz("demo-user", token);
182-
// We make 3 calls to Github for a single auth check
183-
Mockito.verify(mockClient, Mockito.times(3)).execute(Mockito.any(HttpGet.class));
173+
// We make 2 calls to Github for a single auth check
174+
Mockito.verify(mockClient, Mockito.times(2)).execute(Mockito.any(HttpGet.class));
184175
Mockito.verifyNoMoreInteractions(mockClient);
185176

186177
// Wait a bit for the cache to become invalidated
@@ -191,8 +182,8 @@ public void principalCacheHonorsTtl() throws Exception {
191182
mockResponsesForGithubAuthRequest(mockClient);
192183
// This should also hit Github because the cache TTL has elapsed
193184
clientToTest.authz("demo-user", token);
194-
// We make 3 calls to Github for a single auth check
195-
Mockito.verify(mockClient, Mockito.times(3)).execute(Mockito.any(HttpGet.class));
185+
// We make 2 calls to Github for a single auth check
186+
Mockito.verify(mockClient, Mockito.times(2)).execute(Mockito.any(HttpGet.class));
196187
Mockito.verifyNoMoreInteractions(mockClient);
197188
}
198189

0 commit comments

Comments
 (0)