001    package com.nimbusds.oauth2.sdk.token;
002    
003    
004    import net.minidev.json.JSONObject;
005    
006    import com.nimbusds.oauth2.sdk.ParseException;
007    import com.nimbusds.oauth2.sdk.Scope;
008    
009    
010    /**
011     * The base abstract class for access tokens.
012     *
013     * <p>Related specifications:
014     *
015     * <ul>
016     *     <li>OAuth 2.0 (RFC 6749), sections 1.4 and 5.1.
017     * </ul>
018     *
019     * @author Vladimir Dzhuvinov
020     * @version $version$ (2013-02-05)
021     */
022    public abstract class AccessToken 
023            extends Token
024            implements Comparable<AccessToken> {
025    
026            
027            /**
028             * The access token type.
029             */
030            private final AccessTokenType type;
031            
032            
033            /**
034             * Optional lifetime, in seconds.
035             */
036            private final long lifetime;
037            
038            
039            /**
040             * Optional scope.
041             */
042            private final Scope scope;
043    
044    
045            /**
046             * Creates a new minimal access token with a randomly generated value. 
047             * The value will be made up of 32 mixed-case alphanumeric ASCII 
048             * characters. The optional lifetime and scope are left undefined.
049             *
050             * @param type The access token type. Must not be {@code null}.
051             */
052            public AccessToken(final AccessTokenType type) {
053            
054                    this(type, 32);
055            }
056    
057    
058            /**
059             * Creates a new minimal access token with a randomly generated value
060             * of the specified length. The value will be made up of mixed-case 
061             * alphanumeric ASCII characters. The optional lifetime and scope are 
062             * left undefined.
063             *
064             * @param type   The access token type. Must not be {@code null}.
065             * @param length The number of characters. Must be a positive integer.
066             */
067            public AccessToken(final AccessTokenType type, final int length) {
068            
069                    this(type, length, 0l, null);
070            }
071    
072    
073            /**
074             * Creates a new access token with a randomly generated value and the 
075             * specified optional lifetime and scope. The value will be made up of
076             * 32 mixed-case alphanumeric ASCII characters.
077             *
078             * @param type     The access token type. Must not be {@code null}.
079             * @param lifetime The lifetime in seconds, 0 if not specified.
080             * @param scope    The scope, {@code null} if not specified.
081             */
082            public AccessToken(final AccessTokenType type,
083                               final long lifetime, 
084                               final Scope scope) {
085            
086                    this(type, 32, lifetime, scope);
087            }
088    
089    
090            /**
091             * Creates a new access token with a randomly generated value of the 
092             * specified length and optional lifetime and scope. The value will be 
093             * made up of mixed-case alphanumeric ASCII characters.
094             *
095             * @param type     The access token type. Must not be {@code null}.
096             * @param length   The number of characters. Must be a positive 
097             *                 integer.
098             * @param lifetime The lifetime in seconds, 0 if not specified.
099             * @param scope    The scope, {@code null} if not specified.
100             */
101            public AccessToken(final AccessTokenType type, 
102                               final int length, 
103                               final long lifetime, 
104                               final Scope scope) {
105            
106                    super(length);
107    
108                    if (type == null)
109                            throw new IllegalArgumentException("The access token type must not be null");
110    
111                    this.type = type;
112    
113                    this.lifetime = lifetime;
114                    this.scope = scope;
115            }
116            
117            
118            /**
119             * Creates a new minimal access token with the specified value. The 
120             * optional lifetime and scope are left undefined.
121             *
122             * @param type  The access token type. Must not be {@code null}.
123             * @param value The access token value. Must not be {@code null} or
124             *              empty string.
125             */
126            public AccessToken(final AccessTokenType type, final String value) {
127            
128                    this(type, value, 0l, null);
129            }
130            
131            
132            /**
133             * Creates a new access token with the specified value and optional 
134             * lifetime and scope.
135             *
136             * @param type     The access token type. Must not be {@code null}.
137             * @param value    The access token value. Must not be {@code null} or
138             *                 empty string.
139             * @param lifetime The lifetime in seconds, 0 if not specified.
140             * @param scope    The scope, {@code null} if not specified.
141             */
142            public AccessToken(final AccessTokenType type, 
143                               final String value, 
144                               final long lifetime, 
145                               final Scope scope) {
146            
147                    super(value);
148    
149                    if (type == null)
150                            throw new IllegalArgumentException("The access token type must not be null");
151    
152                    this.type = type;
153    
154                    this.lifetime = lifetime;
155                    this.scope = scope;
156            }
157    
158    
159            /**
160             * Gets the access token type.
161             *
162             * @return The access token type.
163             */
164            public AccessTokenType getType() {
165    
166                    return type;
167            }
168    
169            
170            /**
171             * Gets the lifetime of this access token.
172             *
173             * @return The lifetime in seconds, 0 if not specified.
174             */
175            public long getLifetime() {
176            
177                    return lifetime;
178            }
179            
180            
181            /**
182             * Gets the scope of this access token.
183             *
184             * @return The scope, {@code null} if not specified.
185             */
186            public Scope getScope() {
187            
188                    return scope;
189            }
190    
191    
192            @Override
193            public JSONObject toJSONObject() {
194    
195                    JSONObject o = new JSONObject();
196    
197                    o.put("access_token", getValue());
198                    o.put("token_type", type.toString());
199                    
200                    if (getLifetime() > 0)
201                            o.put("expires_in", lifetime);
202    
203                    if (getScope() != null)
204                            o.put("scope", scope.toString());
205                    
206                    return o;
207            }
208    
209    
210            @Override
211            public String toJSONString() {
212    
213                    return toJSONObject().toString();
214            }
215            
216            
217            /**
218             * Returns the {@code Authorization} HTTP request header value for this
219             * access token.
220             *
221             * @return The {@code Authorization} header value.
222             */
223            public abstract String toAuthorizationHeader();
224    
225    
226            @Override
227            public int compareTo(AccessToken other) {
228    
229                    return getValue().compareTo(other.getValue());
230            }
231    
232    
233            /**
234             * Parses an access token from a JSON object access token response.
235             * Only bearer access tokens are supported.
236             *
237             * @param jsonObject The JSON object to parse. Must not be 
238             *                   {@code null}.
239             *
240             * @return The access token.
241             *
242             * @throws ParseException If the JSON object couldn't be parsed to an
243             *                        access token.
244             */
245            public static AccessToken parse(final JSONObject jsonObject)
246                    throws ParseException {
247    
248                    return BearerAccessToken.parse(jsonObject);
249            }
250            
251            
252            /**
253             * Parses an {@code Authorization} HTTP request header value for an 
254             * access token. Only bearer access token are supported.
255             *
256             * @param header The {@code Authorization} header value to parse. Must 
257             *               not be {@code null}.
258             *
259             * @return The access token.
260             *
261             * @throws ParseException If the {@code Authorization} header value 
262             *                        couldn't be parsed to an access token.
263             */
264            public static AccessToken parse(final String header)
265                    throws ParseException {
266            
267                    return BearerAccessToken.parse(header);
268            }
269    }