org.eclipse.che.multiuser.api.permission.server.HttpPermissionCheckerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.che.multiuser.api.permission.server.HttpPermissionCheckerImpl.java

Source

/*
 * Copyright (c) 2012-2018 Red Hat, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Red Hat, Inc. - initial API and implementation
 */
package org.eclipse.che.multiuser.api.permission.server;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.inject.name.Named;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
import org.eclipse.che.multiuser.api.permission.shared.dto.PermissionsDto;

/**
 * Implementation of {@link PermissionChecker} that load permissions by http requests to {@link
 * PermissionsService}
 *
 * <p>It also caches permissions to avoid frequently requests to workspace master.
 *
 * @author Sergii Leschenko
 */
@Singleton
public class HttpPermissionCheckerImpl implements PermissionChecker {
    private final LoadingCache<Key, Set<String>> permissionsCache;

    @Inject
    public HttpPermissionCheckerImpl(@Named("che.api") String apiEndpoint, HttpJsonRequestFactory requestFactory) {
        // TODO mb make configurable size of cache and expiration time
        this.permissionsCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(1, TimeUnit.MINUTES)
                .build(new CacheLoader<Key, Set<String>>() {
                    @Override
                    public Set<String> load(Key key) throws Exception {
                        UriBuilder currentUsersPermissions = UriBuilder.fromUri(apiEndpoint)
                                .path("permissions/" + key.domain);
                        if (key.instance != null) {
                            currentUsersPermissions.queryParam("instance", key.instance);
                        }
                        String userPermissionsUrl = currentUsersPermissions.build().toString();
                        try {
                            PermissionsDto usersPermissions = requestFactory.fromUrl(userPermissionsUrl)
                                    .useGetMethod().request().asDto(PermissionsDto.class);
                            return new HashSet<>(usersPermissions.getActions());
                        } catch (NotFoundException e) {
                            // user doesn't have permissions
                            return new HashSet<>();
                        }
                    }
                });
    }

    @Override
    public boolean hasPermission(String user, String domain, String instance, String action)
            throws ServerException {
        try {
            return permissionsCache.get(new Key(user, domain, instance)).contains(action);
        } catch (Exception e) {
            throw new ServerException(e.getMessage(), e);
        }
    }

    private static final class Key {
        private final String user;
        private final String domain;
        private final String instance;

        private Key(String user, String domain, String instance) {
            this.user = user;
            this.domain = domain;
            this.instance = instance;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof Key)) {
                return false;
            }
            final Key other = (Key) obj;
            return Objects.equals(user, other.user) && Objects.equals(domain, other.domain)
                    && Objects.equals(instance, other.instance);
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = hash * 31 + Objects.hashCode(user);
            hash = hash * 31 + Objects.hashCode(domain);
            hash = hash * 31 + Objects.hashCode(instance);
            return hash;
        }
    }
}