I am not good at VBA programming (quite the basics), so I would like some of your input in the following matter as I couldn't find the correct answer for my concern. I would like to execute an API call with authentication using VBA. I have the below code but in Java (for test purposes), but my aim is to receive the responses in Excel. The idea is to login and fetch the records requested, and return it in form of XML or anything that would be readable ultimately in a wide Excel user form.
How to go about this? I do not need necessarily a-ready-code, any heads-up start would be appreciated.
package tests;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import com.tgmtSystems.core.util.XML_Utils;
public class TestQueryService
{
static String url = ".....";
static String ACCOUNT = "......";
static String USERNAME = ".....";
static String PASSWORD = "***********";
static String SERVICE = "queryservice.do";
static String QUERY_SEARCH_INSTANCE_ID = "14289081";
public static class ListResponse
{
String[ ] itemInstanceIds;
String projectInstanceId;
String templateInstanceId;
}
public static void main( String[ ] args )
throws Exception
{
String credentials = TestQueryService.login( );
ListResponse listResponse = listItems( credentials );
getItem( credentials, listResponse, listResponse.itemInstanceIds[ 0 ] );
//This will return the 10 first records identified by their Ids ( itemInstanceId )
getItems( credentials, listResponse, "11324721,11324744,11324745,11324746,11324748,11324751,11324758,11324829,11324830,11324836" );
//This will return All Ids, if there are more than 50, there will be an error, you can only fetch 50 at a time.
//getItems( credentials, listResponse, StringUtils.join( listResponse.itemInstanceIds, "," ) );
}
public static String login( )
throws Exception
{
String xmlRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST><action>login</action><accountName>" + ACCOUNT + "</accountName><username>" + USERNAME + "</username><password>" + PASSWORD + "</password></REQUEST>";
Document loginResponseDoc = sendRequest( xmlRequest );
String credentials = XML_Utils.getNodeValue( "credentials", loginResponseDoc );
return credentials;
}
public static ListResponse listItems( String credentials )
throws Exception
{
String xmlRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST><action>listItems</action><credentials>" + credentials + "</credentials><querySearchInstanceId>" + QUERY_SEARCH_INSTANCE_ID + "</querySearchInstanceId></REQUEST>";
Document responseDoc = sendRequest( xmlRequest );
ListResponse listResponse = new ListResponse( );
listResponse.itemInstanceIds = StringUtils.split( XML_Utils.getNodeValue( "itemInstanceIds", responseDoc ), "," );
listResponse.projectInstanceId = XML_Utils.getNodeValue( "projectInstanceId", responseDoc );
listResponse.templateInstanceId = XML_Utils.getNodeValue( "templateInstanceId", responseDoc );
return listResponse;
}
public static Document getItem( String credentials, ListResponse listResponse, String itemInstanceId )
throws Exception
{
String xmlRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST><action>getItem</action><credentials>" + credentials + "</credentials><templateInstanceId>" + listResponse.templateInstanceId + "</templateInstanceId><projectInstanceId>" + listResponse.projectInstanceId + "</projectInstanceId><itemInstanceId>" + itemInstanceId + "</itemInstanceId></REQUEST>";
return sendRequest( xmlRequest );
}
public static Document getItems( String credentials, ListResponse listResponse, String itemInstancesId )
throws Exception
{
String xmlRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><REQUEST><action>getItems</action><credentials>" + credentials + "</credentials><templateInstanceId>" + listResponse.templateInstanceId + "</templateInstanceId><projectInstanceId>" + listResponse.projectInstanceId + "</projectInstanceId><itemInstancesId>" + itemInstancesId + "</itemInstancesId></REQUEST>";
return sendRequest( xmlRequest );
}
public static Document sendRequest( String xmlRequest )
throws Exception
{
String type = "text/xml";
System.out.println( "REQUEST\n" + xmlRequest );
URL u = new URL( url + SERVICE );
HttpURLConnection conn = (HttpURLConnection) u.openConnection( );
conn.setDoOutput( true );
conn.setRequestMethod( "POST" );
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length", String.valueOf( xmlRequest.length( ) ) );
OutputStream os = conn.getOutputStream( );
os.write( xmlRequest.getBytes( ) );
StringBuilder stringBuilder = new StringBuilder( );
try
{
InputStream inputStream = conn.getInputStream( );
if ( inputStream != null )
{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( inputStream ) );
char[ ] charBuffer = new char[ 128 ];
int bytesRead = - 1;
while ( ( bytesRead = bufferedReader.read( charBuffer ) ) > 0 )
{
stringBuilder.append( charBuffer, 0, bytesRead );
}
bufferedReader.close( );
}
else
{
stringBuilder.append( "" );
}
}
catch ( Exception ex )
{
throw ex;
}
String responseXML = stringBuilder.toString( );
responseXML = responseXML.trim( );
System.out.println( "RESPONSE\n" + responseXML );
conn.disconnect( );
return XML_Utils.getDocument( responseXML );
}
}
Related
I need to get timestamp from a TSA in a Groovy script, in a SoapUI project. I try to use following script to get timestamp.
import org.bouncycastle.asn1.*
import org.bouncycastle.asn1.cmp.*
import org.bouncycastle.operator.*
import org.bouncycastle.tsp.*
import com.google.inject.AbstractModule
import com.google.inject.Provides
import com.google.inject.Inject
public interface TSAClient {
public byte[] getToken(byte[] imprint)
}
class TSAModule extends AbstractModule {
private String url
private String username
private String password
public TSAModule(String url, String username, String password) {
this.url = url
this.username = username
this.password = password
}
#Override
protected void configure() {
}
#Provides
TSAClient tsaClient() {
new TSAClientImpl(url, username, password)
}
}
public class TSAClientImpl implements TSAClient {
String tsaURL = "http://localhost:5050/timestamp"
String tsaUsername
String tsaPassword
public TSAClientImpl() {
}
public TSAClientImpl(String url, String username, String password) {
this.tsaURL = url
this.tsaUsername = username
this.tsaPassword = password
}
#Override
public byte[] getToken(byte[] imprint) {
byte[] respBytes = null
def algoFinder = new DefaultDigestAlgorithmIdentifierFinder()
def algoIdentifier = algoFinder.find("SHA-256")
// Setup the time stamp request
def tsqGenerator = new TimeStampRequestGenerator()
tsqGenerator.certReq = true
//tsqGenerator.reqPolicy = new ASN1ObjectIdentifier("1.3.6.1.4.1.13762.3")
def nonce = BigInteger.valueOf(System.currentTimeMillis())
def request = tsqGenerator.generate(algoIdentifier.objectId, imprint, nonce)
byte[] requestBytes = request.encoded
// Call the communications layer
respBytes = getTSAResponse(requestBytes)
// Handle the TSA response
def response = new TimeStampResponse(respBytes)
// validate communication level attributes (RFC 3161 PKIStatus)
response.validate(request)
def failure = response.failInfo
int value = (failure == null) ? 0 : failure.intValue()
if (value != 0) {
throw new IOException("TSA failure: ${value} (${response.statusString})")
}
// extract just the time stamp token (removes communication status info)
def tsToken = response.timeStampToken
if (tsToken == null) {
throw new IOException("TSA failed to return token: ${response.status} (${response.statusString})")
}
def tsTokenInfo = tsToken.timeStampInfo
byte[] encoded = tsToken.encoded
encoded
}
def getTSAResponse(byte[] requestBytes) {
// Setup the TSA connection
def tsaConnection = new URL(tsaURL).openConnection()
tsaConnection.doInput = true
tsaConnection.doOutput = true
tsaConnection.useCaches = false
tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query")
//tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64")
tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary")
if (tsaUsername != null && tsaUsername != "") {
String userPassword = tsaUsername + ":" + tsaPassword
tsaConnection.setRequestProperty("Authorization", "Basic " +
userPassword.bytes.encodeBase64().toString())
}
def out = tsaConnection.outputStream
out << requestBytes
out.close()
// Get TSA response as a byte array
def inp = tsaConnection.inputStream
def baos = new ByteArrayOutputStream()
baos << inp
byte[] respBytes = baos.toByteArray()
def encoding = tsaConnection.getContentEncoding()
if (encoding != null && encoding.equalsIgnoreCase("base64")) {
respBytes = new String(respBytes).decodeBase64()
}
respBytes
}
}
I imported bcprov-jdk15on-1.62.jar, bcpkix-jdk15on-1.62.jar, guice-4.2.2.jar and javax.inject-1.jar dependencies to SOAPUI_HOME/bin/ext folder.
I get following error message during execution:
java.lang.NoClassDefFoundError: Unable to load class
com.google.inject.AbstractModule due to missing dependency
[Lorg/aopalliance/intercept/MethodInterceptor;
Source of code: https://github.com/carohadad/seginf/tree/master/Sinapuli-service/src/main/groovy/garantito/sinapuli/tsa
Update:
I added all the needed dependency jar files, but got following error message:
groovy.lang.GroovyRuntimeException: Failed to create Script instance
for class: interface TSAClient. Reason:
java.lang.InstantiationException: TSAClient
Opening mail.box with ExtLibUtil.getCurrentSessionAsSigner does not work for mail.box.
All elements are signed with the same id.
I'd like to copy mails, created by Anonymous, to mail.box. Any ideas, workarounds?
package de.egvpb.surveys;
import java.io.Serializable;
import lotus.domino.Database;
import lotus.domino.Session;
import com.ibm.xsp.extlib.util.ExtLibUtil;
public class SessionAsSignerBean implements Serializable{
private static final long serialVersionUID = 1L;
private Database mailBoxDb ;
public SessionAsSignerBean(){
this.mailBoxDb = this.getMailBoxDbAsSigner() ;
}
private Database getMailBoxDbAsSigner() {
Session s = ExtLibUtil.getCurrentSessionAsSigner() ;
Database result = null ;
Database currentDb = null ;
String server = "" ;
String filepath = "" ;
try {
// Anonymous has reader access for currentDb; database is opend
currentDb = s.getCurrentDatabase() ;
if( currentDb.isOpen() ) {
System.out.println( "getMailBoxDbAsSigner, currentDB is open: " + currentDb.getFilePath() + " on " + currentDb.getServer() );
} else {
System.out.println( "getMailBoxDbAsSigner, currentDB is NOT open");
}
server = currentDb.getServer() ;
// Anonymous has no Access for names.nsf; database is opend
filepath = "names.nsf" ;
result = s.getDatabase(server, filepath) ;
if( result.isOpen() == false ) {
System.out.println( "getMailBoxDbAsSigner, failed to open database " + filepath + " on " + server );
} else {
System.out.println( "getMailBoxDbAsSigner, database opend " + filepath + " on " + server );
}
// Anonymous has no Access for mail.box; database is NOT opend
filepath = "mail.box" ;
result = s.getDatabase(server, filepath) ;
if( result.isOpen() == false ) {
System.out.println( "getMailBoxDbAsSigner, failed to open database " + filepath + " on " + server );
} else {
System.out.println( "getMailBoxDbAsSigner, opend database " + filepath + " on " + server );
}
} catch (Exception e) {
e.printStackTrace() ;
}
return result ;
}
// ====
public Database getMailBoxDb() {
return mailBoxDb;
}
public void setMailBoxDb(Database mailBoxDb) {
this.mailBoxDb = mailBoxDb;
}
}
I can't see anything wrong in your code, although for best practice I would recommend setting server to s.getServerName(), "" has different meanings for XPiNC.
Does your signer have access to mail.box? This should work and I've used such code before, amongst other places in XPages OpenLog Logger. If there are multiple mail.box databases set up, Domino will automatically still get the relevant one.
Recently i have started working on consuming wcf rest webservices in blackberry.
I have used the below two codes:
1.
URLEncodedPostData postData = new URLEncodedPostData(URLEncodedPostData.DEFAULT_CHARSET, false);
// passing q’s value and ie’s value
postData.append("UserName", "hsharma#seasiaconsulting.com");
postData.append("Password", "mind#123");
HttpPosst hh=new HttpPosst();
add(new LabelField("1"));
String res=hh.GetResponse("http://dotnetstg.seasiaconsulting.com/profire/ProfireService.svc/UserRegistration",postData);
add(new LabelField("2"));
add(new LabelField(res));
public String GetResponse(String url, URLEncodedPostData data)
{
this._postData = data;
this._url = url;
ConnectionFactory conFactory = new ConnectionFactory();
ConnectionDescriptor conDesc = null;
try
{
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
{
connectionString = ";interface=wifi";
}
// Is the carrier network the only way to connect?
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) {
// logMessage("Carrier coverage.");
// String carrierUid = getCarrierBIBSUid();
// Has carrier coverage, but not BIBS. So use the carrier's TCP
// network
// logMessage("No Uid");
connectionString = ";deviceside=true";
}
// Check for an MDS connection instead (BlackBerry Enterprise
// Server)
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
// logMessage("MDS coverage found");
connectionString = ";deviceside=false";
}
// If there is no connection available abort to avoid bugging the
// user
// unnecssarily.
else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE)
{
// logMessage("There is no available connection.");
}
// In theory, all bases are covered so this shouldn't be reachable.
else {
// logMessage("no other options found, assuming device.");
// connectionString = ";deviceside=true";
}
conDesc = conFactory.getConnection(url + connectionString);
}
catch (Exception e)
{
System.out.println(e.toString() + ":" + e.getMessage());
}
String response = ""; // this variable used for the server response
// if we can get the connection descriptor from ConnectionFactory
if (null != conDesc)
{
try
{
HttpConnection connection = (HttpConnection) conDesc.getConnection();
// set the header property
connection.setRequestMethod(HttpConnection.POST);
connection.setRequestProperty("Content-Length",Integer.toString(data.size()));
// body content of
// post data
connection.setRequestProperty("Connection", "close");
// close
// the
// connection
// after
// success
// sending
// request
// and
// receiving
// response
// from
// the
// server
connection.setRequestProperty("Content-Type","application/json");
// we set the
// content of
// this request
// as
// application/x-www-form-urlencoded,
// because the
// post data is
// encoded as
// form-urlencoded(if
// you print the
// post data
// string, it
// will be like
// this ->
// q=remoQte&ie=UTF-8).
// now it is time to write the post data into OutputStream
OutputStream out = connection.openOutputStream();
out.write(data.getBytes());
out.flush();
out.close();
int responseCode = connection.getResponseCode();
// when this
// code is
// called,
// the post
// data
// request
// will be
// send to
// server,
// and after
// that we
// can read
// the
// response
// from the
// server if
// the
// response
// code is
// 200 (HTTP
// OK).
if (responseCode == HttpConnection.HTTP_OK)
{
// read the response from the server, if the response is
// ascii character, you can use this following code,
// otherwise, you must use array of byte instead of String
InputStream in = connection.openInputStream();
StringBuffer buf = new StringBuffer();
int read = -1;
while ((read = in.read()) != -1)
buf.append((char) read);
response = buf.toString();
}
// don’t forget to close the connection
connection.close();
}
catch (Exception e)
{
System.out.println(e.toString() + ":" + e.getMessage());
}
}
return response;
}
public boolean checkResponse(String res)
{
if(!res.equals(""))
{
if(res.charAt(0)=='{')
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
but with this code i am unable to obtain response as what the above wcf web service return
which is({"UserRegistrationResult":[{"OutputCode":"2","OutputDescription":"UserName Already Exists."}]})
Can anybody help me regarding its parsing in blackberry client end.
2.And the another code which i used is:
public class KSoapDemo extends MainScreen
{
private EditField userNametxt;
private PasswordEditField passwordTxt;
private ButtonField loginBtn;
String Username;
String Password;
public KSoapDemo()
{
userNametxt = new EditField("User Name : ", "hsharma#seasiaconsulting.com");
passwordTxt = new PasswordEditField("Password : ", "mind#123");
loginBtn = new ButtonField("Login");
add(userNametxt);
add(passwordTxt);
add(loginBtn);
loginBtn.setChangeListener(new FieldChangeListener()
{
public void fieldChanged(Field field, int context)
{
//Dialog.alert("Hi Satyaseshu..!");
login();
}
});
}
private void login()
{
if (userNametxt.getTextLength() == 0 || passwordTxt.getTextLength() == 0)
{
//Dialog.alert("You must enter a username and password", );
}
else
{
String username = userNametxt.getText();
String password = passwordTxt.getText();
System.out.println("UserName... " + username);
System.out.println("Password... " + password);
boolean value = loginPArse1(username, password);
add(new LabelField("value... " + value));
}
}
public boolean onClose()
{
Dialog.alert("ADIOOO!!");
System.exit(0);
return true;
}
public boolean loginPArse1(String username, String password)
{
username=this.Username;
password=this.Password;
boolean ans = false;
String result = null;
SoapObject request = new SoapObject("http://dotnetstg.seasiaconsulting.com/","UserRegistration");
//request.addProperty("PowerValue","1000");
//request.addProperty("fromPowerUnit","kilowatts");
//request.addProperty("toPowerUnit","megawatts");
request.addProperty("userName",Username);
request.addProperty("Password", Password);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
envelope.dotNet = true;
add(new LabelField("value... " + "1"));
HttpTransport ht = new HttpTransport("http://dotnetstg.seasiaconsulting.com/profire/ProfireService.svc/UserRegistration"+ConnectionInfo.getInstance().getConnectionParameters());
ht.debug = true;
add(new LabelField("value... " + "2"));
//System.out.println("connectionType is: " + connectionType);
try {
ht.call("http://dotnetstg.seasiaconsulting.com/profire/ProfireService.svc/UserRegistration", envelope);
SoapObject body = (SoapObject) envelope.bodyIn;
add(new LabelField("soap....="+body.toString()));
add(new LabelField("property count....="+body.getPropertyCount()));
// add(new LabelField("Result....="+body.getProperty("HelloWorldResult")));
//result = body.getProperty("Params").toString();
// add(new LabelField("value... " + "4"));
ans=true;
}
catch (XmlPullParserException ex) {
add(new LabelField("ex1 "+ex.toString()) );
ex.printStackTrace();
} catch (IOException ex) {
add(new LabelField("ex1 "+ex.toString()) );
ex.printStackTrace();
} catch (Exception ex) {
add(new LabelField("ex1 "+ex.toString()) );
ex.printStackTrace();
}
return ans;
}
and in return i am obtain response as net.rim.device.cldc.io.dns.DNS Exception:DNS Error
Please help me in this regard
Thanks And Regards
Pinkesh Gupta
Please have the answer for my own question helps in parsing wcf rest services developed in .net and parsed at blackberry end.
This 2 classess definitely helps in achieving the above code parsing.
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
public class ConnectionThread extends Thread
{
private boolean start = false;
private boolean stop = false;
private String url;
private String data;
public boolean sendResult = false;
public boolean sending = false;
private String requestMode = HttpConnection.POST;
public String responseContent;
int ch;
public void run()
{
while (true)
{
if (start == false && stop == false)
{
try
{
sleep(200);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
else if (stop)
{
return;
}
else if (start)
{
http();
}
}
}
private void getResponseContent( HttpConnection conn ) throws IOException
{
InputStream is = null;
is = conn.openInputStream();
// Get the length and process the data
int len = (int) conn.getLength();
if ( len > 0 )
{
int actual = 0;
int bytesread = 0;
byte[] data = new byte[len];
while ( ( bytesread != len ) && ( actual != -1 ) )
{
actual = is.read( data, bytesread, len - bytesread );
bytesread += actual;
}
responseContent = new String (data);
}
else
{
// int ch;
while ( ( ch = is.read() ) != -1 )
{
}
}
}
private void http()
{
System.out.println( url );
HttpConnection conn = null;
OutputStream out = null;
int responseCode;
try
{
conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(requestMode);
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Length",Integer.toString(data.length()));
conn.setRequestProperty("Connection", "close");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("SOAPAction","http://dotnetstg.seasiaconsulting.com/");
out = conn.openOutputStream();
out.write(data.getBytes());
out.flush();
responseCode = conn.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK)
{
sendResult = false;
responseContent = null;
}
else
{
sendResult = true;
getResponseContent( conn );
}
start = false;
sending = false;
}
catch (IOException e)
{
start = false;
sendResult = false;
sending = false;
}
}
public void get(String url)
{
this.url = url;
this.data = "";
requestMode = HttpConnection.GET;
sendResult = false;
sending = true;
start = true;
}
public void post(String url, String data)
{
this.url = url;
this.data = data;
requestMode = HttpConnection.POST;
sendResult = false;
sending = true;
start = true;
}
public void stop()
{
stop = true;
}
}
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.component.AutoTextEditField;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.DateField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.Status;
import net.rim.device.api.ui.container.MainScreen;
import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;
import org.xml.sax.SAXException;
import net.rim.device.api.xml.parsers.SAXParser;
import net.rim.device.api.xml.jaxp.SAXParserImpl;
import org.xml.sax.helpers.DefaultHandler;
import java.io.ByteArrayInputStream;
import com.sts.example.ConnectionThread;
import com.sts.example.ResponseHandler;
public class DemoScreen extends MainScreen
{
private ConnectionThread connThread;
private BasicEditField response = new BasicEditField("Response: ", "");
private BasicEditField xmlResponse = new BasicEditField("xml: ", "");
private ButtonField sendButton = new ButtonField("Response");
public DemoScreen(ConnectionThread connThread)
{
this.connThread = connThread;
FieldListener sendListener = new FieldListener();
sendButton.setChangeListener(sendListener);
response.setEditable( false );
xmlResponse.setEditable( false );
add(sendButton);
add(response);
add(new SeparatorField());
add(xmlResponse);
}
public boolean onClose()
{
connThread.stop();
close();
return true;
}
private String getFieldData()
{
//{"UserName":"hsharma#seasiaconsulting.com","Password":"mind#123"}
StringBuffer sb = new StringBuffer();
sb.append("{\"UserNamepinkesh.g#cisinlabs.com\",\"Password\":\"pinkesh1985\"}");
return sb.toString();
}
class FieldListener implements FieldChangeListener
{
public void fieldChanged(Field field, int context)
{
StringBuffer sb = new StringBuffer("Sending...");
connThread.post("http://dotnetstg.seasiaconsulting.com/profire/ProfireService.svc/UserRegistration"+ConnectionInfo.getInstance().getConnectionParameters(), getFieldData());
while (connThread.sending)
{
try
{
Status.show( sb.append(".").toString() );
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
if (connThread.sendResult)
{
Status.show("Transmission Successfull");
xmlResponse.setText( connThread.responseContent );
try {
JSONObject jsonResponse = new JSONObject(connThread.responseContent);
JSONArray jsonArray = jsonResponse.getJSONArray("UserRegistrationResult");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject result = (JSONObject)jsonArray.get(i);
add(new LabelField("OutputCode"+result.getString("OutputCode")));
add(new LabelField("OutputDescription"+result.getString("OutputDescription")));
}
}
catch (JSONException e)
{
add(new LabelField(e.getMessage().toString()));
e.printStackTrace();
}
}
else
{
Status.show("Transmission Failed");
}
}
}
}
Using the Google Docs Java API with a Google Apps account, is it possible to impersonate a user and download a file?
When I run the program below, it is clearly logging on to the domain and impersonating the user because it retrieves the details of one of the files and prints out the file title. However, when it tries to download the file, a ServiceForbiddenException is thrown.
If it is not possible with the Java API, does anyone know if it is possible for my program to write an HTTP request to download the file using the Protocol API?
public class AuthExample {
private static DocsService docService = new DocsService("Auth Example");
public static void main(String[] args)
throws Exception
{
String adminUser = args[0];
String adminPassword = args[1];
String authToken = args[2];
String impersonatedUser = args[3];
loginToDomain(adminUser, adminPassword, authToken);
URL url = new URL( "https://docs.google.com/feeds/" + impersonatedUser + "/private/full" );
DocumentListFeed feed = docService.getFeed(url, DocumentListFeed.class);
DocumentListEntry entry = feed.getEntries().get(0);
String title = entry.getTitle().getPlainText();
System.out.println( title );
String type = entry.getType();
if ( type.equals("document") )
{
String encodedAdminUser = URLEncoder.encode(adminUser);
String resourceId = entry.getResourceId();
String resourceIdNoPrefix = resourceId.substring( resourceId.indexOf(':')+1 );
String downloadUrl =
"https://docs.google.com/feeds/download/documents/Export" +
"?xoauth_requestor=" + encodedAdminUser +
"&docId=" + resourceIdNoPrefix +
"&exportFormat=doc";
downloadFile( downloadUrl, title + ".doc" );
}
}
private static void loginToDomain(String adminUser, String adminPassword, String authToken)
throws OAuthException, AuthenticationException
{
String domain = adminUser.substring( adminUser.indexOf('#')+1 );
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(domain);
oauthParameters.setOAuthConsumerSecret(authToken);
oauthParameters.setOAuthType(OAuthType.TWO_LEGGED_OAUTH);
oauthParameters.setScope("https://docs.google.com/feeds/ http://spreadsheets.google.com/feeds/ http://docs.googleusercontent.com/");
docService.useSsl();
docService.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
docService.setUserCredentials(adminUser, adminPassword);
}
// Method pasted directly from Google documentation
public static void downloadFile(String exportUrl, String filepath)
throws IOException, MalformedURLException, ServiceException
{
System.out.println("Exporting document from: " + exportUrl);
MediaContent mc = new MediaContent();
mc.setUri(exportUrl);
MediaSource ms = docService.getMedia(mc);
InputStream inStream = null;
FileOutputStream outStream = null;
try {
inStream = ms.getInputStream();
outStream = new FileOutputStream(filepath);
int c;
while ((c = inStream.read()) != -1) {
outStream.write(c);
}
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}
}
}
Impersonation will work as intended if you use Oauth2 with ServiceAccounts
Do you guys see any issues with this C# code? It gets email notifications from gmail and then prints to CMD how many unread mails are waiting:
Unread Mails: 10
Unread Mails: 10
and then sends how many mails over serial too. But after it says "unread mails:" twice i get:
Operation Timed Out.
Unread Mails: 0
and it repeats.
Iv'e tried this on different computers and ISPs so its definitely something in the code.
The C# program. I also have tried changing the Thread.Sleep value so that it takes longer before it does it again, but still doesn't work.
Thanks!
public static void Main(string[] args)
{
try
{
SerialPort port = new SerialPort( "COM1", 9600, Parity.None, 8, StopBits.One );
port.Open();
string Unreadz = "0";
while ( true )
{
Unreadz = CheckMail();
Console.WriteLine("Unread Mails: " + Unreadz);
if (Convert.ToInt32(Unreadz) < 10) port.Write("0" + Unreadz);
else port.Write("" + Unreadz);
System.Threading.Thread.Sleep( 10000 );
}
} catch ( Exception ee ) { Console.WriteLine( ee.Message ); }
}
public static string TextToBase64( string sAscii )
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytes = encoding.GetBytes( sAscii );
return System.Convert.ToBase64String( bytes, 0, bytes.Length );
}
public static string CheckMail()
{
string result = "0";
try
{
var url = #"https://gmail.google.com/gmail/feed/atom";
var USER = "USER";
var PASS = "PASS";
var encoded = TextToBase64( USER + ":" + PASS );
var myWebRequest = HttpWebRequest.Create( url );
myWebRequest.Method = "POST";
myWebRequest.ContentLength = 0;
myWebRequest.Headers.Add( "Authorization", "Basic " + encoded );
var response = myWebRequest.GetResponse();
var stream = response.GetResponseStream();
XmlReader reader = XmlReader.Create( stream );
while ( reader.Read())
if ( reader.NodeType == XmlNodeType.Element )
if ( reader.Name == "fullcount" )
{
result = reader.ReadElementContentAsString();
return result;
}
} catch ( Exception ee ) { Console.WriteLine( ee.Message ); }
return result;
}
}
}
well i seemed to fix it. since i was just looping it every 10 seconds for testing, i put it to 5 minutes. 5 minutes is more realistic for my needs.