package restx.admin;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.Hashing;
import java.io.IOException;
import java.util.Collections;
import java.util.regex.Pattern;
import restx.RestxContext;
import restx.RestxFilter;
import restx.RestxHandler;
import restx.RestxHandlerMatch;
import restx.RestxRequest;
import restx.RestxRequestMatch;
import restx.RestxResponse;
import restx.StdRestxRequestMatch;
import restx.WebException;
import restx.factory.Module;
import restx.factory.Provides;
import restx.http.HttpStatus;
import restx.security.*;
import javax.inject.Named;
@Module(priority = 10000)
public class AdminModule {
public static final String RESTX_ADMIN_ROLE = "restx-admin";
public static final RestxAdminPrincipal RESTX_ADMIN_PRINCIPAL = new RestxAdminPrincipal();
@Provides
@Named("restx.admin.password")
public String restxAdminPassword() {
return "juma";
}
@Provides
@Named("restx.admin.passwordHash")
public String restxAdminPasswordHash(@Named("restx.admin.password") String password) {
return Hashing.md5().hashString(password, Charsets.UTF_8).toString();
}
@Provides
public BasicPrincipalAuthenticator basicPrincipalAuthenticator(
@Named("restx.admin.passwordHash") final String adminPasswordHash, SecuritySettings securitySettings) {
return new StdBasicPrincipalAuthenticator(new UserService<RestxAdminPrincipal>() {
@Override
public Optional<RestxAdminPrincipal> findUserByName(String name) {
return "admin".equals(name) ? Optional.of(RESTX_ADMIN_PRINCIPAL) : Optional.<RestxAdminPrincipal>absent();
}
@Override
public Optional<RestxAdminPrincipal> findAndCheckCredentials(String name, String passwordHash) {
return "admin".equals(name) && adminPasswordHash.equals(passwordHash) ?
Optional.of(RESTX_ADMIN_PRINCIPAL) : Optional.<RestxAdminPrincipal>absent();
}
}, securitySettings);
}
public static class RestxAdminPrincipal implements RestxPrincipal {
@Override
public ImmutableSet<String> getPrincipalRoles() {
return ImmutableSet.of(RESTX_ADMIN_ROLE);
}
@Override
public String getName() {
return "admin";
}
}
@Provides
public RestxFilter adminRoleFilter(final PermissionFactory permissionFactory) {
return new RestxFilter() {
final Pattern privatePath = Pattern.compile("^/@/(?!(ui|webjars)/).*$");
@Override
public Optional<RestxHandlerMatch> match(RestxRequest req) {
if (privatePath.matcher(req.getRestxPath()).find()) {
return Optional.of(new RestxHandlerMatch(
new StdRestxRequestMatch("/@/*", req.getRestxPath()),
new RestxHandler() {
@Override
public void handle(RestxRequestMatch match, RestxRequest req, RestxResponse resp, RestxContext ctx) throws IOException {
final RestxSession current = RestxSession.current();
if (current.getPrincipal().isPresent() &&
permissionFactory.hasRole(RESTX_ADMIN_ROLE).has(current.getPrincipal().get(), Collections.<String, String>emptyMap()).isPresent()) {
ctx.nextHandlerMatch().handle(req, resp, ctx);
} else {
throw new WebException(HttpStatus.UNAUTHORIZED);
}
}
}
));
}
return Optional.absent();
}
};
}
}