source: josm/trunk/src/org/openstreetmap/josm/io/auth/AbstractCredentialsAgent.java @ 12869

Last change on this file since 12869 was 12869, checked in by Don-vip, 12 months ago

see #15229 - see #15182 - SonarQube - squid:S2444 - make static fields volatile

  • Property svn:eol-style set to native
File size: 5.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io.auth;
3
4import java.net.Authenticator.RequestorType;
5import java.net.PasswordAuthentication;
6import java.util.EnumMap;
7import java.util.Map;
8import java.util.Objects;
9
10import org.openstreetmap.josm.tools.Logging;
11
12/**
13 * Partial implementation of the {@link CredentialsAgent} interface.
14 * <p>
15 * Provides a memory cache for the credentials and means to query the information from the user.
16 * @since 4246
17 */
18public abstract class AbstractCredentialsAgent implements CredentialsAgent {
19
20    /**
21     * Synchronous credentials provider. Called if no credentials are cached. Can be used for user login prompt.
22     * @since 12821
23     */
24    @FunctionalInterface
25    public interface CredentialsProvider {
26        /**
27         * Fills the given response with appropriate user credentials.
28         * @param requestorType type of the entity requesting authentication
29         * @param agent the credentials agent requesting credentials
30         * @param response authentication response to fill
31         * @param username the known username, if any. Likely to be empty
32         * @param password the known password, if any. Likely to be empty
33         * @param host the host against authentication will be performed
34         */
35        void provideCredentials(RequestorType requestorType, AbstractCredentialsAgent agent, CredentialsAgentResponse response,
36                String username, String password, String host);
37    }
38
39    private static volatile CredentialsProvider credentialsProvider =
40            (a, b, c, d, e, f) -> Logging.error("Credentials provider has not been set");
41
42    /**
43     * Sets the global credentials provider.
44     * @param provider credentials provider. Called if no credentials are cached. Can be used for user login prompt
45     */
46    public static void setCredentialsProvider(CredentialsProvider provider) {
47        credentialsProvider = Objects.requireNonNull(provider, "provider");
48    }
49
50    protected Map<RequestorType, PasswordAuthentication> memoryCredentialsCache = new EnumMap<>(RequestorType.class);
51
52    @Override
53    public CredentialsAgentResponse getCredentials(final RequestorType requestorType, final String host, boolean noSuccessWithLastResponse)
54            throws CredentialsAgentException {
55        if (requestorType == null)
56            return null;
57        PasswordAuthentication credentials = lookup(requestorType, host);
58        final String username = (credentials == null || credentials.getUserName() == null) ? "" : credentials.getUserName();
59        final String password = (credentials == null || credentials.getPassword() == null) ? "" : String.valueOf(credentials.getPassword());
60
61        final CredentialsAgentResponse response = new CredentialsAgentResponse();
62
63        /*
64         * Last request was successful and there was no credentials stored
65         * in file (or only the username is stored).
66         * -> Try to recall credentials that have been entered
67         * manually in this session.
68         */
69        if (!noSuccessWithLastResponse && memoryCredentialsCache.containsKey(requestorType) &&
70                (credentials == null || credentials.getPassword() == null || credentials.getPassword().length == 0)) {
71            PasswordAuthentication pa = memoryCredentialsCache.get(requestorType);
72            response.setUsername(pa.getUserName());
73            response.setPassword(pa.getPassword());
74            response.setCanceled(false);
75        /*
76         * Prompt the user for credentials. This happens the first time each
77         * josm start if the user does not save the credentials to preference
78         * file (username=="") and each time after authentication failed
79         * (noSuccessWithLastResponse == true).
80         */
81        } else if (noSuccessWithLastResponse || username.isEmpty() || password.isEmpty()) {
82            credentialsProvider.provideCredentials(requestorType, this, response, username, password, host);
83            if (response.isCanceled() || response.getUsername() == null || response.getPassword() == null) {
84                return response;
85            }
86            if (response.isSaveCredentials()) {
87                store(requestorType, host, new PasswordAuthentication(
88                        response.getUsername(),
89                        response.getPassword()
90                ));
91            /*
92             * User decides not to save credentials to file. Keep it
93             * in memory so we don't have to ask over and over again.
94             */
95            } else {
96                PasswordAuthentication pa = new PasswordAuthentication(response.getUsername(), response.getPassword());
97                memoryCredentialsCache.put(requestorType, pa);
98            }
99        /*
100         * We got it from file.
101         */
102        } else {
103            response.setUsername(username);
104            response.setPassword(password.toCharArray());
105            response.setCanceled(false);
106        }
107        return response;
108    }
109
110    /**
111     * Provide the text for a checkbox that offers to save the
112     * username and password that has been entered by the user.
113     * @return checkbox text
114     */
115    public abstract String getSaveUsernameAndPasswordCheckboxText();
116}
Note: See TracBrowser for help on using the repository browser.