001// Generated by delombok at Sun Apr 14 14:59:49 CEST 2024
002/*
003 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels.
004 *
005 * Permission is hereby granted, free of charge, to any person obtaining a copy
006 * of this software and associated documentation files (the "Software"), to deal
007 * in the Software without restriction, including without limitation the rights
008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009 * copies of the Software, and to permit persons to whom the Software is
010 * furnished to do so, subject to the following conditions:
011 *
012 * The above copyright notice and this permission notice shall be included in
013 * all copies or substantial portions of the Software.
014 *
015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021 * THE SOFTWARE.
022 */
023package com.restfb;
024
025import com.restfb.util.ReflectionUtils;
026import lombok.Setter;
027import java.util.Date;
028import java.util.List;
029import java.util.Map;
030import java.util.Optional;
031import static com.restfb.util.UrlUtils.extractParametersFromQueryString;
032import static java.lang.String.format;
033
034/**
035 * Represents an access token/expiration date pair.
036 * <p>
037 * Facebook returns these types when performing access token-related operations - see
038 * {@link FacebookClient#convertSessionKeysToAccessTokens(String, String, String...)},
039 * {@link FacebookClient#obtainAppAccessToken(String, String)}, and
040 * {@link FacebookClient#obtainExtendedAccessToken(String, String, String)} for details.
041 *
042 * @author <a href="http://restfb.com">Mark Allen</a>
043 */
044public class AccessToken {
045    /**
046     * The access token's value.
047     */
048    @Facebook("access_token")
049    private String accessToken;
050    @Facebook("expires_in")
051    private Long rawExpires;
052    /**
053     * The date on which the access token expires.
054     */
055    private Date expires;
056    /**
057     * The token type of this access token provided by Facebook
058     */
059    @Facebook("token_type")
060    private String tokenType;
061    private FacebookClient client;
062
063    public void setClient(FacebookClient client) {
064        this.client = client;
065    }
066
067    public FacebookClient getClient() {
068        return Optional.ofNullable(client).orElse(null);
069    }
070
071    /**
072     * Given a query string of the form {@code access_token=XXX} or {@code access_token=XXX&expires=YYY}, return an
073     * {@code AccessToken} instance.
074     * <p>
075     * The {@code queryString} is required to contain an {@code access_token} parameter with a non-{@code null} value.
076     * The {@code expires} value is optional and should be the number of seconds since the epoch. If the {@code expires}
077     * value cannot be parsed, the returned {@code AccessToken} will have a {@code null} {@code expires} value.
078     *
079     * @param queryString The Facebook query string out of which to parse an {@code AccessToken} instance.
080     * @return An {@code AccessToken} instance which corresponds to the given {@code queryString}.
081     * @throws IllegalArgumentException If no {@code access_token} parameter is present in the query string.
082     * @since 1.6.10
083     */
084    public static AccessToken fromQueryString(String queryString) {
085        // Query string can be of the form 'access_token=XXX' or
086        // 'access_token=XXX&expires=YYY'
087        Map<String, List<String>> urlParameters = extractParametersFromQueryString(queryString);
088        String extendedAccessToken = null;
089        String tokenType = null;
090        if (urlParameters.containsKey("access_token")) {
091            extendedAccessToken = urlParameters.get("access_token").get(0);
092        }
093        if (urlParameters.containsKey("token_type")) {
094            tokenType = urlParameters.get("token_type").get(0);
095        }
096        if (extendedAccessToken == null) {
097            throw new IllegalArgumentException(format("Was expecting a query string of the form \'access_token=XXX\' or \'access_token=XXX&expires=YYY\'. Instead, the query string was \'%s\'", queryString));
098        }
099        Date expires = null;
100        // If an expires or expires_in value was provided and it's a valid long, great - use it.
101        // Otherwise ignore it.
102        String rawExpires = null;
103        if (urlParameters.containsKey("expires")) {
104            rawExpires = urlParameters.get("expires").get(0);
105        }
106        if (urlParameters.containsKey("expires_in")) {
107            rawExpires = urlParameters.get("expires_in").get(0);
108        }
109        if (rawExpires != null && rawExpires.trim().matches("\\d+")) {
110            expires = new Date(new Date().getTime() + Long.parseLong(rawExpires) * 1000L);
111        }
112        AccessToken accessToken = new AccessToken();
113        accessToken.accessToken = extendedAccessToken;
114        accessToken.expires = expires;
115        accessToken.tokenType = tokenType;
116        return accessToken;
117    }
118
119    @Override
120    public int hashCode() {
121        return ReflectionUtils.hashCode(this);
122    }
123
124    @Override
125    public boolean equals(Object that) {
126        return ReflectionUtils.equals(this, that);
127    }
128
129    @Override
130    public String toString() {
131        return ReflectionUtils.toString(this);
132    }
133
134    @JsonMapper.JsonMappingCompleted
135    void convertExpires() {
136        if (rawExpires != null) {
137            expires = new Date(new Date().getTime() + 1000L * rawExpires);
138        }
139    }
140
141    /**
142     * The access token's value.
143     *
144     * @return The access token's value.
145     */
146    @java.lang.SuppressWarnings("all")
147    public String getAccessToken() {
148        return this.accessToken;
149    }
150
151    /**
152     * The date on which the access token expires.
153     *
154     * @return The date on which the access token expires.
155     */
156    @java.lang.SuppressWarnings("all")
157    public Date getExpires() {
158        return this.expires;
159    }
160
161    /**
162     * The token type of this access token provided by Facebook
163     *
164     * @return the access token type
165     */
166    @java.lang.SuppressWarnings("all")
167    public String getTokenType() {
168        return this.tokenType;
169    }
170}