Search in sources :

Example 1 with MaterializedJWTID

use of io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID in project hopsworks by logicalclocks.

the class AirflowManager method prepareSecurityMaterial.

@Lock(LockType.READ)
@AccessTimeout(value = 1, unit = TimeUnit.SECONDS)
public void prepareSecurityMaterial(Users user, Project project, String[] audience) throws AirflowException {
    isInitialized();
    MaterializedJWTID materialID = new MaterializedJWTID(project.getId(), user.getUid(), MaterializedJWTID.USAGE.AIRFLOW);
    if (!materializedJWTFacade.exists(materialID)) {
        LocalDateTime expirationDate = DateUtils.getNow().plus(settings.getJWTLifetimeMs(), ChronoUnit.MILLIS);
        AirflowJWT airflowJWT = new AirflowJWT(user.getUsername(), project.getId(), project.getName(), expirationDate, user.getUid());
        try {
            String[] roles = getUserRoles(user);
            MaterializedJWT airflowMaterial = new MaterializedJWT(new MaterializedJWTID(project.getId(), user.getUid(), MaterializedJWTID.USAGE.AIRFLOW));
            materializedJWTFacade.persist(airflowMaterial);
            Map<String, Object> claims = new HashMap<>(3);
            claims.put(Constants.RENEWABLE, false);
            claims.put(Constants.EXPIRY_LEEWAY, settings.getJWTExpLeewaySec());
            claims.put(Constants.ROLES, roles);
            String token = jwtController.createToken(settings.getJWTSigningKeyName(), false, settings.getJWTIssuer(), audience, DateUtils.localDateTime2Date(expirationDate), DateUtils.localDateTime2Date(DateUtils.getNow()), user.getUsername(), claims, SignatureAlgorithm.valueOf(settings.getJWTSignatureAlg()));
            String projectAirflowDir = getProjectSecretsDirectory(user.getUsername()).toString();
            airflowJWT.tokenFile = Paths.get(projectAirflowDir, getTokenFileName(project.getName(), user.getUsername()));
            airflowJWT.token = token;
            writeTokenToFile(airflowJWT);
            certificateMaterializer.materializeCertificatesLocalCustomDir(user.getUsername(), project.getName(), projectAirflowDir);
            airflowJWTs.add(airflowJWT);
        } catch (GeneralSecurityException | JWTException ex) {
            deleteAirflowMaterial(materialID);
            throw new AirflowException(RESTCodes.AirflowErrorCode.JWT_NOT_CREATED, Level.SEVERE, "Could not generate Airflow JWT for user " + user.getUsername(), ex.getMessage(), ex);
        } catch (IOException ex) {
            LOG.log(Level.WARNING, "Could not write Airflow JWT for user " + hdfsUsersController.getHdfsUserName(project, user), ex);
            deleteAirflowMaterial(materialID);
            try {
                jwtController.invalidate(airflowJWT.token);
            } catch (InvalidationException invEx) {
                LOG.log(Level.FINE, "Could not invalidate Airflow JWT. Skipping...", ex);
            }
            throw new AirflowException(RESTCodes.AirflowErrorCode.JWT_NOT_STORED, Level.SEVERE, "Could not store Airflow JWT for user " + hdfsUsersController.getHdfsUserName(project, user), ex.getMessage(), ex);
        }
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) HashMap(java.util.HashMap) JWTException(io.hops.hopsworks.jwt.exception.JWTException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) MaterializedJWT(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT) MaterializedJWTID(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID) AirflowException(io.hops.hopsworks.exceptions.AirflowException) InvalidationException(io.hops.hopsworks.jwt.exception.InvalidationException) AccessTimeout(javax.ejb.AccessTimeout) Lock(javax.ejb.Lock)

Example 2 with MaterializedJWTID

use of io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID in project hopsworks by logicalclocks.

the class AirflowManager method cleanStaleSecurityMaterial.

private void cleanStaleSecurityMaterial() {
    Iterator<AirflowJWT> airflowJWTsIt = airflowJWTs.iterator();
    while (airflowJWTsIt.hasNext()) {
        AirflowJWT nextElement = airflowJWTsIt.next();
        try {
            MaterializedJWTID materialId = new MaterializedJWTID(nextElement.projectId, nextElement.uid, MaterializedJWTID.USAGE.AIRFLOW);
            MaterializedJWT airflowMaterial = materializedJWTFacade.findById(materialId);
            boolean shouldDelete = true;
            if (airflowMaterial != null) {
                List<AirflowDag> ownedDags = airflowDagFacade.filterByOwner(nextElement.username);
                for (AirflowDag dag : ownedDags) {
                    if (!dag.getPaused()) {
                        shouldDelete = false;
                        break;
                    }
                }
            }
            if (shouldDelete) {
                certificateMaterializer.removeCertificatesLocalCustomDir(nextElement.username, nextElement.projectName, getProjectSecretsDirectory(nextElement.username).toString());
                FileUtils.deleteQuietly(nextElement.tokenFile.toFile());
                airflowJWTsIt.remove();
                if (airflowMaterial != null) {
                    deleteAirflowMaterial(materialId);
                }
                deleteDirectoryIfEmpty(nextElement.tokenFile.getParent());
            }
        } catch (Exception ex) {
            // Catch everything here. We don't want the timer thread to get killed (expunging timer)
            // Be on the safe side and renew the token
            LOG.log(Level.WARNING, "Could not determine if token " + nextElement + " is stale. It will be renewed!", ex);
        }
    }
}
Also used : MaterializedJWTID(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID) AirflowDag(io.hops.hopsworks.common.dao.airflow.AirflowDag) MaterializedJWT(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT) GeneralSecurityException(java.security.GeneralSecurityException) JWTDecodeException(com.auth0.jwt.exceptions.JWTDecodeException) SQLException(java.sql.SQLException) AirflowException(io.hops.hopsworks.exceptions.AirflowException) IOException(java.io.IOException) JWTException(io.hops.hopsworks.jwt.exception.JWTException) InvalidationException(io.hops.hopsworks.jwt.exception.InvalidationException)

Example 3 with MaterializedJWTID

use of io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID in project hopsworks by logicalclocks.

the class JupyterJWTManager method materializeJWT.

@Lock(LockType.WRITE)
@AccessTimeout(value = 2000)
public void materializeJWT(Users user, Project project, JupyterSettings jupyterSettings, String cid, Integer port, String[] audience) throws ServiceException {
    MaterializedJWTID materialID = new MaterializedJWTID(project.getId(), user.getUid(), MaterializedJWTID.USAGE.JUPYTER);
    if (!materializedJWTFacade.exists(materialID)) {
        LocalDateTime expirationDate = LocalDateTime.now().plus(settings.getJWTLifetimeMs(), ChronoUnit.MILLIS);
        JupyterJWT jupyterJWT = new JupyterJWT(project, user, expirationDate, new CidAndPort(cid, port));
        try {
            String[] roles = usersController.getUserRoles(user).toArray(new String[1]);
            MaterializedJWT materializedJWT = new MaterializedJWT(materialID);
            materializedJWTFacade.persist(materializedJWT);
            Map<String, Object> claims = new HashMap<>(3);
            claims.put(Constants.RENEWABLE, false);
            claims.put(Constants.EXPIRY_LEEWAY, settings.getJWTExpLeewaySec());
            claims.put(Constants.ROLES, roles);
            String token = jwtController.createToken(settings.getJWTSigningKeyName(), false, settings.getJWTIssuer(), audience, DateUtils.localDateTime2Date(expirationDate), DateUtils.localDateTime2Date(DateUtils.getNow()), user.getUsername(), claims, SignatureAlgorithm.valueOf(settings.getJWTSignatureAlg()));
            jupyterJWT.tokenFile = constructTokenFilePath(jupyterSettings);
            jupyterJWT.token = token;
            jwtTokenWriter.writeToken(settings, jupyterJWT);
            addToken(jupyterJWT);
        } catch (GeneralSecurityException | JWTException ex) {
            LOG.log(Level.SEVERE, "Error generating Jupyter JWT for " + jupyterJWT, ex);
            materializedJWTFacade.delete(materialID);
            throw new ServiceException(RESTCodes.ServiceErrorCode.JUPYTER_START_ERROR, Level.SEVERE, "Could not generate Jupyter JWT", ex.getMessage(), ex);
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, "Error writing Jupyter JWT to file for " + jupyterJWT, ex);
            materializedJWTFacade.delete(materialID);
            try {
                jwtController.invalidate(jupyterJWT.token);
            } catch (InvalidationException invEx) {
                LOG.log(Level.FINE, "Could not invalidate Jupyter JWT after failure to write to file", ex);
            }
            throw new ServiceException(RESTCodes.ServiceErrorCode.JUPYTER_START_ERROR, Level.SEVERE, "Could not write Jupyter JWT to file", ex.getMessage(), ex);
        }
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) HashMap(java.util.HashMap) JWTException(io.hops.hopsworks.jwt.exception.JWTException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) MaterializedJWT(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT) MaterializedJWTID(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID) ServiceException(io.hops.hopsworks.exceptions.ServiceException) InvalidationException(io.hops.hopsworks.jwt.exception.InvalidationException) AccessTimeout(javax.ejb.AccessTimeout) Lock(javax.ejb.Lock)

Example 4 with MaterializedJWTID

use of io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID in project hopsworks by logicalclocks.

the class JupyterJWTManager method cleanJWT.

@Lock(LockType.WRITE)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void cleanJWT(String cid, Integer port) {
    Optional<JupyterJWT> optional = Optional.ofNullable(pidAndPortToJWT.get(new CidAndPort(cid, port)));
    if (!optional.isPresent()) {
        LOG.log(WARNING, "JupyterJWT not found for cid " + cid + " and port " + port);
        return;
    }
    JupyterJWT element = optional.get();
    try {
        MaterializedJWTID materializedJWTID = new MaterializedJWTID(element.project.getId(), element.user.getUid(), MaterializedJWTID.USAGE.JUPYTER);
        MaterializedJWT material = materializedJWTFacade.findById(materializedJWTID);
        jwtTokenWriter.deleteToken(element);
        if (material != null) {
            materializedJWTFacade.delete(materializedJWTID);
        }
        removeToken(element.pidAndPort);
        jwtController.invalidate(element.token);
    } catch (Exception ex) {
        // Catch everything and do not fail. If we failed to determine the status of Jupyter, we renew the token
        // to be safe
        LOG.log(Level.FINE, "Could not determine if Jupyter JWT for " + element + " is still valid. Renewing it...");
    }
}
Also used : MaterializedJWTID(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID) MaterializedJWT(io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT) GeneralSecurityException(java.security.GeneralSecurityException) JWTDecodeException(com.auth0.jwt.exceptions.JWTDecodeException) IOException(java.io.IOException) ServiceException(io.hops.hopsworks.exceptions.ServiceException) JWTException(io.hops.hopsworks.jwt.exception.JWTException) InvalidationException(io.hops.hopsworks.jwt.exception.InvalidationException) TransactionAttribute(javax.ejb.TransactionAttribute) Lock(javax.ejb.Lock)

Aggregations

InvalidationException (io.hops.hopsworks.jwt.exception.InvalidationException)4 JWTException (io.hops.hopsworks.jwt.exception.JWTException)4 MaterializedJWT (io.hops.hopsworks.persistence.entity.airflow.MaterializedJWT)4 MaterializedJWTID (io.hops.hopsworks.persistence.entity.airflow.MaterializedJWTID)4 IOException (java.io.IOException)4 GeneralSecurityException (java.security.GeneralSecurityException)4 Lock (javax.ejb.Lock)3 JWTDecodeException (com.auth0.jwt.exceptions.JWTDecodeException)2 AirflowException (io.hops.hopsworks.exceptions.AirflowException)2 ServiceException (io.hops.hopsworks.exceptions.ServiceException)2 LocalDateTime (java.time.LocalDateTime)2 HashMap (java.util.HashMap)2 AccessTimeout (javax.ejb.AccessTimeout)2 AirflowDag (io.hops.hopsworks.common.dao.airflow.AirflowDag)1 SQLException (java.sql.SQLException)1 TransactionAttribute (javax.ejb.TransactionAttribute)1