Skip to content

Commit 3b7a5c2

Browse files
committed
Use a single no-arg ctor for JAX-RS Providers (#833)
Resolves to #819
1 parent a4359bf commit 3b7a5c2

File tree

23 files changed

+466
-141
lines changed

23 files changed

+466
-141
lines changed

auth/basic/src/main/java/org/trellisldp/auth/basic/BasicAuthFilter.java

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,18 @@
3131
import java.util.stream.Stream;
3232

3333
import javax.annotation.Priority;
34-
import javax.inject.Inject;
3534
import javax.ws.rs.NotAuthorizedException;
3635
import javax.ws.rs.container.ContainerRequestContext;
3736
import javax.ws.rs.container.ContainerRequestFilter;
3837
import javax.ws.rs.core.SecurityContext;
38+
import javax.ws.rs.ext.Provider;
3939

4040
import org.eclipse.microprofile.config.Config;
4141

4242
/**
4343
* A basic authentication filter using an Authorization HTTP header.
4444
*/
45+
@Provider
4546
@Priority(AUTHENTICATION)
4647
public class BasicAuthFilter implements ContainerRequestFilter {
4748

@@ -57,30 +58,38 @@ public class BasicAuthFilter implements ContainerRequestFilter {
5758
/** The admin role. */
5859
public static final String ADMIN_ROLE = "admin";
5960

60-
private final File file;
61-
private final String challenge;
62-
private final Set<String> admins;
61+
private File file;
62+
private String challenge;
63+
private Set<String> admins;
6364

6465
/**
6566
* Create a basic auth filter.
6667
*/
67-
@Inject
6868
public BasicAuthFilter() {
69-
this(getConfig().getValue(CONFIG_AUTH_BASIC_CREDENTIALS, String.class));
69+
final Config config = getConfig();
70+
this.file = config.getOptionalValue(CONFIG_AUTH_BASIC_CREDENTIALS, String.class)
71+
.map(File::new).orElse(null);
72+
this.challenge = "Basic realm=\""
73+
+ config.getOptionalValue(CONFIG_AUTH_REALM, String.class).orElse("trellis") + "\"";
74+
this.admins = unmodifiableSet(getConfiguredAdmins(config));
7075
}
7176

7277
/**
7378
* Create a basic auth filter.
7479
* @param credentialsFile a credentials file
80+
* @deprecated this constructor is deprecated and will be removed in a future release
7581
*/
82+
@Deprecated
7683
public BasicAuthFilter(final String credentialsFile) {
7784
this(new File(credentialsFile));
7885
}
7986

8087
/**
8188
* Create a basic auth filter.
8289
* @param file the credentials file
90+
* @deprecated this constructor is deprecated and will be removed in a future release
8391
*/
92+
@Deprecated
8493
public BasicAuthFilter(final File file) {
8594
this(file, getConfig());
8695
}
@@ -95,13 +104,39 @@ private BasicAuthFilter(final File file, final Config config) {
95104
* @param file the credentials file
96105
* @param realm the authentication realm
97106
* @param admins the admin users
107+
* @deprecated this constructor is deprecated and will be removed in a future release
98108
*/
109+
@Deprecated
99110
public BasicAuthFilter(final File file, final String realm, final Set<String> admins) {
100111
this.file = file;
101112
this.challenge = "Basic realm=\"" + realm + "\"";
102113
this.admins = unmodifiableSet(requireNonNull(admins, "admins set may not be null!"));
103114
}
104115

116+
/**
117+
* Set the credentials file.
118+
* @param file the credentials file
119+
*/
120+
public void setFile(final File file) {
121+
this.file = requireNonNull(file, "Credentials file may not be null!");
122+
}
123+
124+
/**
125+
* Set the challenge response on auth failures.
126+
* @param challenge the challenge response
127+
*/
128+
public void setChallenge(final String challenge) {
129+
this.challenge = requireNonNull(challenge, "Challenge may not be null!");
130+
}
131+
132+
/**
133+
* Set the admin users.
134+
* @param admins the admin users
135+
*/
136+
public void setAdmins(final Set<String> admins) {
137+
this.admins = requireNonNull(admins, "Admin set may not be null!");
138+
}
139+
105140
@Override
106141
public void filter(final ContainerRequestContext requestContext) {
107142

@@ -118,7 +153,7 @@ public void filter(final ContainerRequestContext requestContext) {
118153

119154
private Principal authenticate(final String credentials) {
120155
final Credentials creds = Credentials.parse(credentials);
121-
if (creds != null && file.exists()) {
156+
if (creds != null && file != null && file.exists()) {
122157
final Path path = file.toPath();
123158
try (final Stream<String> lineStream = BasicAuthUtils.uncheckedLines(path)) {
124159
return lineStream.map(String::trim).filter(line -> !line.startsWith("#"))

auth/basic/src/test/java/org/trellisldp/auth/basic/BasicAuthFilterTest.java

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ void setUp() {
5555

5656
@Test
5757
void testCredentials() {
58-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
58+
final BasicAuthFilter filter = new BasicAuthFilter();
59+
filter.setFile(getAuthFile());
5960
final String webid = "https://people.apache.org/~acoburn/#i";
6061
final String token = encodeCredentials("acoburn", "secret");
6162
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("BASIC " + token);
@@ -71,7 +72,10 @@ void testCredentials() {
7172
@Test
7273
void testAdminCredentials() {
7374
final String webid = "https://people.apache.org/~acoburn/#i";
74-
final BasicAuthFilter filter = new BasicAuthFilter(new File(getAuthFile()), "trellis", singleton(webid));
75+
final BasicAuthFilter filter = new BasicAuthFilter();
76+
filter.setFile(getAuthFile());
77+
filter.setChallenge("Basic realm=\"trellis\"");
78+
filter.setAdmins(singleton(webid));
7579
final String token = encodeCredentials("acoburn", "secret");
7680
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("BASIC " + token);
7781
filter.filter(mockContext);
@@ -85,15 +89,17 @@ void testAdminCredentials() {
8589

8690
@Test
8791
void testNoHeader() {
88-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
92+
final BasicAuthFilter filter = new BasicAuthFilter();
93+
filter.setFile(getAuthFile());
8994
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn(null);
9095
filter.filter(mockContext);
9196
verify(mockContext, never()).setSecurityContext(securityArgument.capture());
9297
}
9398

9499
@Test
95100
void testOtherCredentials() {
96-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
101+
final BasicAuthFilter filter = new BasicAuthFilter();
102+
filter.setFile(getAuthFile());
97103
when(mockContext.getHeaderString(AUTHORIZATION))
98104
.thenReturn("Basic " + encodeCredentials("user", "password"));
99105
filter.filter(mockContext);
@@ -108,7 +114,8 @@ void testOtherCredentials() {
108114
@Test
109115
void testSecureCredentials() {
110116
when(mockSecurityContext.isSecure()).thenReturn(true);
111-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
117+
final BasicAuthFilter filter = new BasicAuthFilter();
118+
filter.setFile(getAuthFile());
112119
final String webid = "https://people.apache.org/~acoburn/#i";
113120
final String token = encodeCredentials("acoburn", "secret");
114121
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("BASIC " + token);
@@ -122,7 +129,8 @@ void testSecureCredentials() {
122129

123130
@Test
124131
void testNoSecurityContext() {
125-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
132+
final BasicAuthFilter filter = new BasicAuthFilter();
133+
filter.setFile(getAuthFile());
126134
when(mockContext.getSecurityContext()).thenReturn(null);
127135
when(mockContext.getHeaderString(AUTHORIZATION))
128136
.thenReturn("Basic " + encodeCredentials("user", "password"));
@@ -138,7 +146,7 @@ void testNoSecurityContext() {
138146
@Test
139147
void testCredentialsViaConfiguration() {
140148
try {
141-
System.setProperty(BasicAuthFilter.CONFIG_AUTH_BASIC_CREDENTIALS, getAuthFile());
149+
System.setProperty(BasicAuthFilter.CONFIG_AUTH_BASIC_CREDENTIALS, getAuthFile().getPath());
142150
final BasicAuthFilter filter = new BasicAuthFilter();
143151
when(mockContext.getHeaderString(AUTHORIZATION))
144152
.thenReturn("Basic " + encodeCredentials("user2", "password2"));
@@ -156,7 +164,8 @@ void testCredentialsViaConfiguration() {
156164

157165
@Test
158166
void testNoCredentials() {
159-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
167+
final BasicAuthFilter filter = new BasicAuthFilter();
168+
filter.setFile(getAuthFile());
160169
final String token = encodeCredentials("acoburn", "secret");
161170
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token);
162171
filter.filter(mockContext);
@@ -165,39 +174,44 @@ void testNoCredentials() {
165174

166175
@Test
167176
void testBadCredentials() {
168-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
177+
final BasicAuthFilter filter = new BasicAuthFilter();
178+
filter.setFile(getAuthFile());
169179
final String token = encodeCredentials("acoburn", "wrong");
170180
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token);
171181
assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext));
172182
}
173183

174184
@Test
175185
void testBadCredentialsFile() {
176-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile() + ".non-existent");
186+
final BasicAuthFilter filter = new BasicAuthFilter();
187+
filter.setFile(new File(getAuthFile().getPath() + ".non-existent"));
177188
final String token = encodeCredentials("acoburn", "secret");
178189
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token);
179190
assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext));
180191
}
181192

182193
@Test
183194
void testNoToken() {
184-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
195+
final BasicAuthFilter filter = new BasicAuthFilter();
196+
filter.setFile(getAuthFile());
185197
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("BASIC");
186198
filter.filter(mockContext);
187199
verify(mockContext, never()).setSecurityContext(any());
188200
}
189201

190202
@Test
191203
void testBadToken() {
192-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
204+
final BasicAuthFilter filter = new BasicAuthFilter();
205+
filter.setFile(getAuthFile());
193206
final String token = "blahblah";
194207
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token);
195208
assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext));
196209
}
197210

198211
@Test
199212
void testTokenWithBadChars() {
200-
final BasicAuthFilter filter = new BasicAuthFilter(getAuthFile());
213+
final BasicAuthFilter filter = new BasicAuthFilter();
214+
filter.setFile(getAuthFile());
201215
final String token = "&=!*#$";
202216
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token);
203217
assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext));
@@ -206,7 +220,8 @@ void testTokenWithBadChars() {
206220
@Test
207221
void testUnreadableFile() {
208222
final File file = new File(getAuthFile(), "nonexistent");
209-
final BasicAuthFilter filter = new BasicAuthFilter(file);
223+
final BasicAuthFilter filter = new BasicAuthFilter();
224+
filter.setFile(file);
210225
final String token = encodeCredentials("acoburn", "secret");
211226
when(mockContext.getHeaderString(AUTHORIZATION)).thenReturn("Basic " + token);
212227
assertThrows(NotAuthorizedException.class, () -> filter.filter(mockContext));
@@ -224,8 +239,8 @@ private String encodeCredentials(final String username, final String password) {
224239
return new String(Base64.getEncoder().encode(combined.getBytes(UTF_8)), UTF_8);
225240
}
226241

227-
private String getAuthFile() {
242+
private File getAuthFile() {
228243
final String prefix = "file:";
229-
return getClass().getResource("/users.auth").toString().substring(prefix.length());
244+
return new File(getClass().getResource("/users.auth").toString().substring(prefix.length()));
230245
}
231246
}

auth/oauth/src/main/java/org/trellisldp/auth/oauth/OAuthFilter.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.Set;
3333

3434
import javax.annotation.Priority;
35-
import javax.inject.Inject;
3635
import javax.ws.rs.NotAuthorizedException;
3736
import javax.ws.rs.container.ContainerRequestContext;
3837
import javax.ws.rs.container.ContainerRequestFilter;
@@ -71,22 +70,27 @@ public class OAuthFilter implements ContainerRequestFilter {
7170

7271
private static final Logger LOGGER = getLogger(OAuthFilter.class);
7372

74-
private final Authenticator authenticator;
75-
private final String challenge;
76-
private final Set<String> admins;
73+
private Authenticator authenticator;
74+
private String challenge;
75+
private Set<String> admins;
7776

7877
/**
7978
* Create an OAuth filter.
8079
*/
81-
@Inject
8280
public OAuthFilter() {
83-
this(buildAuthenticator());
81+
final Config config = getConfig();
82+
this.authenticator = buildAuthenticator();
83+
this.challenge = "Bearer realm=\"" +
84+
config.getOptionalValue(CONFIG_AUTH_REALM, String.class).orElse("trellis") + "\"";
85+
this.admins = unmodifiableSet(getConfiguredAdmins(config));
8486
}
8587

8688
/**
8789
* Create an OAuth filter with a defined authenticator.
8890
* @param authenticator the authenticator
91+
* @deprecated this constructor is deprecated and will be removed in a future release
8992
*/
93+
@Deprecated
9094
public OAuthFilter(final Authenticator authenticator) {
9195
this(authenticator, getConfig());
9296
}
@@ -101,13 +105,39 @@ private OAuthFilter(final Authenticator authenticator, final Config config) {
101105
* @param authenticator the authenticator
102106
* @param realm the authentication realm
103107
* @param admins the admin users
108+
* @deprecated this constructor is deprecated and will be removed in a future release
104109
*/
110+
@Deprecated
105111
public OAuthFilter(final Authenticator authenticator, final String realm, final Set<String> admins) {
106112
this.authenticator = authenticator;
107113
this.challenge = "Bearer realm=\"" + realm + "\"";
108114
this.admins = unmodifiableSet(requireNonNull(admins, "Admin set may not be null!"));
109115
}
110116

117+
/**
118+
* Set the authenticator to use.
119+
* @param authenticator the authenticator in use
120+
*/
121+
public void setAuthenticator(final Authenticator authenticator) {
122+
this.authenticator = authenticator;
123+
}
124+
125+
/**
126+
* Set the challenge text.
127+
* @param challenge the challenge text
128+
*/
129+
public void setChallenge(final String challenge) {
130+
this.challenge = challenge;
131+
}
132+
133+
/**
134+
* Set the admin users.
135+
* @param admins the admin users
136+
*/
137+
public void setAdmins(final Set<String> admins) {
138+
this.admins = requireNonNull(admins, "Admin set may not be null!");
139+
}
140+
111141
@Override
112142
public void filter(final ContainerRequestContext requestContext) {
113143

0 commit comments

Comments
 (0)