com.microsoft.tfs.core.credentials.internal.PersistenceStoreCredentialsManager.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.tfs.core.credentials.internal.PersistenceStoreCredentialsManager.java

Source

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See License.txt in the repository root.

package com.microsoft.tfs.core.credentials.internal;

import java.net.URI;
import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.microsoft.tfs.core.Messages;
import com.microsoft.tfs.core.credentials.CachedCredentials;
import com.microsoft.tfs.core.credentials.CredentialsManager;
import com.microsoft.tfs.core.persistence.LockMode;
import com.microsoft.tfs.core.persistence.PersistenceSecurity;
import com.microsoft.tfs.core.persistence.PersistenceStore;
import com.microsoft.tfs.core.util.ServerURIComparator;
import com.microsoft.tfs.core.util.URIUtils;
import com.microsoft.tfs.util.Check;

/**
 * An implementation of {@link CredentialsManager} that can read and write to
 * the <b>unsecure</b> {@link PersistenceStore} mechanism.
 *
 * @threadsafety thread-safe
 */
public class PersistenceStoreCredentialsManager implements CredentialsManager {
    private static final Log log = LogFactory.getLog(PersistenceStoreCredentialsManager.class);

    private static final String CHILD_STORE_NAME = "TEE-Servers"; //$NON-NLS-1$
    private static final String OBJECT_NAME = "Credentials.xml"; //$NON-NLS-1$

    private final PersistenceStore configurationStore;

    public PersistenceStoreCredentialsManager(final PersistenceStore configurationStore) {
        Check.notNull(configurationStore, "configurationStore"); //$NON-NLS-1$

        this.configurationStore = configurationStore;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getUIMechanismName() {
        return Messages.getString("PersistenceStoreCredentialsManager.PersistenceStore"); //$NON-NLS-1$
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean canWrite() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isSecure() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public CachedCredentials[] getCredentials() {
        final Collection<CachedCredentials> credentials = load().values();

        return credentials.toArray(new CachedCredentials[credentials.size()]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public CachedCredentials getCredentials(URI serverURI) {
        Check.notNull(serverURI, "serverURI"); //$NON-NLS-1$

        // Reduce to scheme, host, port
        serverURI = URIUtils.removePathAndQueryParts(serverURI);

        // The map normalizes URIs for comparision
        return load().get(serverURI);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean setCredentials(CachedCredentials cachedCredentials) {
        Check.notNull(cachedCredentials, "cachedCredentials"); //$NON-NLS-1$
        Check.notNull(cachedCredentials.getURI(), "cachedCredentials.getURI()"); //$NON-NLS-1$

        // Reduce to scheme, host, port
        final URI serverURI = URIUtils.removePathAndQueryParts(cachedCredentials.getURI());
        cachedCredentials = new CachedCredentials(serverURI, cachedCredentials.getUsername(),
                cachedCredentials.getPassword());

        try {
            final Map<URI, CachedCredentials> credentialsMap = load();

            // Even though the map uses a custom comparator that knows to ignore
            // slashes, tidy up the string so it looks good in the cache file.
            credentialsMap.put(URIUtils.removeTrailingSlash(serverURI), cachedCredentials);

            save(credentialsMap);

            return true;
        } catch (final Exception e) {
            log.warn("Unable to save credentials cache", e); //$NON-NLS-1$
            return false;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean removeCredentials(final CachedCredentials cachedCredentials) {
        Check.notNull(cachedCredentials, "cachedCredentials"); //$NON-NLS-1$
        Check.notNull(cachedCredentials.getURI(), "cachedCredentials.getURI()"); //$NON-NLS-1$

        return removeCredentials(cachedCredentials.getURI());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean removeCredentials(final URI uri) {
        Check.notNull(uri, "uri"); //$NON-NLS-1$

        // Reduce to scheme, host, port
        final URI serverURI = URIUtils.removePathAndQueryParts(uri);

        try {
            final Map<URI, CachedCredentials> credentialsMap = load();

            // Even though the map uses a custom comparator that knows to ignore
            // slashes, tidy up the string so it looks good in the cache file.
            final CachedCredentials removedCredentials = credentialsMap.remove(serverURI);

            save(credentialsMap);

            return (removedCredentials != null);
        } catch (final Exception e) {
            log.warn("Unable to remove entry from credentials cache", e); //$NON-NLS-1$
            return false;
        }
    }

    private Map<URI, CachedCredentials> load() {
        final PersistenceStore currentStore = configurationStore.getChildStore(CHILD_STORE_NAME);

        try {
            if (currentStore.containsItem(OBJECT_NAME) == false) {
                return newMap();
            }

            @SuppressWarnings("unchecked")
            final Map<URI, CachedCredentials> credentialsMap = (Map<URI, CachedCredentials>) currentStore
                    .retrieveItem(OBJECT_NAME, LockMode.WAIT_FOREVER, null, new CachedCredentialsSerializer());

            // Will be null on XML serialization error
            if (credentialsMap == null) {
                return newMap();
            }

            return credentialsMap;
        } catch (final Exception e) {
            log.warn("Unable to load credentials cache", e); //$NON-NLS-1$
            return newMap();
        }
    }

    private boolean save(final Map<URI, CachedCredentials> credentialsMap) {
        Check.notNull(credentialsMap, "credentialsMap"); //$NON-NLS-1$

        try {
            return configurationStore.getChildStore(CHILD_STORE_NAME).storeItem(OBJECT_NAME, credentialsMap,
                    LockMode.WAIT_FOREVER, null, new CachedCredentialsSerializer(), PersistenceSecurity.PRIVATE);
        } catch (final Exception e) {
            log.warn("Unable to save credentials cache", e); //$NON-NLS-1$ r
            return false;
        }
    }

    protected static Map<URI, CachedCredentials> newMap() {
        return new TreeMap<URI, CachedCredentials>(ServerURIComparator.INSTANCE);
    }
}