Skip to content

Commit f296e0e

Browse files
authored
feat: Allow no expiration team access token (#1665)
* feat: Allow no expiration team access token
1 parent 072ae49 commit f296e0e

File tree

3 files changed

+97
-23
lines changed

3 files changed

+97
-23
lines changed

api/src/main/java/org/terrakube/api/plugin/token/team/TeamTokenService.java

+35-18
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,41 @@ public String createToken(int days, int hours, int minutes, String description,
5757
JSONArray groupArray = new JSONArray();
5858
groupArray.add(groupName);
5959

60-
Date expiration = Date.from(Instant.now().plus(days, ChronoUnit.DAYS).plus(hours, ChronoUnit.HOURS).plus(minutes, ChronoUnit.MINUTES));
61-
62-
log.info("Team token will expire: {}", expiration);
63-
64-
jws = Jwts.builder()
65-
.setIssuer(ISSUER)
66-
.setSubject(String.format("%s (Team Token)", groupName))
67-
.setAudience(ISSUER)
68-
.setId(groupToken.getId().toString())
69-
.claim("email", ownerEmail)
70-
.claim("description", description)
71-
.claim("email_verified", true)
72-
.claim("name", String.format("%s (Token)", groupName))
73-
.claim("groups", groupArray)
74-
.setIssuedAt(Date.from(Instant.now()))
75-
.setExpiration(expiration)
76-
.signWith(key)
77-
.compact();
60+
if (days > 0 || hours > 0 || minutes > 0 ) {
61+
Date expiration = Date.from(Instant.now().plus(days, ChronoUnit.DAYS).plus(hours, ChronoUnit.HOURS).plus(minutes, ChronoUnit.MINUTES));
62+
log.info("Team token will expire: {}", expiration);
63+
64+
jws = Jwts.builder()
65+
.setIssuer(ISSUER)
66+
.setSubject(String.format("%s (Team Token)", groupName))
67+
.setAudience(ISSUER)
68+
.setId(groupToken.getId().toString())
69+
.claim("email", ownerEmail)
70+
.claim("description", description)
71+
.claim("email_verified", true)
72+
.claim("name", String.format("%s (Token)", groupName))
73+
.claim("groups", groupArray)
74+
.setIssuedAt(Date.from(Instant.now()))
75+
.setExpiration(expiration)
76+
.signWith(key)
77+
.compact();
78+
} else {
79+
log.info("Team token will not expire:");
80+
81+
jws = Jwts.builder()
82+
.setIssuer(ISSUER)
83+
.setSubject(String.format("%s (Team Token)", groupName))
84+
.setAudience(ISSUER)
85+
.setId(groupToken.getId().toString())
86+
.claim("email", ownerEmail)
87+
.claim("description", description)
88+
.claim("email_verified", true)
89+
.claim("name", String.format("%s (Token)", groupName))
90+
.claim("groups", groupArray)
91+
.setIssuedAt(Date.from(Instant.now()))
92+
.signWith(key)
93+
.compact();
94+
}
7895

7996
} catch (Exception e) {
8097
log.error("Error generating token.", e);

api/src/test/java/org/terrakube/api/TokenTests.java

+58-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import java.util.Map;
1212

1313
import static io.restassured.RestAssured.given;
14-
import static org.hamcrest.core.IsEqual.equalTo;
1514

1615
class TokenTests extends ServerApplicationTests {
1716

@@ -74,4 +73,62 @@ void createTokenNoExpiration() throws JsonProcessingException {
7473

7574
}
7675

76+
@Test
77+
void createTeamToken() throws JsonProcessingException {
78+
String token = given()
79+
.headers("Authorization", "Bearer " + generatePAT("TERRAKUBE_DEVELOPERS"))
80+
.headers("Content-Type", "application/vnd.api+json")
81+
.when()
82+
.body("{\"description\":\"12345\",\"days\":1,\"minutes\":1,\"hours\":1,\"group\":\"TERRAKUBE_DEVELOPERS\"}")
83+
.post("/access-token/v1/teams")
84+
.then()
85+
.assertThat()
86+
.log()
87+
.all()
88+
.statusCode(HttpStatus.CREATED.value()).extract().path("token");
89+
90+
String[] chunks = token.split("\\.");
91+
Base64.Decoder decoder = Base64.getDecoder();
92+
String payload = new String(decoder.decode(chunks[1]));
93+
Map<String, Object> result = new ObjectMapper().readValue(payload, HashMap.class);
94+
Assert.assertNotNull(result.get("exp"));
95+
96+
given()
97+
.headers("Authorization", "Bearer " + token).when()
98+
.get("/api/v1/organization/d9b58bd3-f3fc-4056-a026-1163297e80a8")
99+
.then()
100+
.log()
101+
.all()
102+
.statusCode(HttpStatus.OK.value());
103+
}
104+
105+
@Test
106+
void createTeamTokenNoExpiration() throws JsonProcessingException {
107+
String token = given()
108+
.headers("Authorization", "Bearer " + generatePAT("TERRAKUBE_DEVELOPERS"))
109+
.headers("Content-Type", "application/vnd.api+json")
110+
.when()
111+
.body("{\"description\":\"12345\",\"days\":0,\"minutes\":0,\"hours\":0,\"group\":\"TERRAKUBE_DEVELOPERS\"}")
112+
.post("/access-token/v1/teams")
113+
.then()
114+
.assertThat()
115+
.log()
116+
.all()
117+
.statusCode(HttpStatus.CREATED.value()).extract().path("token");
118+
119+
String[] chunks = token.split("\\.");
120+
Base64.Decoder decoder = Base64.getDecoder();
121+
String payload = new String(decoder.decode(chunks[1]));
122+
Map<String, Object> result = new ObjectMapper().readValue(payload, HashMap.class);
123+
Assert.assertNull(result.get("exp"));
124+
125+
given()
126+
.headers("Authorization", "Bearer " + token).when()
127+
.get("/api/v1/organization/d9b58bd3-f3fc-4056-a026-1163297e80a8")
128+
.then()
129+
.log()
130+
.all()
131+
.statusCode(HttpStatus.OK.value());
132+
}
133+
77134
}

ui/src/domain/Settings/EditTeam.jsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,10 @@ export const EditTeam = ({ mode, setMode, teamId, loadTeams }) => {
442442
>
443443
{" "}
444444
<b>
445-
Expires{" "}
446-
{DateTime.fromISO(item.createdDate)
447-
.plus({ days: item.days })
448-
.toLocaleString(DateTime.DATETIME_MED)}
445+
Expires{": "}
446+
{(item.days > 0 || item.minutes > 0 || item.hours > 0) ? DateTime.fromISO(item.createdDate)
447+
.plus({ days: item.days, minutes: item.minutes, hours: item.hours })
448+
.toLocaleString(DateTime.DATETIME_MED) : "Token without expiration date"}
449449
</b>
450450
</Tag>
451451
</Col>

0 commit comments

Comments
 (0)