use of io.hops.hopsworks.exceptions.HopsSecurityException in project hopsworks by logicalclocks.
the class JWTResource method renewServiceToken.
@PUT
@Path("/service")
@ApiOperation(value = "Renew a service JWT without invalidating the previous token", response = ServiceJWTDTO.class)
public Response renewServiceToken(JsonWebTokenDTO jwt, @Context HttpServletRequest request) throws HopsSecurityException {
// This token should be the one-time renewal token
String token = jWTHelper.getAuthToken(request);
Users user = jWTHelper.getUserPrincipal(request);
if (user == null) {
DecodedJWT decodedJWT = JWT.decode(token);
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.NOT_RENEWABLE_TOKEN, Level.FINE, "User not found associated with that JWT", "Could not find user in the database associated with JWT " + decodedJWT.getId());
}
try {
ServiceJWTDTO renewedTokens = jWTHelper.renewServiceToken(jwt, token, user, request.getRemoteHost());
return Response.ok().entity(renewedTokens).build();
} catch (JWTException | NoSuchAlgorithmException ex) {
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.NOT_RENEWABLE_TOKEN, Level.WARNING, "Could not renew service JWT", "Could not renew service JWT for " + request.getRemoteHost());
}
}
use of io.hops.hopsworks.exceptions.HopsSecurityException in project hopsworks by logicalclocks.
the class JWTResource method invalidateServiceToken.
@DELETE
@Path("/service/{token}")
@ApiOperation(value = "Invalidate a service JWT and also delete the signing key encoded in the token")
public Response invalidateServiceToken(@ApiParam(value = "Service token to invalidate", required = true) @PathParam("token") String token, @Context HttpServletRequest request) throws HopsSecurityException {
DecodedJWT jwt2invalidate = JWT.decode(token);
Users user = jWTHelper.getUserPrincipal(request);
if (user == null) {
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.INVALIDATION_ERROR, Level.FINE, "Could not find registered user", "Could not find registered user associated with JWT " + jwt2invalidate.getId());
}
if (!user.getUsername().equals(jwt2invalidate.getSubject())) {
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.INVALIDATION_ERROR, Level.FINE, "Tried to invalidate token with different subject", "User " + user.getUsername() + " tried to invalidate token with Subject " + jwt2invalidate.getSubject());
}
jWTHelper.invalidateServiceToken(token);
return Response.ok().build();
}
use of io.hops.hopsworks.exceptions.HopsSecurityException in project hopsworks by logicalclocks.
the class AuthService method serviceLogin.
@POST
@Path("/service")
@Produces(MediaType.APPLICATION_JSON)
@JWTNotRequired
public Response serviceLogin(@FormParam("email") String email, @FormParam("password") String password, @Context HttpServletRequest request) throws UserException, GeneralSecurityException, SigningKeyNotFoundException, DuplicateSigningKeyException, HopsSecurityException {
if (Strings.isNullOrEmpty(email)) {
throw new IllegalArgumentException("Email cannot be null or empty");
}
if (Strings.isNullOrEmpty(password)) {
throw new IllegalArgumentException("Password cannot be null or empty");
}
Users user = userFacade.findByEmail(email);
if (user == null) {
throw new LoginException("Could not find registered user with email " + email);
}
if (!needLogin(request, user)) {
return Response.ok().build();
}
if (!userController.isUserInRole(user, "AGENT")) {
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.REST_ACCESS_CONTROL, Level.FINE, "Users are not allowed to access this endpoint, use auth/login instead", "User " + user.getUsername() + " tried to login but they don't have AGENT role");
}
request.getSession();
Collection roles = user.getBbcGroupCollection();
if (roles == null || roles.isEmpty()) {
throw new UserException(RESTCodes.UserErrorCode.NO_ROLE_FOUND, Level.FINE);
}
statusValidator.checkStatus(user.getStatus());
String saltedPassword = authController.preCustomRealmLoginCheck(user, password, null);
try {
request.login(user.getEmail(), saltedPassword);
} catch (ServletException ex) {
authController.registerAuthenticationFailure(user);
throw new UserException(RESTCodes.UserErrorCode.AUTHENTICATION_FAILURE, Level.FINE, null, ex.getMessage(), ex);
}
// First generate the one-time tokens for renewal of master token
String renewalKeyName = jwtController.getServiceOneTimeJWTSigningKeyname(user.getUsername(), request.getRemoteHost());
LocalDateTime masterExpiration = DateUtils.getNow().plus(settings.getServiceJWTLifetimeMS(), ChronoUnit.MILLIS);
LocalDateTime notBefore = jwtController.computeNotBefore4ServiceRenewalTokens(masterExpiration);
LocalDateTime expiresAt = notBefore.plus(settings.getServiceJWTLifetimeMS(), ChronoUnit.MILLIS);
List<String> userRoles = userController.getUserRoles(user);
JsonWebToken renewalJWTSpec = new JsonWebToken();
renewalJWTSpec.setSubject(user.getUsername());
renewalJWTSpec.setIssuer(settings.getJWTIssuer());
renewalJWTSpec.setAudience(JWTHelper.SERVICE_RENEW_JWT_AUDIENCE);
renewalJWTSpec.setKeyId(renewalKeyName);
renewalJWTSpec.setNotBefore(DateUtils.localDateTime2Date(notBefore));
renewalJWTSpec.setExpiresAt(DateUtils.localDateTime2Date(expiresAt));
Map<String, Object> claims = new HashMap<>(4);
claims.put(Constants.RENEWABLE, false);
claims.put(Constants.EXPIRY_LEEWAY, 3600);
claims.put(Constants.ROLES, userRoles.toArray(new String[1]));
String[] oneTimeRenewalTokens = jwtController.generateOneTimeTokens4ServiceJWTRenewal(renewalJWTSpec, claims, settings.getJWTSigningKeyName());
// Then generate the master service token
try {
String signingKeyID = jwtController.getSignKeyID(oneTimeRenewalTokens[0]);
claims.clear();
// The rest of JWT claims will be added by JWTHelper
claims.put(Constants.RENEWABLE, false);
claims.put(Constants.SERVICE_JWT_RENEWAL_KEY_ID, signingKeyID);
String token = jWTHelper.createToken(user, settings.getJWTIssuer(), claims);
ServiceJWTDTO renewTokensResponse = new ServiceJWTDTO();
renewTokensResponse.setRenewTokens(oneTimeRenewalTokens);
return Response.ok().header(AUTHORIZATION, Constants.BEARER + token).entity(renewTokensResponse).build();
} catch (Exception ex) {
jwtController.deleteSigningKey(renewalKeyName);
throw ex;
}
}
use of io.hops.hopsworks.exceptions.HopsSecurityException in project hopsworks by logicalclocks.
the class VariablesService method getVar.
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@JWTRequired(acceptedTokens = { Audience.API }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
@ApiKeyRequired(acceptedScopes = { ApiScope.PROJECT }, allowedUserRoles = { "HOPS_ADMIN", "HOPS_USER" })
public Response getVar(@Context SecurityContext sc, @PathParam("id") String id) throws ServiceException, HopsSecurityException {
Variables variable = settings.findById(id).orElseThrow(() -> new ServiceException(RESTCodes.ServiceErrorCode.VARIABLE_NOT_FOUND, Level.FINE, "Variable: " + id + "not found"));
if (variable.getVisibility() == VariablesVisibility.ADMIN && !sc.isUserInRole("HOPS_ADMIN")) {
throw new HopsSecurityException(RESTCodes.SecurityErrorCode.REST_ACCESS_CONTROL, Level.FINE, "The requested variable requires admin privileges");
}
RESTApiJsonResponse json = new RESTApiJsonResponse();
json.setSuccessMessage(variable.getValue());
return Response.ok().entity(json).build();
}
use of io.hops.hopsworks.exceptions.HopsSecurityException in project hopsworks by logicalclocks.
the class CachedFeaturegroupController method getOfflineFeaturegroupPreview.
/**
* Previews the offline data of a given featuregroup by doing a SELECT LIMIT query on the Hive Table
*
* @param featuregroup the featuregroup to fetch
* @param project the project the user is operating from, in case of shared feature store
* @param user the user making the request
* @param limit number of sample to fetch
* @return list of feature-rows from the Hive table where the featuregroup is stored
* @throws SQLException
* @throws FeaturestoreException
* @throws HopsSecurityException
*/
public FeaturegroupPreview getOfflineFeaturegroupPreview(Featuregroup featuregroup, Project project, Users user, String partition, int limit) throws FeaturestoreException, HopsSecurityException, SQLException {
String tbl = getTblName(featuregroup.getName(), featuregroup.getVersion());
List<FeatureGroupFeatureDTO> features = getFeaturesDTO(featuregroup, project, user);
// This is not great, but at the same time the query runs as the user.
SqlNodeList selectList = new SqlNodeList(SqlParserPos.ZERO);
for (FeatureGroupFeatureDTO feature : features) {
if (feature.getDefaultValue() == null) {
selectList.add(new SqlIdentifier(Arrays.asList("`" + tbl + "`", "`" + feature.getName() + "`"), SqlParserPos.ZERO));
} else {
selectList.add(constructorController.selectWithDefaultAs(new Feature(feature, tbl)));
}
}
SqlNode whereClause = getWhereCondition(partition, features);
SqlSelect select = new SqlSelect(SqlParserPos.ZERO, null, selectList, new SqlIdentifier("`" + tbl + "`", SqlParserPos.ZERO), whereClause, null, null, null, null, null, SqlLiteral.createExactNumeric(String.valueOf(limit), SqlParserPos.ZERO), null);
String db = featurestoreController.getOfflineFeaturestoreDbName(featuregroup.getFeaturestore().getProject());
try {
return executeReadHiveQuery(select.toSqlString(new HiveSqlDialect(SqlDialect.EMPTY_CONTEXT)).getSql(), db, project, user);
} catch (Exception e) {
return executeReadHiveQuery(select.toSqlString(new HiveSqlDialect(SqlDialect.EMPTY_CONTEXT)).getSql(), db, project, user);
}
}
Aggregations