|  | 
|  | 1 | +/* | 
|  | 2 | + * Licensed to the Apache Software Foundation (ASF) under one or more | 
|  | 3 | + * contributor license agreements.  See the NOTICE file distributed with | 
|  | 4 | + * this work for additional information regarding copyright ownership. | 
|  | 5 | + * The ASF licenses this file to You under the Apache License, Version 2.0 | 
|  | 6 | + * (the "License"); you may not use this file except in compliance with | 
|  | 7 | + * the License.  You may obtain a copy of the License at | 
|  | 8 | + * | 
|  | 9 | + *    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 10 | + * | 
|  | 11 | + * Unless required by applicable law or agreed to in writing, software | 
|  | 12 | + * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 14 | + * See the License for the specific language governing permissions and | 
|  | 15 | + * limitations under the License. | 
|  | 16 | + * | 
|  | 17 | + */ | 
|  | 18 | + | 
|  | 19 | +package org.apache.streampipes.service.core.migrations.v0980; | 
|  | 20 | + | 
|  | 21 | +import org.apache.streampipes.model.shared.api.Storable; | 
|  | 22 | +import org.apache.streampipes.service.core.migrations.Migration; | 
|  | 23 | +import org.apache.streampipes.storage.api.IPermissionStorage; | 
|  | 24 | +import org.apache.streampipes.storage.management.StorageDispatcher; | 
|  | 25 | + | 
|  | 26 | +import org.slf4j.Logger; | 
|  | 27 | +import org.slf4j.LoggerFactory; | 
|  | 28 | + | 
|  | 29 | +import java.io.IOException; | 
|  | 30 | +import java.util.List; | 
|  | 31 | + | 
|  | 32 | +/** | 
|  | 33 | + * This migration is required because the export/import process sanitizes resource ids for the permissions. | 
|  | 34 | + * This breaks the link between resources and their permissions after import. | 
|  | 35 | + */ | 
|  | 36 | +public class FixImportedPermissionsMigration implements Migration { | 
|  | 37 | + | 
|  | 38 | +  private static final Logger LOG = LoggerFactory.getLogger(FixImportedPermissionsMigration.class); | 
|  | 39 | + | 
|  | 40 | +  private final IPermissionStorage permissionStorage = | 
|  | 41 | +      StorageDispatcher.INSTANCE.getNoSqlStore() | 
|  | 42 | +                                .getPermissionStorage(); | 
|  | 43 | + | 
|  | 44 | +  @Override | 
|  | 45 | +  public boolean shouldExecute() { | 
|  | 46 | +    return true; | 
|  | 47 | +  } | 
|  | 48 | + | 
|  | 49 | +  @Override | 
|  | 50 | +  public void executeMigration() throws IOException { | 
|  | 51 | +    migrateDashboardPermissions(); | 
|  | 52 | +    migrateChartsPermissions(); | 
|  | 53 | +    migrateDataStreamPermissions(); | 
|  | 54 | +  } | 
|  | 55 | + | 
|  | 56 | +  private void migrateDashboardPermissions() { | 
|  | 57 | +    LOG.info("Strart migrate permissions for dashboards"); | 
|  | 58 | +    var dataExplorerDashboardStorage = StorageDispatcher.INSTANCE | 
|  | 59 | +        .getNoSqlStore() | 
|  | 60 | +        .getDataExplorerDashboardStorage(); | 
|  | 61 | +    var dashboards = dataExplorerDashboardStorage.findAll(); | 
|  | 62 | +    migrateResourcePermissions(dashboards); | 
|  | 63 | +    LOG.info("Finished migrate permissions for dashboards"); | 
|  | 64 | +  } | 
|  | 65 | + | 
|  | 66 | +  private void migrateChartsPermissions() { | 
|  | 67 | +    LOG.info("Strart migrate permissions for charts"); | 
|  | 68 | +    var dataExplorerWidgetStorage = StorageDispatcher.INSTANCE | 
|  | 69 | +        .getNoSqlStore() | 
|  | 70 | +        .getDataExplorerWidgetStorage(); | 
|  | 71 | +    var charts = dataExplorerWidgetStorage.findAll(); | 
|  | 72 | +    migrateResourcePermissions(charts); | 
|  | 73 | +    LOG.info("Finished migrate permissions for charts"); | 
|  | 74 | +  } | 
|  | 75 | + | 
|  | 76 | +  private void migrateDataStreamPermissions() { | 
|  | 77 | +    LOG.info("Strart migrate permissions for data streams"); | 
|  | 78 | +    var dataStreamStorage = | 
|  | 79 | +        StorageDispatcher.INSTANCE.getNoSqlStore() | 
|  | 80 | +                                  .getDataStreamStorage(); | 
|  | 81 | +    var dataStreams = dataStreamStorage.findAll(); | 
|  | 82 | +    migrateResourcePermissions(dataStreams); | 
|  | 83 | +    LOG.info("Finished migrate permissions for data streams"); | 
|  | 84 | +  } | 
|  | 85 | + | 
|  | 86 | +  /** | 
|  | 87 | +   * Migrate permissions for the given resources, by replacing the sanitized id with the original id. | 
|  | 88 | +   */ | 
|  | 89 | +  private void migrateResourcePermissions(List<? extends Storable> resources) { | 
|  | 90 | +    resources.forEach(resource -> { | 
|  | 91 | +      // This uses the same sanitization logic as the exporter | 
|  | 92 | +      var sanitizedId = sanitize(resource.getElementId()); | 
|  | 93 | +      var permissions = permissionStorage.getUserPermissionsForObject(sanitizedId); | 
|  | 94 | + | 
|  | 95 | +      permissions.forEach(permission -> { | 
|  | 96 | +        permission.setObjectInstanceId(resource.getElementId()); | 
|  | 97 | +        permissionStorage.updateElement(permission); | 
|  | 98 | +        LOG.info( | 
|  | 99 | +            "Updated permission id from {} to {}", | 
|  | 100 | +            sanitizedId, | 
|  | 101 | +            resource.getElementId() | 
|  | 102 | +        ); | 
|  | 103 | +      }); | 
|  | 104 | +    }); | 
|  | 105 | +  } | 
|  | 106 | + | 
|  | 107 | +  @Override | 
|  | 108 | +  public String getDescription() { | 
|  | 109 | +    return "Fix permissions of imported data streams, dashboards and charts"; | 
|  | 110 | +  } | 
|  | 111 | + | 
|  | 112 | +  private String sanitize(String resourceId) { | 
|  | 113 | +    return resourceId.replaceAll(":", "") | 
|  | 114 | +                     .replaceAll("\\.", ""); | 
|  | 115 | +  } | 
|  | 116 | +} | 
0 commit comments