Skip to content

Commit 72bff0f

Browse files
authored
Merge pull request #40 from Yubico/versions
Read all version info from manifest
2 parents 4b40a5e + db7d6fb commit 72bff0f

File tree

11 files changed

+184
-15
lines changed

11 files changed

+184
-15
lines changed

build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ task assembleJavadoc(type: Sync) {
7474
destinationDir = file("${rootProject.buildDir}/javadoc")
7575
}
7676

77+
String getGitCommit() {
78+
def proc = "git rev-parse HEAD".execute(null, projectDir)
79+
proc.waitFor()
80+
if (proc.exitValue() != 0) {
81+
throw new RuntimeException("Failed to get git commit ID");
82+
}
83+
return proc.text.trim()
84+
}
85+
7786
subprojects { project ->
7887

7988
sourceCompatibility = 1.8

test-dependent-projects/java-dep-webauthn-server-attestation/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ plugins {
44

55
dependencies {
66
implementation(project(":webauthn-server-attestation"))
7+
testImplementation("junit:junit:4.12")
78
}
89

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.yubico.webauthn.attestation;
2+
3+
import java.io.IOException;
4+
import java.net.URL;
5+
import java.util.Enumeration;
6+
import java.util.NoSuchElementException;
7+
import java.util.jar.Manifest;
8+
import org.junit.Test;
9+
10+
import static org.junit.Assert.assertEquals;
11+
import static org.junit.Assert.assertTrue;
12+
13+
public class ManifestInfoTest {
14+
15+
private static String lookup(String key) throws IOException {
16+
final Enumeration<URL> resources = AttestationResolver.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
17+
18+
while (resources.hasMoreElements()) {
19+
final URL resource = resources.nextElement();
20+
final Manifest manifest = new Manifest(resource.openStream());
21+
if ("java-webauthn-server-attestation".equals(manifest.getMainAttributes().getValue("Implementation-Id"))) {
22+
return manifest.getMainAttributes().getValue(key);
23+
}
24+
}
25+
throw new NoSuchElementException("Could not find \"" + key + "\" in manifest.");
26+
}
27+
28+
@Test
29+
public void standardImplementationPropertiesAreSet() throws IOException {
30+
assertTrue(lookup("Implementation-Title").contains("attestation"));
31+
assertTrue(lookup("Implementation-Version").matches("^\\d+\\.\\d+\\.\\d+(-.*)?"));
32+
assertEquals("Yubico", lookup("Implementation-Vendor"));
33+
}
34+
35+
@Test
36+
public void customImplementationPropertiesAreSet() throws IOException {
37+
assertTrue(lookup("Git-Commit").matches("^[a-f0-9]{40}$"));
38+
}
39+
40+
}

test-dependent-projects/java-dep-webauthn-server-core/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ plugins {
44

55
dependencies {
66
implementation(project(":webauthn-server-core"))
7+
testImplementation("junit:junit:4.12")
78
}
89

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.yubico.webauthn.meta;
2+
3+
import com.yubico.webauthn.RelyingParty;
4+
import java.io.IOException;
5+
import java.net.URL;
6+
import java.time.LocalDate;
7+
import java.util.Enumeration;
8+
import java.util.NoSuchElementException;
9+
import java.util.jar.Manifest;
10+
import org.junit.Test;
11+
12+
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertTrue;
14+
15+
public class ManifestInfoTest {
16+
17+
private static String lookup(String key) throws IOException {
18+
final Enumeration<URL> resources = RelyingParty.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
19+
20+
while (resources.hasMoreElements()) {
21+
final URL resource = resources.nextElement();
22+
final Manifest manifest = new Manifest(resource.openStream());
23+
if ("java-webauthn-server".equals(manifest.getMainAttributes().getValue("Implementation-Id"))) {
24+
return manifest.getMainAttributes().getValue(key);
25+
}
26+
}
27+
throw new NoSuchElementException("Could not find \"" + key + "\" in manifest.");
28+
}
29+
30+
@Test
31+
public void standardSpecPropertiesAreSet() throws IOException {
32+
assertTrue(lookup("Specification-Title").startsWith("Web Authentication"));
33+
assertTrue(lookup("Specification-Version").startsWith("Level"));
34+
assertEquals("World Wide Web Consortium", lookup("Specification-Vendor"));
35+
}
36+
37+
38+
@Test
39+
public void customSpecPropertiesAreSet() throws IOException {
40+
assertTrue(lookup("Specification-Url").startsWith("https://"));
41+
assertTrue(lookup("Specification-Url-Latest").startsWith("https://"));
42+
assertTrue(DocumentStatus.fromString(lookup("Specification-W3c-Status")).isPresent());
43+
assertTrue(LocalDate.parse(lookup("Specification-Release-Date")).isAfter(LocalDate.of(2019, 3, 3)));
44+
}
45+
46+
@Test
47+
public void standardImplementationPropertiesAreSet() throws IOException {
48+
assertTrue(lookup("Implementation-Title").contains("Web Authentication"));
49+
assertTrue(lookup("Implementation-Version").matches("^\\d+\\.\\d+\\.\\d+(-.*)?"));
50+
assertEquals("Yubico", lookup("Implementation-Vendor"));
51+
}
52+
53+
@Test
54+
public void customImplementationPropertiesAreSet() throws IOException {
55+
assertTrue(lookup("Git-Commit").matches("^[a-f0-9]{40}$"));
56+
}
57+
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.yubico.webauthn.meta;
2+
3+
import java.time.LocalDate;
4+
import org.junit.Test;
5+
6+
import static org.junit.Assert.assertNotNull;
7+
import static org.junit.Assert.assertTrue;
8+
9+
/**
10+
* Since this depends on the manifest of the core jar, and the manifest is build by Gradle, this test is likely to fail
11+
* when run in an IDE. It works as expected when run via Gradle.
12+
*/
13+
public class VersionInfoTest {
14+
15+
final VersionInfo versionInfo = VersionInfo.getInstance();
16+
17+
@Test
18+
public void specPropertiesAreSet() {
19+
final Specification spec = versionInfo.getSpecification();
20+
assertTrue(spec.getLatestVersionUrl().toExternalForm().startsWith("https://"));
21+
assertTrue(spec.getUrl().toExternalForm().startsWith("https://"));
22+
assertTrue(spec.getReleaseDate().isAfter(LocalDate.of(2019, 3, 3)));
23+
assertNotNull(spec.getStatus());
24+
}
25+
26+
@Test
27+
public void implementationPropertiesAreSet() {
28+
final Implementation impl = versionInfo.getImplementation();
29+
assertTrue(impl.getSourceCodeUrl().toExternalForm().startsWith("https://"));
30+
assertTrue(impl.getVersion().matches("^\\d+\\.\\d+\\.\\d+(-.*)?"));
31+
assertTrue(impl.getGitCommit().matches("^[a-f0-9]{40}$"));
32+
}
33+
34+
@Test
35+
public void majorVersionIsAtLeast1() {
36+
final String version = versionInfo.getImplementation().getVersion();
37+
String[] splits = version.split("\\.");
38+
final int majorVersion = Integer.parseInt(splits[0]);
39+
assertTrue(majorVersion >= 1);
40+
}
41+
42+
}

webauthn-server-attestation/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jar {
4646
'Implementation-Title': project.description,
4747
'Implementation-Version': project.version,
4848
'Implementation-Vendor': 'Yubico',
49+
'Git-Commit': getGitCommit(),
4950
])
5051
}
5152
}

webauthn-server-core/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,18 @@ jar {
4444
'Specification-Title': 'Web Authentication: An API for accessing Public Key Credentials',
4545
'Specification-Version': 'Level 1 Recommendation 2019-03-04',
4646
'Specification-Vendor': 'World Wide Web Consortium',
47+
48+
'Specification-Url': 'https://www.w3.org/TR/2019/REC-webauthn-1-20190304/',
49+
'Specification-Url-Latest': 'https://www.w3.org/TR/webauthn/',
50+
'Specification-W3c-Status': 'recommendation',
51+
'Specification-Release-Date': '2019-03-04',
52+
4753
'Implementation-Id': 'java-webauthn-server',
4854
'Implementation-Title': 'Yubico Web Authentication server library',
4955
'Implementation-Version': project.version,
5056
'Implementation-Vendor': 'Yubico',
57+
'Implementation-Source-Url': 'https://github.com/Yubico/java-webauthn-server',
58+
'Git-Commit': getGitCommit(),
5159
])
5260
}
5361
}

webauthn-server-core/src/main/java/com/yubico/webauthn/meta/DocumentStatus.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
2828
import com.yubico.internal.util.json.JsonStringSerializable;
2929
import com.yubico.internal.util.json.JsonStringSerializer;
30+
import java.util.Optional;
31+
import java.util.stream.Stream;
3032
import lombok.AllArgsConstructor;
33+
import lombok.NonNull;
3134

3235
/**
3336
* A representation of Web Authentication specification document statuses.
@@ -62,6 +65,10 @@ public enum DocumentStatus implements JsonStringSerializable {
6265

6366
private final String id;
6467

68+
static Optional<DocumentStatus> fromString(@NonNull String id) {
69+
return Stream.of(values()).filter(v -> v.id.equals(id)).findAny();
70+
}
71+
6572
/**
6673
* Used by JSON serializer.
6774
*/

webauthn-server-core/src/main/java/com/yubico/webauthn/meta/Implementation.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public class Implementation {
4242
/**
4343
* The version number of this release of the library.
4444
*/
45+
@NonNull
4546
private final String version;
4647

4748
/**
@@ -50,8 +51,10 @@ public class Implementation {
5051
@NonNull
5152
private final URL sourceCodeUrl;
5253

53-
public Optional<String> getVersion() {
54-
return Optional.ofNullable(version);
55-
}
54+
/**
55+
* The commit ID of the source code the library was built from, if known.
56+
*/
57+
@NonNull
58+
private final String gitCommit;
5659

5760
}

0 commit comments

Comments
 (0)