XMPP server : Account created but attributes not getting saved - android

I am creating new user on ejabberd server.The user gets created.
In the code below user 918 got created but no attribute were saved.
ejabberd server has access rule is : [register, [{allow,all}]]
However, the attributes that i pass along with createAccount(), do not get saved on the ejabberd server.
libraries used - asmack-android-8-4.0.7, dnsjava-2.1.7.
XMPP server - ejabberd 2.1.11
Code is
ConnectionConfiguration config = new ConnectionConfiguration("myserver.co");
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
conn1 = new XMPPTCPConnection(config);
conn1.connect();
AccountManager accMan = AccountManager.getInstance(conn1);
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("phone", "237");
attributes.put("misc", "123");
accMan.createAccount("918", "hellopass", attributes);
conn1.login("918", "hellopass");
accMan = AccountManager.getInstance(conn1);
Log.d(TAG, "acc IMEI " + accMan.getAccountAttribute("misc")); // null returned here
Log.d(TAG, "acc phone " + accMan.getAccountAttribute("phone")); // null returned here
The last 2 lines of code posted above, return null value.
I do not know what am i missing to correctly create account with attributes too getting saved.
thanks
Vilpesh.

Attributes are not stored on the account but on the Vcard. When you register a user, you can only pass username and password.
For the user information, you should look into setting your Vcard.

Related

Gigya ids.setAccountInfo error Schema validation failed

i am trying to set account data
i use ids.setAccountInfo
GSObject param = new GSObject();
GSObject profile = new GSObject();
param.put("UID", user.getString("UID"));
profile.put("firstName", "FirstName");
param.put("profile", profile);
GSAPI.getInstance().sendRequest("ids.setAccountInfo", param, new GSResponseListener() {
#Override
public void onGSResponse(String s, GSResponse gsResponse, Object o) {
Log.d("ids.setAccountInfo", "----------------------------");
Log.d("ids.setAccountInfo", "s " + s);
Log.d("ids.setAccountInfo", "gsResponse " + gsResponse);
Log.d("ids.setAccountInfo", "----------------------------");
}
}, null);
and have response
errorCode:400006
errorMessage:Invalid parameter value
errorDetails:Schema validation failed
data:{"validationErrors":[{"message":"write access mode violation","fieldName":"profile.firstName","errorCode":400025}],"statusCode":400,"errorMessage":"Invalid parameter value","time":"2015-08-13T11:48:14.664Z","errorDetails":"Schema validation failed","statusReason":"Bad Request","errorCode":400006,"callId":"e0ed6aebea144323b095849ae3ed40ee"}
If I send empty profile or not send it then success
errorCode:0
errorMessage:null
errorDetails:null
data:{"statusCode":200,"errorCode":0,"time":"2015-08-13T11:53:19.738Z","callId":"e59b00cd09bf48a398586219f817930d","statusReason":"OK"}
Since the call to ids.setAccountInfo is done from a client side (presuming android SDK is used) while the profile schema for these fields write access is 'serverOnly' or 'clientCreate'. In order for this to work these fields needs to have the 'clientModify' write access.
Get the schema with ids.getSchema and look in fields write access.
It is possible to change that with a call to ids.setSchema, look in link for further details.
writeAccess - Specifies whether to allow unsigned requests to write into this field. This property applies when using the ids.getAccountInfo method, or when setting fields through the usage of a Screen-Set. The supported values are:
"serverOnly" (default) - Only signed requests coming from the server are allowed.
"clientCreate" - Unsigned requests coming from the client are allowed to write into this field, only if it wasn't set before.
"clientModify" - Unsigned requests coming from the client are allowed to write into this field and modify existing values.

protect http request using json (android)

I am using json request for logging in and displaying messages pertaining to the user .But if I make the same request from the browser it still works. I am using PHP-MYSQL for my App .
I do not have any website so I will need the answer for the app itself.
I am using facebook sdk with android app so I dont have any passwords. I would like to secure the chat msgs between the users and user data profile when it is called.Thats it.
My questions are:
How do I make sure the call is made within the app only?
How do I secure the call when some tries to copy and paste the code in the browser ?
3.Have timeout for the message created after 10 secs.So the same url and msg cannot be reused.
I have http call like http:/example.com/login=emailId;
get msgs: http:/example.com/getMsgs/user=uiniqueNo;
I have provided the above links as I am using in the app and its working fine but is not secure.
Please suggest me some documents and process.I have checked this link Protect HTTP request from being called by others but it was not clear .Please suggest me any tutorial which has the above requirements . Thanks in Advance.I really appreciate the help.
public class CustomizedListView extends Activity {
// All static variables
static final String URL = "http://example.com/getmsgs/userno=123";
// XML node keys
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
ListView list;
LazyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
JSONObject json = JSONfunctions.getJSONfromURL(URL);
try {
JSONObject arr2 = json.getJSONObject("feed");
JSONArray arr = arr2.getJSONArray("entry");
for (int i = 0; i < arr.length(); i++) {
JSONObject e1 = arr.getJSONObject(i);
JSONArray arr3 = e1.getJSONArray("im:image");
JSONObject arr8 = e1.getJSONObject("im:name");
JSONObject arr10 = e1.getJSONObject("im:artist");
JSONObject e12 = arr3.getJSONObject(0);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_THUMB_URL, e12.getString("label"));
map.put(KEY_ARTIST, arr8.getString("label"));
map.put(KEY_TITLE, arr10.getString("label"));
// adding HashList to ArrayList
songsList.add(map);
}
} catch (JSONException e) {
// Log.e("log_tag", "Error parsing data "+e.toString());
Toast.makeText(getBaseContext(),
"Network communication error!", 5).show();
}
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(this, songsList);
list.setAdapter(adapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#SuppressWarnings("unchecked")
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
HashMap<String, String> o = (HashMap<String, String>) list.getItemAtPosition(position);
Toast.makeText(CustomizedListView.this, "ID '" + o.get("KEY_TITLE") + "' was clicked.", Toast.LENGTH_SHORT).show();
}
});
}
}
In the above code anyone can guess usersno but how do I secure that no 123 in the app and in the php server .So that even if sniffer program is used and and reverse engineered to get code from apk file the data still is protect and encryption should be deep in OS which users cannot break and hence I can decrypt the code in server php and user will have no way to randomly type anything as 123.
<?php
$strno=$_GET['strno'];
if (isset($strno))
{
$connect=mysql_connect("localhost","test","test") or die ('Connection error!!!');
mysql_select_db("test") or die ('Database error!!!');
$query=mysql_query("select sno FROM users  where strno='$strno';");
while($row = mysql_fetch_assoc($query))
{
$jsonoutput='{"json":{
"msg_sub":"'.$row['msg_sub'].'",
}}';
}
}
echo trim($jsonoutput);
mysql_close($connect) or die ('Unable to close connection-error!!!');
}
?>
Ok there is no way to actually perfectly protect this system unless you use https to transmit data between your api and your js client.
This is what you do:
First create a user login system, username/password table on your database side
Next create a form for the user to login
Whenever a user tries to access the api your server will check if it has a session set for that user, they will either have to login or pass an existing session id which will grant them access
Next is to buy an https certificate that will ensure your data is transmitted securely
Now on each request to the api, the server always checks if they user has sent a valid SESSION ID, if not, it will simply redirect them to a login page
This is pretty much the only way you can add security to your system. The most important part is the https cert. Without this, it doesnt matter how good a user/password is, it can still be compromised.
EDIT
Here is some sample code to get you started. This code is not tested and its just there to give you an idea. You can read all about sessions here.
<?php
/*
like I said earlier, you need to have a "login" screen on your app
- when the user clicks login it POSTS the request back here
*/
if(isset($_SESSION['username'])){
//the username is in the session so it means
//theyre already logged in
//not sure what strno is doing but you can do that here
$strno=$_GET['strno'];
if (isset($strno))
{
$connect=mysql_connect("localhost","test","test") or die ('Connection error!!!');
mysql_select_db("test") or die ('Database error!!!');
$query=mysql_query("select sno FROM users where strno='$strno';");
while($row = mysql_fetch_assoc($query))
{
$jsonoutput='{"json":{
"msg_sub":"'.$row['msg_sub'].'",
}}';
}
}
echo trim($jsonoutput);
mysql_close($connect) or die ('Unable to close connection-error!!!');
}else if(isset($_POST) && isset($_POST['username']) && isset($_POST['password'])){
//log them in
//query ur database to see if the user exists
//if you get a row back then store that row in the session like
//note: this is just example code
if(/*user is in database, get the row....*/){
session_start();
$_SESSION['username'] = $row['username'];
}
}else{
die("Access Denied");
}
?>
There are two options to achieve this. First thing is using GET method, you can create a specific params on your server side which you are looking for. For example from your android app you are sending http://www.my-backend.com/api/test_api?my_secure_code=thisIsTestString and server returns the right response, but if you send http://www.my-backend.com/api/test_api?my_secure_code=thatsAnotherString , the param value you are searching for in the request is not thisIsTestString, so you should return error message.
In my opinion the second way to achieve this is better, because using GET is not thats ecure in my opinion.It's easier than using POST. In that case you will have to send my_secure_param as post param, which you can use by typing in your browser (there is still a way to achieve this by browser by installing plugin for post request). So I think the best solution here is to use POST request while connection to back-end sending some hashed string using MD5 or SHA1 (at least that's the way we are securing connection with our server + some more extras).
Edit: Regarding comments, the way you can achieve this is by creating some kind of identification for the specific user on your server, not trusting facebook. It's just a proposal...for example you can get the id user from facebook and create a unique hashed id which you will store in your server and everytime you are sending requests from your app, you have to send that unique id, which will be created in app in the same way used to create it on the server. And you will have to check for that hash everytime someone sends message if that match, if not just return error..and just don't forget, use POST requests instead of GET! There is no way to achieve something like this without changing some codes in your server's backend.

Paypal refund api gives error NO API ACCESS TO RECEIVER

I am using pre-approvals and delayed chained payment from adaptive payment api.
My test business account from which api is used is also the primary receiver account.
I get a paykey generated after using the preapproval to initiate the delayed payment. The money is received accurately in the primary receiver. My application now has a scenario where the money has to be refunded from primary receiver back to the purchaser. When tyring to execute this refund with the paykey and specifying the receiver and also settings the primary receiver flag, I receive an error NO_API_ACCESS_TO_RECEIVER.
This is blocking my app release and is a serious trouble. Could you please unblock me at earliest.
This is my code:
RefundRequest refundRequest = new RefundRequest();
refundRequest.setPayKey(payKey);
refundRequest.setCurrencyCode(KeyConstants.CURRENCY_USD_CODE);
refundRequest.setRequestEnvelope(ClientInfoUtil.getMyAppRequestEnvelope());
ReceiverList receiverList = new ReceiverList();
Receiver receiver = new Receiver();
receiver.setEmail(businessAccountPaypalEmail);
receiver.setPrimary(true);
double truncatedAmount = NumberUtil.getDoubleTruncate(amount, KeyConstants.TWO_DECIMAL_FORMAT);
BigDecimal trunBigDecimal = new BigDecimal(truncatedAmount);
receiver.setAmount(trunBigDecimal.setScale(2, RoundingMode.HALF_UP));
receiverList.getReceiver().add(receiver);
refundRequest.setReceiverList(receiverList);
try {
AdaptivePayments adaptivePayments = new AdaptivePayments();
RefundResponse refundResponse = adaptivePayments.refund(refundRequest);
ResponseEnvelope responseEnvelope = refundResponse.getResponseEnvelope();
AckCode ackCode = responseEnvelope.getAck();
if(ackCode == AckCode.SUCCESS || ackCode == AckCode.SUCCESS_WITH_WARNING){
Logger.getLogger(PayPalSessionBean.class.getName()).log(Level.INFO, "Refund success for the pay key {0} and messsage {1}",
new Object[]{payKey});
System.out.println("Ack code is " + ackCode);
RefundInfoList refundInfoList = refundResponse.getRefundInfoList();
List<RefundInfo> refundInfos = refundInfoList.getRefundInfo();
for (Iterator iterator = refundInfos.iterator(); iterator
.hasNext();) {
RefundInfo refundInfo = (RefundInfo) iterator.next();
System.out.println(refundInfo.getReceiver().getEmail() + "\t" + refundInfo.getRefundTransactionStatus() + "\t" +
refundInfo.getRefundGrossAmount() + '\t' + refundInfo.getRefundStatus() + '\t');
ErrorList errorList = refundInfo.getErrorList();
List<ErrorData> errs = errorList.getError();
for (Iterator iterator2 = errs.iterator(); iterator2
.hasNext();) {
ErrorData errorData = (ErrorData) iterator2.next();
System.out.println(errorData.getMessage());
}
}
return true;
}
In the above code snippet the ACk code returned is success, but when I print the refund status of the RefundInfo object, it says NO_API_ACCESS_TO_RECEIVER.
I have already given the permission to the api caller from the paypal panel of the primary account.
Is there something that is missing from my side? Please help me out!
If your just refunding from the Primary (yourself) back to the sender and you want to do a full refund, then you shouldn't need to specify any receivers. Otherwise I would need some type of PayKey or Correlation ID to look up the request on my side.
Got the answer myself. Sharing with you all
It was reading the paypal SDK client property file from Wrong location.
To avoid such kind of problems we should set the properties in the constructor of AdaptivePayments.
Below is the code for more illustration:
There is a session bean PropertyBean which has function getPayPalProperties() which reads all paypal properties from a property file.
Properties properties = propertyBeanLocal.getPayPalProperties();
AdaptivePayments adaptivePayments = new AdaptivePayments(properties);
And Instead of doing this
refundRequest.setRequestEnvelope(ClientInfoUtil.getMyAppRequestEnvelope());
do this.
RequestEnvelope requestEnvelope = new RequestEnvelope();
requestEnvelope.setErrorLanguage("en_us");
refundRequest.setRequestEnvelope(requestEnvelope);

How to send a tweet with jTwitter on Android?

Has anyone ever successfully sent a tweet via jTwitter on Android?
I am stuck with the Authentification. I can successfully redirect the user to twitter, authorize my app and redirect to my app with new OAuthSignpostClient(CONSUMER_KEY, CONSUMER_SECRET, CALLBACK_URL). Then I store the oauth_token and oauth_verifier which are given with the Callback URL and try to use the OAuthSignpostClient again to update a state:
OAuthSignpostClient client = new OAuthSignpostClient(TwitterOAuthActivity.CONSUMER_KEY, TwitterOAuthActivity.CONSUMER_SECRET, accessToken, accessTokenSecret);
// Ready to go!
Twitter twitter = new Twitter(null, client);
CharSequence date = DateFormat.format("dd.MM.yyyy # hh:mm:ss", new Date());
twitter.updateStatus("Yay. It works! " + date);
Which ends in a TwitterException without a caused by:
05-11 12:24:32.643: E/AndroidRuntime(25897): winterwell.jtwitter.TwitterException$E401: Could not authenticate with OAuth.
05-11 12:24:32.643: E/AndroidRuntime(25897): http://api.twitter.com/1/statuses/update.json (anonymous)
05-11 12:24:32.643: E/AndroidRuntime(25897): at winterwell.jtwitter.URLConnectionHttpClient.processError(URLConnectionHttpClient.java:425)
05-11 12:24:32.643: E/AndroidRuntime(25897): at winterwell.jtwitter.OAuthSignpostClient.post2_connect(OAuthSignpostClient.java:345)
Does anyone has an idea where my Problem is?
The verifier from the callback url is a temporary key. It let's you unlock the OAuthSignpostClient object that you have. You can't use it to construct a new OAuthSignpostClient.
You need to call:
client.setAuthorizationCode(verifier);
// The client can now be used!
// To use it again, without the oauth dance, store _these_ tokens:
String[] tokens = client.getAccessToken();
You may also want to check out the new AndroidTwitterLogin class which makes things easy:
AndroidTwitterLogin atl = new AndroidTwitterLogin(myApp,
MY_TWITTER_KEY,MY_TWITTER_SECRET,MY_TWITTER_CALLBACK) {
protected void onSuccess(Twitter jtwitter, String[] tokens) {
jtwitter.setStatus("I can now post to Twitter!");
// Recommended: store tokens in your app for future use
// with the constructor OAuthSignpostClient(String consumerKey, String consumerSecret, String accessToken, String accessTokenSecret)
}
};
atl.run();

JavaMail Message getHeader() bug

I am writing an Android GMail client application.
When it creates a message, I add a header to it like this:
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(username));
msg.setSubject(subject);
msg.setText(message);
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
long time = someTime;
msg.addHeader("My_Header", Long.toString(time));
//IMAPFolder f declaration & initialization
f.open(Folder.READ_WRITE);
f.addMessages(new Message[]{msg});
f.close(true);
It all works fine and I am able to see the header correctly added to the message when viewing my GMail account on my PC. However, when I later try to retrieve the header information, it gets very weird.
When I call
String[] str = msg.getHeader("My_Header");
getHeader() returns null if I am running the app. However, when I debug the app and set a breakpoint before the getHeader() call, it returns the header value corrently.
My source code:
MimeMessage msg = getNextMessage();
String subject = msg.getSubject();
InternetAddresses to[] = msg.getAllRecipients()
String when[] = msg.getHeader(GMailClient.TIME_TO_SEND);
if (when == null) {
Log.i(TAG, "Null Header");
} else {
long time = Long.parseLong(when[0]);
Log.i(TAG, "Value retrieved: " + when[0]);
}
Possibly Gmail isn't returning the header information correctly via IMAP? You might want to look at the protocol trace to see exactly what the server is returning for your request.
Also, try writing out the entire message using (e.g.)
msg.writeTo(new FileOutputStream("msg.txt"));
and see if the header is there. If it is, and the protocol trace shows that it's not being returned for the getHeader call, it's a bug in the server. In that case, see the JavaMail FAQ entry for how to work around such server bugs.

Categories

Resources