|
3 | 3 | import com.google.gson.JsonArray;
|
4 | 4 | import org.apache.log4j.Logger;
|
5 | 5 | import org.jetbrains.annotations.NotNull;
|
| 6 | +import org.jetbrains.annotations.Nullable; |
6 | 7 | import xyz.gianlu.librespot.mercury.MercuryClient;
|
7 | 8 | import xyz.gianlu.librespot.mercury.MercuryRequests;
|
8 | 9 |
|
9 | 10 | import java.io.IOException;
|
| 11 | +import java.util.ArrayList; |
10 | 12 | import java.util.Arrays;
|
11 |
| -import java.util.HashMap; |
12 |
| -import java.util.Map; |
| 13 | +import java.util.List; |
| 14 | +import java.util.Objects; |
13 | 15 |
|
14 | 16 | /**
|
15 | 17 | * @author Gianlu
|
16 | 18 | */
|
17 |
| -public class TokenProvider { |
| 19 | +public final class TokenProvider { |
18 | 20 | private final static Logger LOGGER = Logger.getLogger(TokenProvider.class);
|
19 | 21 | private final static int TOKEN_EXPIRE_THRESHOLD = 10;
|
20 | 22 | private final Session session;
|
21 |
| - private final Map<String, StoredToken> tokens = new HashMap<>(); |
| 23 | + private final List<StoredToken> tokens = new ArrayList<>(); |
22 | 24 |
|
23 | 25 | TokenProvider(@NotNull Session session) {
|
24 | 26 | this.session = session;
|
25 | 27 | }
|
26 | 28 |
|
| 29 | + @Nullable |
| 30 | + private StoredToken findTokenWithAllScopes(String[] scopes) { |
| 31 | + for (StoredToken token : tokens) |
| 32 | + if (token.hasScopes(scopes)) |
| 33 | + return token; |
| 34 | + |
| 35 | + return null; |
| 36 | + } |
| 37 | + |
27 | 38 | @NotNull
|
28 |
| - public StoredToken getToken(@NotNull String scope) throws IOException, MercuryClient.MercuryException { |
29 |
| - if (scope.contains(",")) throw new UnsupportedOperationException("Only single scope tokens are supported."); |
| 39 | + public StoredToken getToken(@NotNull String... scopes) throws IOException, MercuryClient.MercuryException { |
| 40 | + if (scopes.length == 0) throw new IllegalArgumentException(); |
30 | 41 |
|
31 |
| - StoredToken token = tokens.get(scope); |
| 42 | + StoredToken token = findTokenWithAllScopes(scopes); |
32 | 43 | if (token != null) {
|
33 |
| - if (token.expired()) tokens.remove(scope); |
| 44 | + if (token.expired()) tokens.remove(token); |
34 | 45 | else return token;
|
35 | 46 | }
|
36 | 47 |
|
37 |
| - LOGGER.debug(String.format("Token expired or not suitable, requesting again. {scope: %s, oldToken: %s}", scope, token)); |
38 |
| - MercuryRequests.KeymasterToken resp = session.mercury().sendSync(MercuryRequests.requestToken(session.deviceId(), scope)); |
| 48 | + LOGGER.debug(String.format("Token expired or not suitable, requesting again. {scopes: %s, oldToken: %s}", Arrays.asList(scopes), token)); |
| 49 | + MercuryRequests.KeymasterToken resp = session.mercury().sendSync(MercuryRequests.requestToken(session.deviceId(), String.join(",", scopes))); |
39 | 50 | token = new StoredToken(resp);
|
40 | 51 |
|
41 |
| - LOGGER.debug(String.format("Updated token successfully! {scope: %s, newToken: %s}", scope, token)); |
| 52 | + LOGGER.debug(String.format("Updated token successfully! {scopes: %s, newToken: %s}", Arrays.asList(scopes), token)); |
| 53 | + tokens.add(token); |
42 | 54 |
|
43 |
| - tokens.put(scope, token); |
44 | 55 | return token;
|
45 | 56 | }
|
46 | 57 |
|
@@ -79,5 +90,21 @@ public String toString() {
|
79 | 90 | ", timestamp=" + timestamp +
|
80 | 91 | '}';
|
81 | 92 | }
|
| 93 | + |
| 94 | + public boolean hasScope(@NotNull String scope) { |
| 95 | + for (String s : scopes) |
| 96 | + if (Objects.equals(s, scope)) |
| 97 | + return true; |
| 98 | + |
| 99 | + return false; |
| 100 | + } |
| 101 | + |
| 102 | + public boolean hasScopes(String[] sc) { |
| 103 | + for (String s : sc) |
| 104 | + if (!hasScope(s)) |
| 105 | + return false; |
| 106 | + |
| 107 | + return true; |
| 108 | + } |
82 | 109 | }
|
83 | 110 | }
|
0 commit comments