Beispiel #1
0
 // is it a eucalyptus account id?
 @Override
 public String check(String id) {
   try {
     Account account = Accounts.lookupAccountById(id);
     return account.getCanonicalId();
   } catch (AuthException authEx) {
     return null;
   }
 }
 @SuppressWarnings("unchecked")
 public ImageInfo grantPermission(final Account account) {
   EntityTransaction db = Entities.get(ImageInfo.class);
   try {
     ImageInfo entity = Entities.merge(this);
     entity.getPermissions().add(account.getAccountNumber());
     db.commit();
   } catch (Exception ex) {
     Logs.exhaust().error(ex, ex);
     db.rollback();
   }
   return this;
 }
 public SnapshotObjectOps() {
   try {
     Account system = Accounts.lookupAccountByName(Account.SYSTEM_ACCOUNT);
     for (User user : system.getUsers()) {
       if (StorageProperties.BLOCKSTORAGE_ACCOUNT.equals(user.getName())) {
         List<AccessKey> keys = user.getKeys();
         if (!keys.isEmpty()) {
           AccessKey key = keys.get(0);
           s3Client =
               new S3Client(
                   new BasicAWSCredentials(key.getAccessKey(), key.getSecretKey()), false);
           s3Client.setUsePathStyle(true);
           s3Client.setS3Endpoint(StorageProperties.WALRUS_URL);
         } else {
           LOG.error(
               "Something went really wrong. Block storage account does not have an associated access key.");
         }
       }
     }
   } catch (Exception ex) {
     LOG.error(ex, ex);
   }
 }
  /**
   * Evaluates the authorization for the operation requested, evaluates IAM, ACL, and bucket policy
   * (bucket policy not yet supported).
   *
   * @param request
   * @param bucketResourceEntity
   * @param objectResourceEntity
   * @param resourceAllocationSize the size for the quota check(s) if applicable
   * @return
   */
  public <T extends ObjectStorageRequestType> boolean operationAllowed(
      @Nonnull T request,
      @Nullable final S3AccessControlledEntity bucketResourceEntity,
      @Nullable final S3AccessControlledEntity objectResourceEntity,
      long resourceAllocationSize)
      throws IllegalArgumentException {
    /*
     * Process the operation's authz requirements based on the request type annotations
     */
    Ats requestAuthzProperties = Ats.from(request);
    ObjectStorageProperties.Permission[] requiredBucketACLPermissions = null;
    ObjectStorageProperties.Permission[] requiredObjectACLPermissions = null;
    Boolean allowOwnerOnly = null;
    RequiresACLPermission requiredACLs = requestAuthzProperties.get(RequiresACLPermission.class);
    if (requiredACLs != null) {
      requiredBucketACLPermissions = requiredACLs.bucket();
      requiredObjectACLPermissions = requiredACLs.object();
      allowOwnerOnly = requiredACLs.ownerOnly();
    } else {
      // No ACL annotation is ok, maybe a admin only op
    }

    String[] requiredActions = null;
    RequiresPermission perms = requestAuthzProperties.get(RequiresPermission.class);
    if (perms != null) {
      requiredActions = perms.value();
    }

    Boolean allowAdmin = (requestAuthzProperties.get(AdminOverrideAllowed.class) != null);
    Boolean allowOnlyAdmin =
        (requestAuthzProperties.get(AdminOverrideAllowed.class) != null)
            && requestAuthzProperties.get(AdminOverrideAllowed.class).adminOnly();

    // Must have at least one of: admin-only, owner-only, ACL, or IAM.
    if (requiredBucketACLPermissions == null
        && requiredObjectACLPermissions == null
        && requiredActions == null
        && !allowAdmin) {
      // Insufficient permission set on the message type.
      LOG.error(
          "Insufficient permission annotations on type: "
              + request.getClass().getName()
              + " cannot evaluate authorization");
      return false;
    }

    String resourceType = null;
    if (requestAuthzProperties.get(ResourceType.class) != null) {
      resourceType = requestAuthzProperties.get(ResourceType.class).value();
    }

    // Use these variables to isolate where all the AuthExceptions can happen on account/user
    // lookups
    User requestUser = null;
    String securityToken = null;
    Account requestAccount = null;
    AuthContextSupplier authContext = null;
    try {
      // Use context if available as it saves a DB lookup
      try {
        Context ctx = Contexts.lookup(request.getCorrelationId());
        requestUser = ctx.getUser();
        securityToken = ctx.getSecurityToken();
        requestAccount = requestUser.getAccount();
        authContext = ctx.getAuthContext();
      } catch (NoSuchContextException e) {
        requestUser = null;
        securityToken = null;
        requestAccount = null;
        authContext = null;
      }

      // This is not an expected path, but if no context found use the request credentials itself
      if (requestUser == null && !Strings.isNullOrEmpty(request.getEffectiveUserId())) {
        requestUser = Accounts.lookupUserById(request.getEffectiveUserId());
        requestAccount = requestUser.getAccount();
      }

      if (requestUser == null) {
        if (!Strings.isNullOrEmpty(request.getAccessKeyID())) {
          if (securityToken != null) {
            requestUser = SecurityTokenManager.lookupUser(request.getAccessKeyID(), securityToken);
          } else {
            requestUser = Accounts.lookupUserByAccessKeyId(request.getAccessKeyID());
          }
          requestAccount = requestUser.getAccount();
        } else {
          // Set to anonymous user since all else failed
          requestUser = Principals.nobodyUser();
          requestAccount = requestUser.getAccount();
        }
      }
    } catch (AuthException e) {
      LOG.error(
          "Failed to get user for request, cannot verify authorization: " + e.getMessage(), e);
      return false;
    }

    if (allowAdmin && requestUser.isSystemAdmin()) {
      // Admin override
      return true;
    }

    if (authContext == null) {
      authContext =
          Permissions.createAuthContextSupplier(
              requestUser, Collections.<String, String>emptyMap());
    }

    Account resourceOwnerAccount = null;
    if (resourceType == null) {
      LOG.error("No resource type found in request class annotations, cannot process.");
      return false;
    } else {
      try {
        // Ensure we have the proper resource entities present and get owner info
        if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
          // Get the bucket owner.
          if (bucketResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no bucket resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(bucketResourceEntity.getOwnerCanonicalId());
          }
        } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
          if (objectResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no object resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(objectResourceEntity.getOwnerCanonicalId());
          }
        }
      } catch (AuthException e) {
        LOG.error("Exception caught looking up resource owner. Disallowing operation.", e);
        return false;
      }
    }

    // Get the resourceId based on IAM resource type
    String resourceId = null;
    if (resourceId == null) {
      if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
        resourceId = request.getBucket();
      } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
        resourceId = request.getFullResource();
      }
    }

    if (allowAdmin
        && requestUser.isSystemUser()
        && iamPermissionsAllow(
            authContext, requiredActions, resourceType, resourceId, resourceAllocationSize)) {
      // Admin override
      return true;
    }

    if (requiredBucketACLPermissions == null && requiredObjectACLPermissions == null) {
      throw new IllegalArgumentException(
          "No requires-permission actions found in request class annotations, cannot process.");
    }

    /* ACL Checks: Is the user's account allowed? */
    Boolean aclAllow = false;
    if (requiredBucketACLPermissions != null && requiredBucketACLPermissions.length > 0) {
      // Check bucket ACLs

      if (bucketResourceEntity == null) {
        // There are bucket ACL requirements but no bucket entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }

      // Evaluate the bucket ACL, any matching grant gives permission
      for (ObjectStorageProperties.Permission permission : requiredBucketACLPermissions) {
        aclAllow =
            aclAllow || bucketResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    // Check object ACLs, if any
    if (requiredObjectACLPermissions != null && requiredObjectACLPermissions.length > 0) {
      if (objectResourceEntity == null) {
        // There are object ACL requirements but no object entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }
      for (ObjectStorageProperties.Permission permission : requiredObjectACLPermissions) {
        aclAllow =
            aclAllow || objectResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    /* Resource owner only? if so, override any previous acl decisions
     * It is not expected that owneronly is set as well as other ACL permissions,
     * Regular owner permissions (READ, WRITE, READ_ACP, WRITE_ACP) are handled by the regular acl checks.
     * OwnerOnly should be only used for operations not covered by the other Permissions (e.g. logging, or versioning)
     */
    aclAllow =
        (allowOwnerOnly
            ? resourceOwnerAccount.getAccountNumber().equals(requestAccount.getAccountNumber())
            : aclAllow);
    if (aclAllow && isUserAnonymous(requestUser)) {
      // Skip the IAM checks for anonymous access since they will always fail and aren't valid for
      // anonymous users.
      return true;
    } else {
      Boolean iamAllow =
          iamPermissionsAllow(
              authContext, requiredActions, resourceType, resourceId, resourceAllocationSize);
      // Must have both acl and iam allow (account & user)
      return aclAllow && iamAllow;
    }
  }
Beispiel #5
0
 public static CanonicalUser buildCanonicalUser(Account accnt) {
   return new CanonicalUser(accnt.getCanonicalId(), accnt.getName());
 }
  public static NetworkGroup create(
      final OwnerFullName ownerFullName, final String groupName, final String groupDescription)
      throws MetadataException {
    UserFullName userFullName = null;
    if (ownerFullName instanceof UserFullName) {
      userFullName = (UserFullName) ownerFullName;
    } else {
      try {
        Account account = Accounts.lookupAccountById(ownerFullName.getAccountNumber());
        User admin =
            Iterables.find(
                account.getUsers(),
                new Predicate<User>() {

                  @Override
                  public boolean apply(User input) {
                    return input.isAccountAdmin();
                  }
                });
        userFullName = UserFullName.getInstance(admin);
      } catch (Exception ex) {
        LOG.error(ex, ex);
        throw new NoSuchMetadataException(
            "Failed to create group because owning user could not be identified.", ex);
      }
    }

    final EntityTransaction db = Entities.get(NetworkGroup.class);
    try {
      NetworkGroup net =
          Entities.uniqueResult(
              new NetworkGroup(
                  AccountFullName.getInstance(userFullName.getAccountNumber()), groupName));
      if (net == null) {
        final NetworkGroup entity =
            Entities.persist(new NetworkGroup(userFullName, groupName, groupDescription));
        db.commit();
        return entity;
      } else {
        db.rollback();
        throw new DuplicateMetadataException(
            "Failed to create group: " + groupName + " for " + userFullName.toString());
      }
    } catch (final NoSuchElementException ex) {
      final NetworkGroup entity =
          Entities.persist(new NetworkGroup(userFullName, groupName, groupDescription));
      db.commit();
      return entity;
    } catch (final ConstraintViolationException ex) {
      Logs.exhaust().error(ex);
      db.rollback();
      throw new DuplicateMetadataException(
          "Failed to create group: " + groupName + " for " + userFullName.toString(), ex);
    } catch (final Exception ex) {
      Logs.exhaust().error(ex, ex);
      db.rollback();
      throw new MetadataException(
          "Failed to create group: " + groupName + " for " + userFullName.toString(),
          PersistenceExceptions.transform(ex));
    }
  }
Beispiel #7
0
  public void doGet(HttpServletRequest request, HttpServletResponse response) {
    String code = request.getParameter(PARAMETER_CODE);
    String userName = request.getParameter(PARAMETER_USERNAME);
    String accountName = request.getParameter(PARAMETER_ACCOUNTNAME);
    String mimetype = "application/zip";
    if (accountName == null || "".equals(accountName)) {
      hasError(HttpServletResponse.SC_BAD_REQUEST, "No account name provided", response);
      return;
    }
    if (userName == null || "".equals(userName)) {
      hasError(HttpServletResponse.SC_BAD_REQUEST, "No user name provided", response);
      return;
    }
    if (code == null || "".equals(code)) {
      hasError(HttpServletResponse.SC_BAD_REQUEST, "Wrong user security code", response);
      return;
    }

    User user = null;
    try {
      Account account = Accounts.lookupAccountByName(accountName);
      user = account.lookupUserByName(userName);
      if (!user.isEnabled() || !RegistrationStatus.CONFIRMED.equals(user.getRegistrationStatus())) {
        hasError(HttpServletResponse.SC_FORBIDDEN, "Access is not authorized", response);
        return;
      }
    } catch (AuthException e) {
      hasError(HttpServletResponse.SC_BAD_REQUEST, "User does not exist", response);
      return;
    } catch (Exception e) {
      hasError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Fail to retrieve user data", response);
      return;
    }
    try {
      if (!code.equals(user.resetToken())) {
        hasError(HttpServletResponse.SC_FORBIDDEN, "Access is not authorized", response);
        return;
      }
    } catch (Exception e) {
      hasError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "Can not reset user security code",
          response);
      return;
    }
    response.setContentType(mimetype);
    response.setHeader(
        "Content-Disposition",
        "attachment; filename=\"" + X509Download.NAME_SHORT + "-" + userName + "-x509.zip\"");
    LOG.info("pushing out the X509 certificate for user " + userName);

    byte[] x509zip = null;
    try {
      x509zip = getX509Zip(user);
    } catch (Exception e) {
      LOG.debug(e, e);
      hasError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
          "Fail to return user credentials",
          response);
      return;
    }
    try {
      ServletOutputStream op = response.getOutputStream();

      response.setContentLength(x509zip.length);

      op.write(x509zip);
      op.flush();

    } catch (Exception e) {
      LOG.error(e, e);
    }
  }