• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

smartsheet / smartsheet-java-sdk / #60

24 Oct 2025 09:43AM UTC coverage: 60.156% (+0.4%) from 59.737%
#60

push

github

web-flow
Add Wiremock integration tests and update dependencies (#145)

* Add Wiremock integration tests and update dependencies

* Update test method names

* Bump version to 3.9.0 and address comments for the wiremock integration tests

* Refactor Wiremock integration tests for user resources to improve query parameter handling and update endpoint paths

* Fix imports

* Fix checkstyle errors

* Move wiremock tests to sdktest

* Remove redundant Wiremock tests from UserResourcesIT

* Remove unused imports from UserResourcesIT

* Revert UserResourcesIT

* Fix changelog

* Add copyright to WiremockTest

* Update wiremock base uri port

* Rename WiremockTest to UserResourcesContractTests for clarity

* Change WireMock default port

4392 of 7301 relevant lines covered (60.16%)

0.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.45
/src/main/java/com/smartsheet/api/internal/UserResourcesImpl.java
1
/*
2
 * Copyright (C) 2025 Smartsheet
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package com.smartsheet.api.internal;
18

19
import com.smartsheet.api.AuthorizationException;
20
import com.smartsheet.api.InvalidRequestException;
21
import com.smartsheet.api.ResourceNotFoundException;
22
import com.smartsheet.api.ServiceUnavailableException;
23
import com.smartsheet.api.SmartsheetException;
24
import com.smartsheet.api.UserResources;
25
import com.smartsheet.api.internal.http.HttpEntity;
26
import com.smartsheet.api.internal.http.HttpMethod;
27
import com.smartsheet.api.internal.http.HttpRequest;
28
import com.smartsheet.api.internal.http.HttpResponse;
29
import com.smartsheet.api.internal.util.QueryUtil;
30
import com.smartsheet.api.internal.util.Util;
31
import com.smartsheet.api.models.AlternateEmail;
32
import com.smartsheet.api.models.DeleteUserParameters;
33
import com.smartsheet.api.models.PagedResult;
34
import com.smartsheet.api.models.PaginationParameters;
35
import com.smartsheet.api.models.Result;
36
import com.smartsheet.api.models.Sheet;
37
import com.smartsheet.api.models.TokenPaginatedResult;
38
import com.smartsheet.api.models.User;
39
import com.smartsheet.api.models.UserPlan;
40
import com.smartsheet.api.models.UserProfile;
41
import com.smartsheet.api.models.enums.ListUserInclusion;
42
import com.smartsheet.api.models.enums.SeatType;
43
import com.smartsheet.api.models.enums.UpgradeSeatType;
44
import com.smartsheet.api.models.enums.DowngradeSeatType;
45
import com.smartsheet.api.models.enums.UserInclusion;
46

47
import java.io.File;
48
import java.io.FileInputStream;
49
import java.io.FileNotFoundException;
50
import java.io.InputStream;
51
import java.net.URLEncoder;
52
import java.nio.charset.StandardCharsets;
53
import java.text.SimpleDateFormat;
54
import java.util.Date;
55
import java.util.EnumSet;
56
import java.util.HashMap;
57
import java.util.List;
58
import java.util.Map;
59
import java.util.Set;
60

61
/**
62
 * This is the implementation of the UserResources.
63
 * <p>
64
 * Thread Safety: This class is thread safe because it is immutable and its base class is thread safe.
65
 */
66
public class UserResourcesImpl extends AbstractResources implements UserResources {
67

68
    private static final String USERS = "users";
69
    private static final String ALTERNATE_EMAILS = "alternateemails";
70
    public static final String PLANS = "/plans/";
71

72
    /**
73
     * Constructor.
74
     * <p>
75
     * Exceptions: - IllegalArgumentException : if any argument is null
76
     *
77
     * @param smartsheet the smartsheet
78
     */
79
    public UserResourcesImpl(SmartsheetImpl smartsheet) {
80
        super(smartsheet);
1✔
81
    }
1✔
82

83
    /**
84
     * List all users.
85
     * <p>
86
     * It mirrors to the following Smartsheet REST API method: GET /users
87
     *
88
     * @return the list of all users
89
     * @throws IllegalArgumentException    if any argument is null or empty string
90
     * @throws InvalidRequestException     if there is any problem with the REST API request
91
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
92
     * @throws ResourceNotFoundException   if the resource cannot be found
93
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
94
     * @throws SmartsheetException         if there is any other error during the operation
95
     */
96
    public PagedResult<User> listUsers() throws SmartsheetException {
97
        return this.listUsersInternal(null, null, null, null, null);
1✔
98
    }
99

100
    /**
101
     * List all users.
102
     * <p>
103
     * It mirrors to the following Smartsheet REST API method: GET /users
104
     * <p>
105
     * Exceptions:
106
     *   - InvalidRequestException : if there is any problem with the REST API request
107
     *   - AuthorizationException : if there is any problem with the REST API authorization(access token)
108
     *   - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
109
     *   - SmartsheetRestException : if there is any other REST API related error occurred during the operation
110
     *   - SmartsheetException : if there is any other error occurred during the operation
111
     *
112
     * @param pagination the object containing the pagination query parameters
113
     * @return all users (note that empty list will be returned if there is none)
114
     * @throws SmartsheetException the smartsheet exception
115
     */
116
    public PagedResult<User> listUsers(PaginationParameters pagination) throws SmartsheetException {
117
        return this.listUsersInternal(null, null, null, null, pagination);
1✔
118
    }
119

120
    /**
121
     * List all users.
122
     * <p>
123
     * It mirrors to the following Smartsheet REST API method: GET /users
124
     * <p>
125
     * Exceptions:
126
     * - InvalidRequestException : if there is any problem with the REST API request
127
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
128
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
129
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
130
     * - SmartsheetException : if there is any other error occurred during the operation
131
     *
132
     * @param email      the list of email addresses
133
     * @param pagination the object containing the pagination query parameters
134
     * @return all users (note that empty list will be returned if there is none)
135
     * @throws SmartsheetException the smartsheet exception
136
     */
137
    public PagedResult<User> listUsers(Set<String> email, PaginationParameters pagination) throws SmartsheetException {
138
        return this.listUsersInternal(email, null, null, null, pagination);
1✔
139
    }
140

141
    /**
142
     * List all users.
143
     * <p>
144
     * It mirrors to the following Smartsheet REST API method: GET /users
145
     * <p>
146
     * Exceptions:
147
     * - InvalidRequestException : if there is any problem with the REST API request
148
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
149
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
150
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
151
     * - SmartsheetException : if there is any other error occurred during the operation
152
     *
153
     * @param email      the list of email addresses
154
     * @param includes   elements to include in the response
155
     * @param pagination the object containing the pagination query parameters
156
     * @return all users (note that empty list will be returned if there is none)
157
     * @throws SmartsheetException the smartsheet exception
158
     */
159
    public PagedResult<User> listUsers(Set<String> email, EnumSet<ListUserInclusion> includes,
160
                                       PaginationParameters pagination) throws SmartsheetException {
161
        return this.listUsersInternal(email, includes, null, null, pagination);
1✔
162
    }
163

164
    /**
165
     * List all users with support for Seat Type and Plan ID. If planID or seatType is provided, then the response
166
     * will contain  planId, seatType, seatTypeLastChangedAt, isInternal, otherwise - not
167
     * <p>
168
     * It mirrors to the following Smartsheet REST API method: GET /users
169
     * <p>
170
     * Exceptions:
171
     *   - InvalidRequestException : if there is any problem with the REST API request
172
     *   - AuthorizationException : if there is any problem with the REST API authorization(access token)
173
     *   - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
174
     *   - SmartsheetRestException : if there is any other REST API related error occurred during the operation
175
     *   - SmartsheetException : if there is any other error occurred during the operation
176
     *
177
     * @param email the list of email addresses
178
     * @param pagination the object containing the pagination query parameters
179
     * @param planId filtering all users part of the specific plan
180
     * @param seatType filter users by seat type
181
     * @return all users (note that empty list will be returned if there is none)
182
     * @throws SmartsheetException the smartsheet exception
183
     */
184
    @Override
185
    public PagedResult<User> listUsers(Set<String> email, Long planId,
186
                                       SeatType seatType, PaginationParameters pagination
187
                                       ) throws SmartsheetException {
188
        return this.listUsersInternal(email, null, planId, seatType, pagination);
1✔
189
    }
190

191
    /**
192
     * List all users with support for Seat Type and Plan ID. If planID or seatType is provided, then the response
193
     * will contain  planId, seatType, seatTypeLastChangedAt, isInternal, otherwise - not
194
     * <p>
195
     * It mirrors to the following Smartsheet REST API method: GET /users
196
     * <p>
197
     * Exceptions:
198
     *   - InvalidRequestException : if there is any problem with the REST API request
199
     *   - AuthorizationException : if there is any problem with the REST API authorization(access token)
200
     *   - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
201
     *   - SmartsheetRestException : if there is any other REST API related error occurred during the operation
202
     *   - SmartsheetException : if there is any other error occurred during the operation
203
     *
204
     * @param email the list of email addresses
205
     * @param includes elements to include in the response
206
     * @param pagination the object containing the pagination query parameters
207
     * @param planId filtering all users part of the specific plan
208
     * @param seatType filter users by seat type
209
     * @return all users (note that empty list will be returned if there is none)
210
     * @throws SmartsheetException the smartsheet exception
211
     */
212
    private PagedResult<User> listUsersInternal(Set<String> email, EnumSet<ListUserInclusion> includes,
213
                                                Long planId, SeatType seatType, PaginationParameters pagination
214
                                                ) throws SmartsheetException {
215
        String path = USERS;
1✔
216
        Map<String, Object> parameters = new HashMap<>();
1✔
217

218
        if (pagination != null) {
1✔
219
            parameters = pagination.toHashMap();
1✔
220
        }
221

222
        if (email != null) {
1✔
223
            parameters.put("email", QueryUtil.generateCommaSeparatedList(email));
1✔
224
        }
225

226
        if (includes != null) {
1✔
227
            parameters.put("include", QueryUtil.generateCommaSeparatedList(includes));
1✔
228
        }
229

230
        // Seat type support
231
        if (planId != null) {
1✔
232
            parameters.put("planId", planId);
1✔
233
        }
234

235
        if (seatType != null) {
1✔
236
            parameters.put("seatType", seatType);
1✔
237
        }
238

239
        path += QueryUtil.generateUrl(null, parameters);
1✔
240
        return this.listResourcesWithWrapper(path, User.class);
1✔
241
    }
242

243
    /**
244
     * Add a user to the organization, without sending email.
245
     * <p>
246
     * It mirrors to the following Smartsheet REST API method: POST /users
247
     * <p>
248
     * Exceptions:
249
     * - IllegalArgumentException : if any argument is null
250
     * - InvalidRequestException : if there is any problem with the REST API request
251
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
252
     * - ResourceNotFoundException : if the resource can not be found
253
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
254
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
255
     * - SmartsheetException : if there is any other error occurred during the operation
256
     *
257
     * @param user the user object limited to the following attributes: * admin * email * licensedSheetCreator
258
     * @return the user
259
     * @throws SmartsheetException the smartsheet exception
260
     */
261
    public User addUser(User user) throws SmartsheetException {
262
        return this.createResource(USERS, User.class, user);
1✔
263
    }
264

265
    /**
266
     * Add a user to the organization, without sending email.
267
     * <p>
268
     * It mirrors to the following Smartsheet REST API method: POST /users
269
     * <p>
270
     * Exceptions:
271
     * - IllegalArgumentException : if any argument is null
272
     * - InvalidRequestException : if there is any problem with the REST API request
273
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
274
     * - ResourceNotFoundException : if the resource can not be found
275
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
276
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
277
     * - SmartsheetException : if there is any other error occurred during the operation
278
     *
279
     * @param user      the created user
280
     * @param sendEmail whether to send email
281
     * @return the user object limited to the following attributes: * admin * email * licensedSheetCreator
282
     * @throws SmartsheetException the smartsheet exception
283
     */
284
    public User addUser(User user, boolean sendEmail) throws SmartsheetException {
285
        return this.createResource("users?sendEmail=" + sendEmail, User.class, user);
1✔
286
    }
287

288
    /**
289
     * Get the current user.
290
     * <p>
291
     * It mirrors to the following Smartsheet REST API method: GET /users/{userId}
292
     *
293
     * @param userId the user id
294
     * @return the user
295
     * @throws IllegalArgumentException    if any argument is null or empty string
296
     * @throws InvalidRequestException     if there is any problem with the REST API request
297
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
298
     * @throws ResourceNotFoundException   if the resource cannot be found
299
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
300
     * @throws SmartsheetException         if there is any other error during the operation
301
     */
302
    public UserProfile getUser(long userId) throws SmartsheetException {
303
        return this.getResource(USERS + "/" + userId, UserProfile.class);
1✔
304
    }
305

306
    /**
307
     * Get the current user.
308
     * <p>
309
     * It mirrors to the following Smartsheet REST API method: GET /users/me
310
     * <p>
311
     * Exceptions:
312
     * - InvalidRequestException : if there is any problem with the REST API request
313
     * - AuthorizationException : if there is any problem with the REST API authorization(access token)
314
     * - ResourceNotFoundException : if the resource can not be found
315
     * - ServiceUnavailableException : if the REST API service is not available (possibly due to rate limiting)
316
     * - SmartsheetRestException : if there is any other REST API related error occurred during the operation
317
     * - SmartsheetException : if there is any other error occurred during the operation
318
     *
319
     * @return the resource (note that if there is no such resource, this method will throw ResourceNotFoundException
320
     * rather than returning null).
321
     * @throws SmartsheetException the smartsheet exception
322
     */
323
    public UserProfile getCurrentUser() throws SmartsheetException {
324
        return this.getResource("users/me", UserProfile.class);
1✔
325
    }
326

327
    /**
328
     * <p>Get the current user.</p>
329
     *
330
     * <p>It mirrors to the following Smartsheet REST API method: GET /user/me</p>
331
     *
332
     * @param includes used to specify the optional objects to include.
333
     * @return the current user
334
     * @throws IllegalArgumentException    if any argument is null or empty string
335
     * @throws InvalidRequestException     if there is any problem with the REST API request
336
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
337
     * @throws ResourceNotFoundException   if the resource cannot be found
338
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
339
     * @throws SmartsheetException         if there is any other error during the operation
340
     */
341
    public UserProfile getCurrentUser(EnumSet<UserInclusion> includes) throws SmartsheetException {
342
        String path = "users/me";
1✔
343

344
        Map<String, Object> parameters = new HashMap<>();
1✔
345
        parameters.put("include", QueryUtil.generateCommaSeparatedList(includes));
1✔
346

347
        path += QueryUtil.generateUrl(null, parameters);
1✔
348
        return this.getResource(path, UserProfile.class);
1✔
349
    }
350

351
    /**
352
     * List all organisation sheets.
353
     * <p>
354
     * It mirrors to the following Smartsheet REST API method: GET /users/sheets
355
     *
356
     * @param pagination the object containing the pagination query parameters
357
     * @return the list of all organisation sheets
358
     * @throws IllegalArgumentException    if any argument is null or empty string
359
     * @throws InvalidRequestException     if there is any problem with the REST API request
360
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
361
     * @throws ResourceNotFoundException   if the resource cannot be found
362
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
363
     * @throws SmartsheetException         if there is any other error during the operation
364
     */
365
    public PagedResult<Sheet> listOrgSheets(PaginationParameters pagination, Date modifiedSince) throws SmartsheetException {
366
        String path = "users/sheets";
1✔
367

368
        Map<String, Object> parameters = new HashMap<>();
1✔
369
        if (pagination != null) {
1✔
370
            parameters = pagination.toHashMap();
1✔
371
        }
372
        if (modifiedSince != null) {
1✔
373
            String isoDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(modifiedSince);
×
374
            parameters.put("modifiedSince", isoDate);
×
375
        }
376
        path += QueryUtil.generateUrl(null, parameters);
1✔
377
        return this.listResourcesWithWrapper(path, Sheet.class);
1✔
378
    }
379

380
    public PagedResult<Sheet> listOrgSheets(PaginationParameters pagination) throws SmartsheetException {
381
        return this.listOrgSheets(pagination, null);
×
382
    }
383

384
    /**
385
     * List all user alternate emails.
386
     * <p>
387
     * It mirrors to the following Smartsheet REST API method: GET /users/{userId}/alternateemails
388
     *
389
     * @param userId     the id of the user
390
     * @param pagination the object containing the pagination query parameters
391
     * @return the list of all user alternate emails
392
     * @throws IllegalArgumentException    if any argument is null or empty string
393
     * @throws InvalidRequestException     if there is any problem with the REST API request
394
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
395
     * @throws ResourceNotFoundException   if the resource cannot be found
396
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
397
     * @throws SmartsheetException         if there is any other error during the operation
398
     */
399
    public PagedResult<AlternateEmail> listAlternateEmails(long userId, PaginationParameters pagination) throws SmartsheetException {
400
        String path = USERS + "/" + userId + "/" + ALTERNATE_EMAILS;
1✔
401

402
        if (pagination != null) {
1✔
403
            path += pagination.toQueryString();
1✔
404
        }
405
        return this.listResourcesWithWrapper(path, AlternateEmail.class);
1✔
406
    }
407

408
    /**
409
     * Get alternate email.
410
     * <p>
411
     * It mirrors to the following Smartsheet REST API method: GET /users/{userId}/alternateemails/{alternateEmailId}
412
     *
413
     * @param userId     the id of the user
414
     * @param altEmailId the alternate email id for the alternate email to retrieve.
415
     * @return the resource (note that if there is no such resource, this method will throw
416
     * ResourceNotFoundException rather than returning null).
417
     * @throws IllegalArgumentException    if any argument is null or empty string
418
     * @throws InvalidRequestException     if there is any problem with the REST API request
419
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
420
     * @throws ResourceNotFoundException   if the resource cannot be found
421
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
422
     * @throws SmartsheetException         if there is any other error during the operation
423
     */
424
    public AlternateEmail getAlternateEmail(long userId, long altEmailId) throws SmartsheetException {
425
        return this.getResource(USERS + "/" + userId + "/" + ALTERNATE_EMAILS + "/" + altEmailId, AlternateEmail.class);
1✔
426
    }
427

428
    /**
429
     * Add an alternate email.
430
     * <p>
431
     * It mirrors to the following Smartsheet REST API method: POST /users/{userId}/alternateemails
432
     *
433
     * @param userId    the id of the user
434
     * @param altEmails AlternateEmail alternate email address to add.
435
     * @return the resource (note that if there is no such resource, this method will throw
436
     * ResourceNotFoundException rather than returning null).
437
     * @throws IllegalArgumentException    if any argument is null or empty string
438
     * @throws InvalidRequestException     if there is any problem with the REST API request
439
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
440
     * @throws ResourceNotFoundException   if the resource cannot be found
441
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
442
     * @throws SmartsheetException         if there is any other error during the operation
443
     */
444
    public List<AlternateEmail> addAlternateEmail(long userId, List<AlternateEmail> altEmails) throws SmartsheetException {
445
        Util.throwIfNull(altEmails);
1✔
446
        if (altEmails.size() == 0) {
1✔
447
            return altEmails;
1✔
448
        }
449
        return this.postAndReceiveList(USERS + "/" + userId + "/" + ALTERNATE_EMAILS, altEmails, AlternateEmail.class);
1✔
450
    }
451

452
    /**
453
     * Delete an alternate email.
454
     * <p>
455
     * It mirrors to the following Smartsheet REST API method: DELETE /users/{userId}/alternateemails/{alternateEmailId}
456
     *
457
     * @param userId     the id of the user
458
     * @param altEmailId the alternate email id for the alternate email to retrieve.
459
     * @throws IllegalArgumentException    if any argument is null or empty string
460
     * @throws InvalidRequestException     if there is any problem with the REST API request
461
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
462
     * @throws ResourceNotFoundException   if the resource cannot be found
463
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
464
     * @throws SmartsheetException         if there is any other error during the operation
465
     */
466
    public void deleteAlternateEmail(long userId, long altEmailId) throws SmartsheetException {
467
        this.deleteResource(USERS + "/" + userId + "/" + ALTERNATE_EMAILS + "/" + altEmailId, AlternateEmail.class);
1✔
468
    }
1✔
469

470
    /**
471
     * Promote and alternate email to primary.
472
     *
473
     * @param userId     id of the user
474
     * @param altEmailId alternate email id
475
     * @return alternateEmail of the primary
476
     * @throws IllegalArgumentException    if any argument is null or empty string
477
     * @throws InvalidRequestException     if there is any problem with the REST API request
478
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
479
     * @throws ResourceNotFoundException   if the resource cannot be found
480
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
481
     * @throws SmartsheetException         f there is any other error during the operation
482
     */
483
    public AlternateEmail promoteAlternateEmail(long userId, long altEmailId) throws SmartsheetException {
484

485
        HttpRequest request = createHttpRequest(smartsheet.getBaseURI().resolve(
×
486
                USERS + "/" + userId + "/" + ALTERNATE_EMAILS + "/" + altEmailId + "/makeprimary"), HttpMethod.POST);
487

488
        Object obj = null;
×
489
        try {
490
            HttpResponse response = this.smartsheet.getHttpClient().request(request);
×
491
            switch (response.getStatusCode()) {
×
492
                case 200:
493
                    obj = this.smartsheet.getJsonSerializer().deserializeResult(AlternateEmail.class,
×
494
                            response.getEntity().getContent());
×
495
                    break;
×
496
                default:
497
                    handleError(response);
×
498
            }
499
        } finally {
500
            smartsheet.getHttpClient().releaseConnection();
×
501
        }
502

503
        return (AlternateEmail) obj;
×
504
    }
505

506
    /**
507
     * Uploads a profile image for the specified user.
508
     *
509
     * @param userId   id of the user
510
     * @param file     path to the image file
511
     * @param fileType content type of the image file
512
     * @return user
513
     * @throws IllegalArgumentException    if any argument is null or empty string
514
     * @throws InvalidRequestException     if there is any problem with the REST API request
515
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
516
     * @throws ResourceNotFoundException   if the resource cannot be found
517
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
518
     * @throws SmartsheetException         f there is any other error during the operation
519
     */
520
    public User addProfileImage(long userId, String file, String fileType) throws SmartsheetException, FileNotFoundException {
521
        return attachProfileImage(USERS + "/" + userId + "/profileimage", file, fileType);
×
522
    }
523

524
    private User attachProfileImage(String path, String file, String contentType) throws SmartsheetException, FileNotFoundException {
525
        Util.throwIfNull(file);
×
526

527
        if (contentType == null) {
×
528
            contentType = "application/octet-stream";
×
529
        }
530

531
        Map<String, Object> parameters = new HashMap<>();
×
532
        path += QueryUtil.generateUrl(null, parameters);
×
533

534
        HttpRequest request = createHttpRequest(this.smartsheet.getBaseURI().resolve(path), HttpMethod.POST);
×
535
        String attachmentHeaderValue = "attachment; filename=\"" + URLEncoder.encode(file, StandardCharsets.UTF_8) + "\"";
×
536
        request.getHeaders().put("Content-Disposition", attachmentHeaderValue);
×
537

538
        File f = new File(file);
×
539
        InputStream is = new FileInputStream(f);
×
540

541
        HttpEntity entity = new HttpEntity();
×
542
        entity.setContentType(contentType);
×
543
        entity.setContent(is);
×
544
        entity.setContentLength(f.length());
×
545
        request.setEntity(entity);
×
546

547
        User obj = null;
×
548
        try {
549
            HttpResponse response = this.smartsheet.getHttpClient().request(request);
×
550
            switch (response.getStatusCode()) {
×
551
                case 200:
552
                    obj = this.smartsheet.getJsonSerializer().deserializeResult(User.class,
×
553
                            response.getEntity().getContent()).getResult();
×
554
                    break;
×
555
                default:
556
                    handleError(response);
×
557
            }
558
        } finally {
559
            smartsheet.getHttpClient().releaseConnection();
×
560
        }
561

562
        return obj;
×
563
    }
564

565
    /**
566
     * <p>Update a user.</p>
567
     *
568
     * <p>It mirrors to the following Smartsheet REST API method: PUT /user/{id}</p>
569
     *
570
     * @param user the user to update
571
     * @return the updated user
572
     * @throws IllegalArgumentException    if any argument is null or empty string
573
     * @throws InvalidRequestException     if there is any problem with the REST API request
574
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
575
     * @throws ResourceNotFoundException   if the resource cannot be found
576
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
577
     * @throws SmartsheetException         if there is any other error during the operation
578
     */
579
    @Override
580
    public User updateUser(User user) throws SmartsheetException {
581
        return this.updateResource(USERS + "/" + user.getId(), User.class, user);
1✔
582
    }
583

584
    /**
585
     * <p>Fetch all user's plans.</p>
586
     *
587
     * <p>It mirrors to the following Smartsheet REST API method: GET /users/{userId}/plans</p>
588
     *
589
     * @param userId the id of the user whose plans to fetch
590
     * @param lastKey lastKey from previous response to get next page of results
591
     * @return UserPlansResponse json response
592
     * @throws IllegalArgumentException    if any argument is null or empty string
593
     * @throws InvalidRequestException     if there is any problem with the REST API request
594
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
595
     * @throws ResourceNotFoundException   if the resource cannot be found
596
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
597
     * @throws SmartsheetException         if there is any other error during the operation
598
     */
599
    @Override
600
    public TokenPaginatedResult<UserPlan> listUserPlans(long userId, String lastKey, Long maxItems) throws SmartsheetException {
601

602
        String path = USERS + "/" + userId + "/plans";
1✔
603
        Map<String, Object> parameters = new HashMap<>();
1✔
604

605
        if (lastKey != null) {
1✔
606
            parameters.put("lastKey", lastKey);
1✔
607
        }
608

609
        if (maxItems != null) {
1✔
610
            parameters.put("maxItems", maxItems);
1✔
611
        }
612
        path += QueryUtil.generateUrl(null, parameters);
1✔
613
        return this.listResourcesWithTokenPagination(path, UserPlan.class);
1✔
614
    }
615

616
    /**
617
     * <p>Remove's a user from a plan.</p>
618
     *
619
     * <p>It mirrors to the following Smartsheet REST API method: DELETE /2.0/users/{userId}/plans/{planId}</p>
620
     *
621
     * @param userId the id of the user whose plans to fetch
622
     * @param planId the id of the plan from which to remove the user
623
     * @throws IllegalArgumentException    if any argument is null or empty string
624
     * @throws InvalidRequestException     if there is any problem with the REST API request
625
     * @throws AuthorizationException      if there is any problem with  the REST API authorization (access token)
626
     * @throws ResourceNotFoundException   if the resource cannot be found
627
     * @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
628
     * @throws SmartsheetException         if there is any other error during the operation
629
     */
630
    @Override
631
    public void removeUserFromPlan(long userId, long planId) throws SmartsheetException {
632
        deleteResource(USERS + "/" + userId + PLANS + planId, Object.class);
1✔
633
    }
1✔
634

635
    /**
636
     * <p>Upgrades a user's seat type.</p>
637
     *
638
     * <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/plans/{planId}/upgrade</p>
639
     * @param userId the ID of the user to upgrade
640
     * @param planId the ID of the plan to upgrade to
641
     * @param seatType the new seat type for the user
642
     * @throws IllegalArgumentException if any argument is null or empty string
643
     * @throws InvalidRequestException if there is any problem with the REST API request
644
     * @throws AuthorizationException if there is any problem with the REST API authorization
645
     * @throws ResourceNotFoundException if the resource cannot be found
646
     * @throws ServiceUnavailableException if the REST API service is not available
647
     * @throws SmartsheetException if there is any other error during the operation
648
     */
649
    @Override
650
    public void upgradeUser(long userId, long planId, UpgradeSeatType seatType) throws SmartsheetException {
651
        changeSeatType(seatType.name(), USERS + "/" + userId + PLANS + planId + "/upgrade");
1✔
652
    }
1✔
653

654
    /**
655
     * <p>Downgrades a user's seat type.</p>
656
     *
657
     * <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/plans/{planId}/downgrade</p>
658
     * @param userId the ID of the user to downgrade
659
     * @param planId the ID of the plan to downgrade to
660
     * @param seatType the new seat type for the user
661
     * @throws IllegalArgumentException if any argument is null or empty string
662
     * @throws InvalidRequestException if there is any problem with the REST API request
663
     * @throws AuthorizationException if there is any problem with the REST API authorization
664
     * @throws ResourceNotFoundException if the resource cannot be found
665
     * @throws ServiceUnavailableException if the REST API service is not available
666
     * @throws SmartsheetException if there is any other error during the operation
667
     */
668
    @Override
669
    public void downgradeUser(long userId, long planId, DowngradeSeatType seatType) throws SmartsheetException {
670
        changeSeatType(seatType.name(), USERS + "/" + userId + PLANS + planId + "/downgrade");
1✔
671
    }
1✔
672

673
    private void changeSeatType(String seatType, String path) throws SmartsheetException {
674
        Util.throwIfNull(seatType);
1✔
675
        Map<String, String> body = Map.of("seatType", seatType);
1✔
676
        createResource(path, Result.class, body);
1✔
677
    }
1✔
678

679
    @Override
680
    public void deleteUser(long userId, DeleteUserParameters parameters) throws SmartsheetException {
681
        String path = USERS + "/" + userId;
1✔
682

683
        if (parameters != null) {
1✔
684
            path += parameters.toQueryString();
1✔
685
        }
686

687
        this.deleteResource(path, User.class);
1✔
688
    }
1✔
689
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc