Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
OAuth2 refactoring: (#6341)
Browse files Browse the repository at this point in the history
Changes to OAuthFactoryImpl#createOAuthClientService:
- Instead of returning a handle the method required a handle (string). This because if a binding wants to use this method it should have a handle that is derived in the binding. If it were a random uuid the binding would need to store this string and that is not convenient. A typical handle could be the thing uid.
- The create checks if there the parameters are already stored and if so it will update the parameters in the storage. This makes it possible to update the parameters for example if the clientId would change this change makes it possible to update those values. With the previous implementation it was never possible to check if things like clientId were changed.
Other changes:
- Added a AccessTokenRefreshListener to let users of the service be able to get notifications of a change of the access token.
- OAuthClientServiceImpl#getAuthorizationUrl does not store scope in the persistedParams params because according to the spec this parameter can be a subset or null of the initial scope with which the service was authorized so it should not override the initial set here.
- Fixed javadoc warnings.

Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
  • Loading branch information
Hilbrand authored and kaikreuzer committed Oct 31, 2018
1 parent 44d41a9 commit 9776952
Show file tree
Hide file tree
Showing 15 changed files with 435 additions and 181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,63 @@ Simply deploy it to the runtime; then smarthome oauth commands will be registere
# Example 1: (Using authorization code)

## Try these on the OSGI console:

```
smarthome oauth Code cleanupEverything
smarthome oauth Code create
smarthome oauth Code getClient <fill in handle from create step>
smarthome oauth Code getAuthorizationUrl
### now open browser with the URL from above step, authenticate yourself
### to a real oauth provider
### if everything works properly, it should redirect you to your redirectURL
### Read the code http parameter from the redirectURL
```

```
now open browser with the URL from above step, authenticate yourself
to a real oauth provider
if everything works properly, it should redirect you to your redirectURL
Read the code http parameter from the redirectURL
```

```
smarthome oauth Code getAccessTokenByCode <code from redirectURL parameter>
smarthome oauth Code getCachedAccessToken
smarthome oauth Code refresh
smarthome oauth Code close

```

# Example 2: (Using ResourceOwner credentials i.e. you have the user's username and password directly)

## Try these on the OSGI console:

```
smarthome oauth ResourceOwner create
smarthome oauth ResourceOwner getClient <fill in handle from create step>
smarthome oauth ResourceOwner getAccessTokenByResourceOwnerPassword
smarthome oauth ResourceOwner getCachedAccessToken
smarthome oauth ResourceOwner refresh
smarthome oauth ResourceOwner close
```

### load again, similar to reboot/restart

```
smarthome oauth ResourceOwner getClient <fill in handle from create step>
smarthome oauth ResourceOwner getCachedAccessToken
smarthome oauth ResourceOwner refresh
```

### Done playing, delete this service permanently

```
smarthome oauth ResourceOwner delete <fill in handle from create step>
```

### Verify this is deleted (will throw exception)

```
smarthome oauth ResourceOwner getCachedAccessToken
```

### Cannot get the client after delete
smarthome oauth ResourceOwner getClient <fill in handle from create step>

```
smarthome oauth ResourceOwner getClient <fill in handle from create step>
```
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.io.IOException;
import java.util.Map;
import java.util.UUID;

import org.eclipse.smarthome.core.auth.client.oauth2.AccessTokenResponse;
import org.eclipse.smarthome.core.auth.client.oauth2.OAuthClientService;
Expand All @@ -31,33 +32,33 @@
*/
public abstract class AbstractTestAgent implements TestAgent {

protected String TOKEN_URL;
protected String CLIENT_ID;
private final Logger logger = LoggerFactory.getLogger(AbstractTestAgent.class);

protected String AUTH_URL;
protected String REDIRECT_URI;
public String handle;

protected String CLIENT_SECRET;
protected String USERNAME;
protected String PASSWORD;
protected String SCOPE;
protected String tokenUrl;
protected String clientId;

private static final Logger logger = LoggerFactory.getLogger(AbstractTestAgent.class);
protected String authUrl;
protected String redirectUri;

protected OAuthFactory oauthFactory;
protected String clientSecret;
protected String username;
protected String password;
protected String scope;

protected OAuthFactory oauthFactory;
protected OAuthClientService oauthClientService;
protected String handle;

public void activate(Map<String, Object> properties) {
TOKEN_URL = getProperty(properties, "TOKEN_URL");
CLIENT_ID = getProperty(properties, "CLIENT_ID");
AUTH_URL = getProperty(properties, "AUTH_URL");
REDIRECT_URI = getProperty(properties, "REDIRECT_URI");
CLIENT_SECRET = getProperty(properties, "CLIENT_SECRET");
USERNAME = getProperty(properties, "USERNAME");
PASSWORD = getProperty(properties, "PASSWORD");
SCOPE = getProperty(properties, "SCOPE");
tokenUrl = getProperty(properties, "TOKEN_URL");
clientId = getProperty(properties, "CLIENT_ID");
authUrl = getProperty(properties, "AUTH_URL");
redirectUri = getProperty(properties, "REDIRECT_URI");
clientSecret = getProperty(properties, "CLIENT_SECRET");
username = getProperty(properties, "USERNAME");
password = getProperty(properties, "PASSWORD");
scope = getProperty(properties, "SCOPE");
}

private static String getProperty(Map<String, Object> properties, String propKey) {
Expand Down Expand Up @@ -87,11 +88,13 @@ public void deactivate() {
}

@Override
public String testCreateClient() {
public OAuthClientService testCreateClient() {
logger.debug("test createClient");
handle = oauthFactory.createOAuthClientService(TOKEN_URL, AUTH_URL, CLIENT_ID, CLIENT_SECRET, SCOPE, false);
handle = UUID.randomUUID().toString();
OAuthClientService service = oauthFactory.createOAuthClientService(handle, tokenUrl, authUrl, clientId,
clientSecret, scope, false);
logger.info("new client handle: {}", handle);
return handle;
return service;
}

@Override
Expand Down Expand Up @@ -119,21 +122,21 @@ public AccessTokenResponse testGetAccessTokenByResourceOwnerPasswordCredentials(

if (handle == null) {
logger.debug("Creating new oauth service");
handle = oauthFactory.createOAuthClientService(TOKEN_URL, AUTH_URL, CLIENT_ID, CLIENT_SECRET, SCOPE, false);
oauthClientService = testCreateClient();
} else {
logger.debug("getting oauth client by handle: {}", handle);
oauthClientService = oauthFactory.getOAuthClientService(handle);
}
logger.debug("getting oauth client by handle: {}", handle);
oauthClientService = oauthFactory.getOAuthClientService(handle);

AccessTokenResponse accessTokenResponse = oauthClientService
.getAccessTokenByResourceOwnerPasswordCredentials(USERNAME, PASSWORD, SCOPE);
.getAccessTokenByResourceOwnerPasswordCredentials(username, password, scope);
logger.debug("Token: {}", accessTokenResponse);
return accessTokenResponse;
}

@Override
public AccessTokenResponse testGetAccessTokenByAuthorizationCode(String code)
throws OAuthException, IOException, OAuthResponseException {
return oauthClientService.getAccessTokenResponseByAuthorizationCode(code, REDIRECT_URI);
return oauthClientService.getAccessTokenResponseByAuthorizationCode(code, redirectUri);
}

@Override
Expand All @@ -153,7 +156,7 @@ public AccessTokenResponse testRefreshToken() throws OAuthException, IOException
@Override
public String testGetAuthorizationUrl(String state) throws OAuthException {
logger.debug("test getAuthorizationUrl {}", state);
String authorizationURL = oauthClientService.getAuthorizationUrl(REDIRECT_URI, SCOPE, state);
String authorizationURL = oauthClientService.getAuthorizationUrl(redirectUri, scope, state);
return authorizationURL;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
public interface TestAgent {

String testCreateClient();
OAuthClientService testCreateClient();

AccessTokenResponse testGetAccessTokenByResourceOwnerPasswordCredentials()
throws OAuthException, IOException, OAuthResponseException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
public class ConsoleOAuthCommandExtension extends AbstractConsoleCommandExtension implements ConsoleCommandExtension {

public ConsoleOAuthCommandExtension() {
super("oauth", "Test of oauth client with console. Available test agent: {Code, ResourceOwner}.\n"
super("oauth", "Test of oauth client with console. Available test agent: {Code, ResourceOwner}.\n"
+ "The commands in oauth requires oauth provider data to be inputted in configuration admin.");
}

Expand All @@ -67,8 +67,8 @@ public void execute(String[] args, Console console) {
try {
switch (args[1]) {
case "create":
String handle = agent.testCreateClient();
console.println("handle: " + handle);
OAuthClientService newService = agent.testCreateClient();
console.println("handle: " + agent.handle + ", service: " + newService);
break;
case "getAccessTokenByResourceOwnerPassword":
response = agent.testGetAccessTokenByResourceOwnerPasswordCredentials();
Expand Down
Loading

0 comments on commit 9776952

Please sign in to comment.