Skip to content

Commit

Permalink
Merge pull request #230 from telefonicaid/feature/225_add_cache_oauth…
Browse files Browse the repository at this point in the history
…2_hive_auth_provider

feature/225_add_cache_oauth2_hive_auth_provider
  • Loading branch information
fgalan committed Mar 2, 2017
2 parents 5360b01 + 4d2b869 commit 9a76c09
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- [cosmos-hive-auth-provider][hardening] Improve logs (#227)
- [cosmos-hive-auth-provider][feature] Add OAuth2 cache (#225)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
* Copyright 2016-2017 Telefonica Investigación y Desarrollo, S.A.U
*
* This file is part of fiware-cosmos (FI-WARE project).
*
Expand All @@ -17,6 +17,7 @@
*/
package com.telefonica.iot.cosmos.hive.authprovider;

import static com.telefonica.iot.cosmos.hive.authprovider.utils.Constants.CACHEBACKUPFILE;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
Expand All @@ -39,7 +40,8 @@
*/
public class OAuth2AuthenticationProviderImpl implements PasswdAuthenticationProvider {

private static final Logger LOGGER = Logger.getLogger(HttpClientFactory.class);
private static final Logger LOGGER = Logger.getLogger(OAuth2AuthenticationProviderImpl.class);
private static final OAuth2Cache CACHE = new OAuth2Cache(CACHEBACKUPFILE);
private final HttpClientFactory httpClientFactory;
private final String idmEndpoint;

Expand All @@ -52,7 +54,7 @@ public OAuth2AuthenticationProviderImpl() {

try {
conf = new HiveConf();
LOGGER.info("Hive configuration read");
LOGGER.debug("Hive configuration read");
} catch (Exception e) {
LOGGER.debug("Unable to read the Hive configuration, using default values");
} finally {
Expand Down Expand Up @@ -81,58 +83,76 @@ public OAuth2AuthenticationProviderImpl() {

@Override
public void Authenticate(String user, String token) throws AuthenticationException {
// create the Http client
// Check the cache
if (CACHE.isCached(user, token)) {
LOGGER.info("User and token were cached, thus nothing to query to IdM");
return;
} // if

LOGGER.info("User was not cached or token did not match, thus querying the IdM");

// Create the Http client
HttpClient httpClient = httpClientFactory.getHttpClient(true);

// create the request
// Create the request
String url = idmEndpoint + "/user?access_token=" + token;
HttpRequestBase request = new HttpGet(url);

// do the request
// Do the request
HttpResponse httpRes = null;

try {
httpRes = httpClient.execute(request);
LOGGER.debug("Doing request: " + request.toString());
} catch (IOException e) {
LOGGER.error("There was some problem when querying the IdM. Details: " + e.getMessage());
throw new AuthenticationException(e.getMessage());
} // try catch

// get the input streamResponse
// Get the input streamResponse
String streamResponse = "";

try {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpRes.getEntity().getContent()));
streamResponse = reader.readLine();
LOGGER.debug("Response received: " + streamResponse);
} catch (IOException e) {
LOGGER.error("There was some problem when getting the response from the IdM. Details: " + e.getMessage());
throw new AuthenticationException(e.getMessage());
} // try catch

// parse the input streamResponse as a Json
// Parse the input streamResponse as a Json
JSONObject jsonResponse = null;

try {
JSONParser jsonParser = new JSONParser();
jsonResponse = (JSONObject) jsonParser.parse(streamResponse);
} catch (ParseException e) {
LOGGER.error("There was some problem when parsing the response from the IdM. Details: " + e.getMessage());
throw new AuthenticationException(e.getMessage());
} // try catch

// check if the given token does not exist
// Check if the given token does not exist
if (jsonResponse.containsKey("error")) {
LOGGER.error("The give token does not exist in the IdM");
throw new AuthenticationException("The given token does not exist");
} // if

// check if the obtained user id matches the given user
// Check if the obtained user id matches the given user
if (jsonResponse.containsKey("id") && !jsonResponse.get("id").equals(user)) {
LOGGER.error("The given token does not match the given user");
throw new AuthenticationException("The given token does not match the given user");
} // if

// release the connection
// Release the connection
request.releaseConnection();

LOGGER.debug("User " + user + " authenticated");
// User authenticated
LOGGER.info("User " + user + " authenticated");

// Cache the user
CACHE.addToCache(user, token);
LOGGER.info("User cached");
} // Authenticate

} // OAuth2AuthenticationProviderImpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright 2017 Telefonica Investigación y Desarrollo, S.A.U
*
* This file is part of fiware-cosmos (FI-WARE project).
*
* fiware-cosmos is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
* fiware-cosmos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License along with fiware-cosmos. If not, see
* http://www.gnu.org/licenses/.
*
* For those usages not covered by the GNU Affero General Public License please contact with iot_support at tid dot es
*/
package com.telefonica.iot.cosmos.hive.authprovider;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Properties;
import org.apache.log4j.Logger;

/**
*
* @author frb
*/
public class OAuth2Cache {

private static final Logger LOGGER = Logger.getLogger(OAuth2Cache.class);
private final String cacheFile;
private final HashMap<String, String> cache;

/**
* Constructor.
* @param cacheFile
*/
public OAuth2Cache(String cacheFile) {
this.cacheFile = cacheFile;
cache = new HashMap<>();
loadCacheFromFile();
} // OAuth2Cache

/**
* Gets if the pair (user, token) is cached or not.
* @param user
* @param token
* @return True if the pair (user, token) is cached, otherwise false
*/
public boolean isCached(String user, String token) {
if (cache == null || cache.isEmpty()) {
return false;
} else {
String storedToken = cache.get(user);

if (storedToken == null) {
return false;
} else {
return token.equals(storedToken);
} // if else
} // if else
} // isCached

/**
* Adds the pais (user, token) to the cache.
* @param user
* @param token
*/
public void addToCache(String user, String token) {
cache.put(user, token);
saveCacheToFile();
} // addToCache

private void loadCacheFromFile() {
Properties props = new Properties();

try {
props.load(new FileInputStream(cacheFile));
} catch (FileNotFoundException e) {
LOGGER.error("Cache properties file not found when reading. Details: " + e.getMessage());
return;
} catch (IOException e) {
LOGGER.error("There was a problem while reading the cache properties file. Details: "
+ e.getMessage());
return;
} // try catch

for (String key : props.stringPropertyNames()) {
String value = props.getProperty(key);
cache.put(key, value);
} // for
} // loadCacheFromFile

private void saveCacheToFile() {
PrintWriter writer;

try {
writer = new PrintWriter(new FileOutputStream(cacheFile));
} catch (FileNotFoundException e) {
LOGGER.error("Cache properties file not found when saving. Details: " + e.getMessage());
return;
} // try catch

for (String key : cache.keySet()) {
String value = cache.get(key);
writer.println(key + "=" + value);
} // for

writer.flush();
writer.close();
} // saveCacheToFile

} // OAuth2Cache
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright 2017 Telefonica Investigación y Desarrollo, S.A.U
*
* This file is part of fiware-cosmos (FI-WARE project).
*
* fiware-cosmos is free software: you can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
* fiware-cosmos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License along with fiware-cosmos. If not, see
* http://www.gnu.org/licenses/.
*
* For those usages not covered by the GNU Affero General Public License please contact with iot_support at tid dot es
*/
package com.telefonica.iot.cosmos.hive.authprovider.utils;

/**
*
* @author frb
*/
public class Constants {

public static final String CACHEBACKUPFILE = "/home/hive/oauth2.cache";

} // Constants

0 comments on commit 9a76c09

Please sign in to comment.