source: josm/trunk/src/org/openstreetmap/josm/gui/JosmUserIdentityManager.java@ 5434

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

fix #6594 - Fetch user details with supplied OAuth credentials to download changesets without having to set user name in "Basic authentication" tab + fix a bug in languages parsing

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.text.MessageFormat;
8
9import org.openstreetmap.josm.Main;
10import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
11import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
12import org.openstreetmap.josm.data.Preferences.StringSetting;
13import org.openstreetmap.josm.data.osm.UserInfo;
14import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
15import org.openstreetmap.josm.io.OsmServerUserInfoReader;
16import org.openstreetmap.josm.io.OsmTransferException;
17import org.openstreetmap.josm.io.auth.CredentialsManager;
18import org.openstreetmap.josm.tools.CheckParameterUtil;
19
20/**
21 * JosmUserStateManager is a global object which keeps track of what JOSM knows about
22 * the identity of the current user.
23 *
24 * JOSM can be operated anonymously provided the current user never invokes an operation
25 * on the OSM server which required authentication. In this case JOSM neither knows
26 * the user name of the OSM account of the current user nor its unique id. Perhaps the
27 * user doesn't have one.
28 *
29 * If the current user supplies a user name and a password in the JOSM preferences JOSM
30 * can partially identify the user.
31 *
32 * The current user is fully identified if JOSM knows both the user name and the unique
33 * id of the users OSM account. The latter is retrieved from the OSM server with a
34 * <tt>GET /api/0.6/user/details</tt> request, submitted with the user name and password
35 * of the current user.
36 *
37 * The global JosmUserStateManager listens to {@link PreferenceChangeEvent}s and keeps track
38 * of what the current JOSM instance knows about the current user. Other subsystems can
39 * let the global JosmUserStateManager know in case they fully identify the current user, see
40 * {@link #setFullyIdentified}.
41 *
42 * The information kept by the JosmUserStateManager can be used to
43 * <ul>
44 * <li>safely query changesets owned by the current user based on its user id, not on its user name</li>
45 * <li>safely search for objects last touched by the current user based on its user id, not on its user name</li>
46 * </ul>
47 *
48 */
49public class JosmUserIdentityManager implements PreferenceChangedListener{
50
51 static private JosmUserIdentityManager instance;
52
53 /**
54 * Replies the unique instance of the JOSM user identity manager
55 *
56 * @return the unique instance of the JOSM user identity manager
57 */
58 static public JosmUserIdentityManager getInstance() {
59 if (instance == null) {
60 instance = new JosmUserIdentityManager();
61 instance.initFromPreferences();
62 Main.pref.addPreferenceChangeListener(instance);
63 }
64 return instance;
65 }
66
67 private String userName;
68 private UserInfo userInfo;
69
70 private JosmUserIdentityManager() {
71 }
72
73 /**
74 * Remembers the fact that the current JOSM user is anonymous.
75 */
76 public void setAnonymous() {
77 userName = null;
78 userInfo = null;
79 }
80
81 /**
82 * Remebers the fact that the current JOSM user is partially identified
83 * by the user name of its OSM account.
84 *
85 * @param userName the user name. Must not be null. Must not be empty (whitespace only).
86 * @throws IllegalArgumentException thrown if userName is null
87 * @throws IllegalArgumentException thrown if userName is empty
88 */
89 public void setPartiallyIdentified(String userName) throws IllegalArgumentException {
90 CheckParameterUtil.ensureParameterNotNull(userName, "userName");
91 if (userName.trim().equals(""))
92 throw new IllegalArgumentException(MessageFormat.format("Expected non-empty value for parameter ''{0}'', got ''{1}''", "userName", userName));
93 this.userName = userName;
94 userInfo = null;
95 }
96
97 /**
98 * Remembers the fact that the current JOSM user is fully identified with a
99 * verified pair of user name and user id.
100 *
101 * @param userName the user name. Must not be null. Must not be empty.
102 * @param userinfo additional information about the user, retrieved from the OSM server and including the user id
103 * @throws IllegalArgumentException thrown if userName is null
104 * @throws IllegalArgumentException thrown if userName is empty
105 * @throws IllegalArgumentException thrown if userinfo is null
106 */
107 public void setFullyIdentified(String username, UserInfo userinfo) throws IllegalArgumentException {
108 CheckParameterUtil.ensureParameterNotNull(username, "username");
109 if (username.trim().equals(""))
110 throw new IllegalArgumentException(tr("Expected non-empty value for parameter ''{0}'', got ''{1}''", "userName", userName));
111 CheckParameterUtil.ensureParameterNotNull(userinfo, "userinfo");
112 this.userName = username;
113 this.userInfo = userinfo;
114 }
115
116 /**
117 * Replies true if the current JOSM user is anonymous.
118 *
119 * @return true if the current user is anonymous.
120 */
121 public boolean isAnonymous() {
122 return userName == null && userInfo == null;
123 }
124
125 /**
126 * Replies true if the current JOSM user is partially identified.
127 *
128 * @return true if the current JOSM user is partially identified.
129 */
130 public boolean isPartiallyIdentified() {
131 return userName != null && userInfo == null;
132 }
133
134 /**
135 * Replies true if the current JOSM user is fully identified.
136 *
137 * @return true if the current JOSM user is fully identified.
138 */
139 public boolean isFullyIdentified() {
140 return userName != null && userInfo != null;
141 }
142
143 /**
144 * Replies the user name of the current JOSM user. null, if {@link #isAnonymous()} is true.
145 *
146 * @return the user name of the current JOSM user
147 */
148 public String getUserName() {
149 return userName;
150 }
151
152 /**
153 * Replies the user id of the current JOSM user. 0, if {@link #isAnonymous()} or
154 * {@link #isPartiallyIdentified()} is true.
155 *
156 * @return the user id of the current JOSM user
157 */
158 public int getUserId() {
159 if (userInfo == null) return 0;
160 return userInfo.getId();
161 }
162
163 /**
164 * Replies verified additional information about the current user if the user is
165 * {@link #isFullyIdentified()}.
166 *
167 * @return verified additional information about the current user
168 */
169 public UserInfo getUserInfo() {
170 return userInfo;
171 }
172
173 /**
174 * Initializes the user identity manager from Basic Authentication values in the {@link org.openstreetmap.josm.data.Preferences}
175 * This method should be called if {@code osm-server.auth-method} is set to {@code basic}.
176 * @see #initFromOAuth
177 */
178 public void initFromPreferences() {
179 String userName = CredentialsManager.getInstance().getUsername();
180 if (isAnonymous()) {
181 if (userName != null && ! userName.trim().equals("")) {
182 setPartiallyIdentified(userName);
183 }
184 } else {
185 if (!userName.equals(this.userName)) {
186 setPartiallyIdentified(userName);
187 } else {
188 // same name in the preferences as JOSM already knows about;
189 // keep the state, be it partially or fully identified
190 }
191 }
192 }
193
194 /**
195 * Initializes the user identity manager from OAuth request of user details.
196 * This method should be called if {@code osm-server.auth-method} is set to {@code oauth}.
197 * @param parent component relative to which the {@link PleaseWaitDialog} is displayed.
198 * @see #initFromPreferences
199 * @since 5434
200 */
201 public void initFromOAuth(Component parent) {
202 try {
203 UserInfo info = new OsmServerUserInfoReader().fetchUserInfo(NullProgressMonitor.INSTANCE);
204 setFullyIdentified(info.getDisplayName(), info);
205 } catch (IllegalArgumentException e) {
206 e.printStackTrace();
207 } catch (OsmTransferException e) {
208 e.printStackTrace();
209 }
210 }
211
212 /**
213 * Replies true if the user with name <code>username</code> is the current
214 * user
215 *
216 * @param username the user name
217 * @return true if the user with name <code>username</code> is the current
218 * user
219 */
220 public boolean isCurrentUser(String username) {
221 if (username == null || this.userName == null) return false;
222 return this.userName.equals(username);
223 }
224
225 /* ------------------------------------------------------------------- */
226 /* interface PreferenceChangeListener */
227 /* ------------------------------------------------------------------- */
228 public void preferenceChanged(PreferenceChangeEvent evt) {
229 if (evt.getKey().equals("osm-server.username")) {
230 if (!(evt.getNewValue() instanceof StringSetting)) return;
231 String newValue = ((StringSetting) evt.getNewValue()).getValue();
232 if (newValue == null || newValue.trim().length() == 0) {
233 setAnonymous();
234 } else {
235 if (! newValue.equals(userName)) {
236 setPartiallyIdentified(newValue);
237 }
238 }
239 return;
240 }
241
242 if (evt.getKey().equals("osm-server.url")) {
243 if (!(evt.getNewValue() instanceof StringSetting)) return;
244 String newValue = ((StringSetting) evt.getNewValue()).getValue();
245 if (newValue == null || newValue.trim().equals("")) {
246 setAnonymous();
247 } else if (isFullyIdentified()) {
248 setPartiallyIdentified(getUserName());
249 }
250 }
251 }
252}
Note: See TracBrowser for help on using the repository browser.