]> git.basschouten.com Git - openhab-addons.git/blob
c89678b9c8432079582bc4873769de332d6ee146
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.nest.internal.wwn.rest;
14
15 import java.io.IOException;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.openhab.binding.nest.internal.wwn.WWNBindingConstants;
19 import org.openhab.binding.nest.internal.wwn.WWNUtils;
20 import org.openhab.binding.nest.internal.wwn.config.WWNAccountConfiguration;
21 import org.openhab.binding.nest.internal.wwn.dto.WWNAccessTokenData;
22 import org.openhab.binding.nest.internal.wwn.exceptions.InvalidWWNAccessTokenException;
23 import org.openhab.core.io.net.http.HttpUtil;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Retrieves the WWN access token using the OAuth 2.0 protocol using pin-based authorization.
29  *
30  * @author David Bennett - Initial contribution
31  * @author Wouter Born - Improve exception handling
32  */
33 @NonNullByDefault
34 public class WWNAuthorizer {
35     private final Logger logger = LoggerFactory.getLogger(WWNAuthorizer.class);
36
37     private final WWNAccountConfiguration config;
38
39     /**
40      * Create the helper class for the Nest access token. Also creates the folder
41      * to put the access token data in if it does not already exist.
42      *
43      * @param config The configuration to use for the token
44      */
45     public WWNAuthorizer(WWNAccountConfiguration config) {
46         this.config = config;
47     }
48
49     /**
50      * Get the current access token, refreshing if needed.
51      *
52      * @throws InvalidWWNAccessTokenException thrown when the access token is invalid and could not be refreshed
53      */
54     public String getNewAccessToken() throws InvalidWWNAccessTokenException {
55         try {
56             String pincode = config.pincode;
57             if (pincode == null || pincode.isBlank()) {
58                 throw new InvalidWWNAccessTokenException("Pincode is empty");
59             }
60
61             StringBuilder urlBuilder = new StringBuilder(WWNBindingConstants.NEST_ACCESS_TOKEN_URL) //
62                     .append("?client_id=") //
63                     .append(config.productId) //
64                     .append("&client_secret=") //
65                     .append(config.productSecret) //
66                     .append("&code=") //
67                     .append(pincode) //
68                     .append("&grant_type=authorization_code");
69
70             logger.debug("Requesting access token from URL: {}", urlBuilder);
71
72             String responseContentAsString = HttpUtil.executeUrl("POST", urlBuilder.toString(), null, null,
73                     "application/x-www-form-urlencoded", 10_000);
74
75             WWNAccessTokenData data = WWNUtils.fromJson(responseContentAsString, WWNAccessTokenData.class);
76             logger.debug("Received: {}", data);
77
78             String accessToken = data.getAccessToken();
79             if (accessToken == null || accessToken.isBlank()) {
80                 throw new InvalidWWNAccessTokenException("Pincode to obtain access token is already used or invalid)");
81             }
82             return accessToken;
83         } catch (IOException e) {
84             throw new InvalidWWNAccessTokenException("Access token request failed", e);
85         }
86     }
87 }