make sure that users can't bypass easily the upload badge checks simply by tweaking dom values from firebug

git-svn-id: http://google-refine.googlecode.com/svn/trunk@556 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
Stefano Mazzocchi 2010-04-27 19:47:12 +00:00
parent b1375a8997
commit 5cd0301e57
4 changed files with 157 additions and 68 deletions

View File

@ -18,6 +18,7 @@ import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.commands.auth.AuthorizeCommand;
import com.metaweb.gridworks.commands.auth.CheckAuthorizationCommand;
import com.metaweb.gridworks.commands.auth.DeAuthorizeCommand;
import com.metaweb.gridworks.commands.auth.GetUserBadgesCommand;
import com.metaweb.gridworks.commands.edit.AddColumnCommand;
import com.metaweb.gridworks.commands.edit.AnnotateOneRowCommand;
import com.metaweb.gridworks.commands.edit.AnnotateRowsCommand;
@ -145,6 +146,7 @@ public class GridworksServlet extends HttpServlet {
_commands.put("check-authorization", new CheckAuthorizationCommand());
_commands.put("authorize", new AuthorizeCommand());
_commands.put("deauthorize", new DeAuthorizeCommand());
_commands.put("user-badges", new GetUserBadgesCommand());
_commands.put("upload-data", new UploadDataCommand());
_commands.put("mqlread", new MQLReadCommand());

View File

@ -0,0 +1,36 @@
package com.metaweb.gridworks.commands.auth;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.oauth.OAuthUtilities;
import com.metaweb.gridworks.oauth.Provider;
import com.metaweb.gridworks.util.FreebaseUtils;
public class GetUserBadgesCommand extends Command {
final static Logger logger = LoggerFactory.getLogger("check-authorization_command");
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Provider provider = OAuthUtilities.getProvider(request);
String user_id = request.getParameter("user_id");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "application/json");
String user_badges = FreebaseUtils.getUserBadges(provider, user_id);
response.getWriter().write(user_badges);
} catch (Exception e) {
logger.info("error",e);
respondException(response, e);
}
}
}

View File

@ -23,6 +23,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -75,6 +76,47 @@ public class FreebaseUtils {
return EntityUtils.toString(httpResponse.getEntity());
}
public static String getUserBadges(Provider provider, String user_id)
throws ClientProtocolException, IOException, JSONException {
String query = "{" +
"'id' : '" + user_id + "'," +
"'!/type/usergroup/member' : [{" +
"'id' : null," +
"'key' : [{" +
"'namespace' : null" +
"}]" +
"}]" +
"}".replace("'", "\"");
return mqlread(provider, query);
}
public static String mqlread(Provider provider, String query)
throws ClientProtocolException, IOException, JSONException {
JSONObject envelope = new JSONObject();
envelope.put("query", new JSONObject(query));
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("query", envelope.toString()));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost httpRequest = new HttpPost(getMQLReadURL(provider.getHost()));
httpRequest.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Gridworks " + Gridworks.getVersion());
httpRequest.setEntity(entity);
// this is required by the Metaweb API to avoid XSS
httpRequest.setHeader("X-Requested-With", "1");
// execute the request
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
// return the results
return EntityUtils.toString(httpResponse.getEntity());
}
public static String mqlwrite(Credentials credentials, Provider provider, String query)
throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException, JSONException {
OAuthConsumer consumer = OAuthUtilities.getConsumer(credentials, provider);
@ -104,31 +146,6 @@ public class FreebaseUtils {
return EntityUtils.toString(httpResponse.getEntity());
}
public static String mqlread(Provider provider, String query)
throws ClientProtocolException, IOException, JSONException {
JSONObject envelope = new JSONObject();
envelope.put("query", new JSONObject(query));
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("query", envelope.toString()));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost httpRequest = new HttpPost(getMQLReadURL(provider.getHost()));
httpRequest.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Gridworks " + Gridworks.getVersion());
httpRequest.setEntity(entity);
// this is required by the Metaweb API to avoid XSS
httpRequest.setHeader("X-Requested-With", "1");
// execute the request
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
// return the results
return EntityUtils.toString(httpResponse.getEntity());
}
public static String uploadTriples(HttpServletRequest request, String graph, String source_name, String source_id, String triples)
throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, JSONException, IOException {
@ -145,6 +162,10 @@ public class FreebaseUtils {
JSONObject user_info = new JSONObject(getUserInfo(credentials, provider));
if (user_info.has("username")) {
String user_id = user_info.getString("id");
boolean allowed = isAllowedToWrite(provider, graph, user_id);
if (allowed) {
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("user", user_info.getString("id")));
formparams.add(new BasicNameValuePair("action_type", "LOAD_TRIPLE"));
@ -179,8 +200,36 @@ public class FreebaseUtils {
// return the results
return EntityUtils.toString(httpResponse.getEntity());
} else {
throw new RuntimeException("User '" + user_id + "' is not allowed to write to '" + graph + "' with Gridworks");
}
} else {
throw new RuntimeException("Invalid credentials");
}
}
private static boolean isAllowedToWrite(Provider provider, String graph, String user_id) throws JSONException, ClientProtocolException, IOException {
if ("sandbox".equals(graph)) return true;
JSONObject user_badges = new JSONObject(getUserBadges(provider, user_id));
JSONObject result = user_badges.getJSONObject("result");
if (result == null) {
throw new RuntimeException("Error evaluating badges for user '" + user_id + "'");
}
boolean allowed = false;
JSONArray badges = result.getJSONArray("!/type/usergroup/member");
for (int i = 0; i < badges.length(); i++) {
JSONObject o = badges.getJSONObject(i);
String id = o.getString("id");
if ("/en/metaweb_staff".equals(id)) {
allowed = true;
break;
}
}
return allowed;
}
}

View File

@ -69,18 +69,20 @@ FreebaseLoadingDialog.prototype._createDialog = function() {
};
var check_allowed = function(user_id, cont) {
var mql_query = {
id : user_id,
"!/type/usergroup/member": [{
"id": "/en/metaweb_staff"
}]
};
$.post("/command/mqlread/" + provider,
{ "query" : JSON.stringify(mql_query) },
$.get("/command/user-badges/" + provider,
{ "user_id" : user_id },
function(data) {
if ("status" in data && data.code == "/api/status/ok") {
if (typeof cont == "function") cont((data.result != null));
var badges = data.result['!/type/usergroup/member'];
var allowed = false;
for (var i = 0; i < badges.length; i++) {
var id = badges[i].id;
if (id == "/en/metaweb_staff") {
allowed = true;
break;
}
}
if (typeof cont == "function") cont(allowed);
} else {
self._show_error("Error checking if user is a staff member", data);
}
@ -94,7 +96,7 @@ FreebaseLoadingDialog.prototype._createDialog = function() {
"create": "unless_exists",
"name": new_topic_id,
"a:type": topic_type,
"b:type": "/common/topic"
"b:type": "/common/topic",
"id": null,
"guid": null
}];
@ -204,7 +206,7 @@ FreebaseLoadingDialog.prototype._load = function() {
);
self._end();
} else {
self._show_error("Error loading data",error);
self._show_error("Error loading data",data);
}
},
"json"