Smack - get entry starts with specific letter - xmpp

I'm using Smack to build simple XMPP android client, I need to retrieve users only starts with letter "a" I've tried to use roster and UserSearchManager both need specific user id I couldn't use wild card for e.g.
UserSearch userSearch = new UserSearch();
answerForm.setAnswer("user", "a*");
or
RosterEntry entry = roster.getEntry("a*");
Any help?

This is a working snippet:
public static List<Row> searchOnServerForUsers(String searchString, XmppManager xmppManager) throws Exception
{
UserSearchManager usersearchManager = new UserSearchManager(abstractXMPPConnection.getConnection());
String searchServiceName = XmppConstants.USER_SERVICE_NAME_PREFIX + abstractXMPPConnection.getConnection().getServiceName();
Form form = usersearchManager.getSearchForm( searchServiceName );
Form answers = form.createAnswerForm();
answers.setAnswer("Name", false);
answers.setAnswer("Email", false);
answers.setAnswer("Username", true);
// answers.setAnswer("search", "*"); //search for all registered users
answers.setAnswer("search", "a*"); //your search string
ReportedData data = usersearchManager.getSearchResults(answers, searchServiceName);
List<Row> rows = data.getRows();
return rows;
}
So you have to use UserSearch,
on each column (like Username, pay attention to case!)
you have to set if search (true) or to not search (false)
your search string (in your usecase: "a*")

Don't use smack version 4.4.0 alpha1 it has some bugs. After reverting it to 4.1.1 . I got all the users. from UserSearchManager

Related

xamarin forms: Calling phone and sending email (IOS, Android and UWP)

Currently using following code for calling and email features, but it is only working in Android and not working in IOS. Also, I need these features in UWP.
For call:
string phoneno = "1234567890";
Device.OpenUri(new Uri("tel:" + phoneno));
For mail:
string email = "sreejithsree139#gmail.com";
Device.OpenUri(new Uri("mailto:" + email ));
Any package available for this?
Xamarin.Essentials (Nuget) is available as a preview package and contains functionality to both open the default mail app and attach information such as the recipients, subject and the body as well as open the phone dialer with a certain number.
There is also a blog post about Xamarin.Essentials available on blog.xamarin.com.
Edit:
As for your mail issue, Xamarin.Essentials expects an array of strings as recipients so you are able to send mail to multiple people at once. Just pass a string array with one single value.
var recipients = new string[1] {"me#watercod.es"};
If you're using the overload that expects an EmailMessage instance, you are supposed to pass a List of string objects.
In that case, the following should work:
var recipients = new List<string> {"me#watercod.es"};
Updating the complete code for calling and mailing features using Xamarin.Essentials, this might help others.
For call:
try
{
PhoneDialer.Open(number);
}
catch (ArgumentNullException anEx)
{
// Number was null or white space
}
catch (FeatureNotSupportedException ex)
{
// Phone Dialer is not supported on this device.
}
catch (Exception ex)
{
// Other error has occurred.
}
For Mail:
List<string> recipients = new List<string>();
string useremail = email.Text;
recipients.Add(useremail);
try
{
var message = new EmailMessage
{
//Subject = subject,
//Body = body,
To = recipients
//Cc = ccRecipients,
//Bcc = bccRecipients
};
await Email.ComposeAsync(message);
}
catch (Exception ex)
{
Debug.WriteLine("Exception:>>"+ex);
}
Hello to make a call in UWP:
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.ApplicationModel.Calls.PhoneCallManager"))
{
Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI("123", "name to call");
}
To send a Text:
private async void ComposeSms(Windows.ApplicationModel.Contacts.Contact recipient,
string messageBody,
StorageFile attachmentFile,
string mimeType)
{
var chatMessage = new Windows.ApplicationModel.Chat.ChatMessage();
chatMessage.Body = messageBody;
if (attachmentFile != null)
{
var stream = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(attachmentFile);
var attachment = new Windows.ApplicationModel.Chat.ChatMessageAttachment(
mimeType,
stream);
chatMessage.Attachments.Add(attachment);
}
var phone = recipient.Phones.FirstOrDefault<Windows.ApplicationModel.Contacts.ContactPhone>();
if (phone != null)
{
chatMessage.Recipients.Add(phone.Number);
}
await Windows.ApplicationModel.Chat.ChatMessageManager.ShowComposeSmsMessageAsync(chatMessage);
}
as found in Microsoft documentation here: Compose SMS documentation
==> So you can make (If not already done) a shared service interface in your Xamarin app, then the implementation with these codes in your UWP app...
To send an email:
To send an email in UWP, you can refer to the Microsoft documentation too:
Send Email documentation (UWP)
Using a plugin
Else you can use a Xamarin plugin:
documentation: Xamarin cross messaging plugin
Nuget: Nuget plugin package
In our app, we are doing the phone calling with a DependencyService.
Therefore in our PCL, we have
public interface IPhoneCall
{
void Call(string number);
}
On the iOS side, the following method does the calling:
public void Call(string number)
{
if (string.IsNullOrEmpty(number))
return;
var url = new NSUrl("tel:" + number);
if (!UIApplication.SharedApplication.OpenUrl(url))
{
var av = new UIAlertView("Error",
"Your device does not support calls",
null,
Keys.Messages.BUTTON_OK,
null);
av.Show();
}
}
If don't want to wait for the Xamarin essentials that is still in pre-release as of today, you can use this open source plugin. It works on iOS, Android and UWP. There is a sample from the github documentation :
// Make Phone Call
var phoneDialer = CrossMessaging.Current.PhoneDialer;
if (phoneDialer.CanMakePhoneCall)
phoneDialer.MakePhoneCall("+27219333000");
// Send Sms
var smsMessenger = CrossMessaging.Current.SmsMessenger;
if (smsMessenger.CanSendSms)
smsMessenger.SendSms("+27213894839493", "Well hello there from Xam.Messaging.Plugin");
var emailMessenger = CrossMessaging.Current.EmailMessenger;
if (emailMessenger.CanSendEmail)
{
// Send simple e-mail to single receiver without attachments, bcc, cc etc.
emailMessenger.SendEmail("to.plugins#xamarin.com", "Xamarin Messaging Plugin", "Well hello there from Xam.Messaging.Plugin");
// Alternatively use EmailBuilder fluent interface to construct more complex e-mail with multiple recipients, bcc, attachments etc.
var email = new EmailMessageBuilder()
.To("to.plugins#xamarin.com")
.Cc("cc.plugins#xamarin.com")
.Bcc(new[] { "bcc1.plugins#xamarin.com", "bcc2.plugins#xamarin.com" })
.Subject("Xamarin Messaging Plugin")
.Body("Well hello there from Xam.Messaging.Plugin")
.Build();
emailMessenger.SendEmail(email);
}

Get the real JID of user in a room

I have a code to discover room occupants like this :
public List<String> getRoomOccupants() {
List<String> occupants = new ArrayList<>();
DiscoverItems discoItems = null;
DiscoverItems.Item item = null;
try {
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
discoItems = discoManager.discoverItems(zipWhipNumber+"#"+roomService);
Iterator<DiscoverItems.Item> occupantsItems = discoItems.getItems().iterator();
while(occupantsItems.hasNext())
{
item = occupantsItems.next();
occupants.add(item.getName());
System.out.println(" EntityID : " + item.getEntityID() + "\n EntityName : " + item.getName());
}
} catch (NoResponseException | XMPPErrorException
| NotConnectedException e1) {
e1.printStackTrace();
}
return occupants;
}
But the EntityID is the name of the User in the room Not the full JID. So if the user by any chance changes the name to another nickname I won't be able to find his full JID.
Can anyone tell me how to get the full JID from the room ?
Thanks.
Discovery service must to be enabled to show such infos, and depends by implementations and and MultiUserChat configuration.
Probably you are not able to get this informations with a standard Discovery Operation.
You can try to pass through MultiUserChat item like this:
RoomInfo ri = MultiUserChatManager.getInstanceFor(connection).getRoomInfo("zipWhipNumber+"#"+roomService");
List<String> jidUsers = ri.getContactJids());
or like this:
MultiUserChat muc = MultiUserChatManager.getInstance().getMultiUserChat("zipWhipNumber+"#"+roomService");
List<String> jidUsers = muc.getOccupants();
*RoomInformation* it's more or less a DiscoveryService sized on MultiUserChat. Without right configuration, getContactJids() will return null.
*getOccupants()* of a MultiUserChat reply with a List of jids, but it's possible it sends a bad-request if user didn't previously joined the given *MultiUserChat*

Implement Custom Authentication In Windows Azure Mobile Services

Windows Azure Mobile Services currently doesn't have an option for custom authentication and looking at the feature request
http://feedback.azure.com/forums/216254-mobile-services/suggestions/3313778-custom-user-auth
It isn't coming anytime soon.
With a .NET backend and a .NET application how do you implement custom authentication, so that you don't have to use Facebook, Google or any of their other current providers?
There are plenty of partially completed tutorials on how this this is done with a JS backend and iOS and Android but where are the .NET examples?
I finally worked through the solution, with some help of the articles listed below, some intellisense and some trial and error.
How WAMS Works
First I wanted to describe what WAMS is in a very simple form as this part confused me for a while until it finally clicked. WAMS is just a collection of pre-existing technologies packaged up for rapid deployment. What you need to know for this scenario is:
As you can see WAMS is really just a container for a WebAPI and other things, which I won't go into detail here. When you create a new Mobile Service in Azure you get to download a project that contains the WebAPI. The example they use is the TodoItem, so you will see code for this scenario through the project.
Below is where you download this example from (I was just doing a Windows Phone 8 app)
I could go on further about this but this tutorial will get you started:
http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started/
Setup WAMS Project
You will need your MasterKey and ApplicationKey. You can get them from the Azure Portal, clicking on your Mobile Services App and pressing Manage Keys at the bottom
The project you just downloaded, in the Controllers folder I just created a new controller called AccountController.cs and inside I put
public HttpResponseMessage GetLogin(String username, String password)
{
String masterKey = "[enter your master key here]";
bool isValidated = true;
if (isValidated)
return new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent("{ 'UserId' : 'F907F58C-09FE-4F25-A26B-3248CD30F835', 'token' : '" + GetSecurityToken(new TimeSpan(1,0, 0), String.Empty, "F907F58C-09FE-4F25-A26B-3248CD30F835", masterKey) + "' }") };
else
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Username and password are incorrect");
}
private static string GetSecurityToken(TimeSpan periodBeforeExpires, string aud, string userId, string masterKey)
{
var now = DateTime.UtcNow;
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var payload = new
{
exp = (int)now.Add(periodBeforeExpires).Subtract(utc0).TotalSeconds,
iss = "urn:microsoft:windows-azure:zumo",
ver = 2,
aud = "urn:microsoft:windows-azure:zumo",
uid = userId
};
var keyBytes = Encoding.UTF8.GetBytes(masterKey + "JWTSig");
var segments = new List<string>();
//kid changed to a string
var header = new { alg = "HS256", typ = "JWT", kid = "0" };
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments.ToArray());
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
SHA256Managed hash = new SHA256Managed();
byte[] signingBytes = hash.ComputeHash(keyBytes);
var sha = new HMACSHA256(signingBytes);
byte[] signature = sha.ComputeHash(bytesToSign);
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
// from JWT spec
private static string Base64UrlEncode(byte[] input)
{
var output = Convert.ToBase64String(input);
output = output.Split('=')[0]; // Remove any trailing '='s
output = output.Replace('+', '-'); // 62nd char of encoding
output = output.Replace('/', '_'); // 63rd char of encoding
return output;
}
You can replace what is in GetLogin, with your own validation code. Once validated, it will return a security token (JWT) that is needed.
If you are testing on you localhost, remember to go into your web.config file and fill in the following keys
<add key="MS_MasterKey" value="Overridden by portal settings" />
<add key="MS_ApplicationKey" value="Overridden by portal settings" />
You need to enter in your Master and Application Keys here. They will be overridden when you upload them but they need to be entered if you are running everything locally.
At the top of the TodoItemController add the AuthorizeLevel attribute as shown below
[AuthorizeLevel(AuthorizationLevel.User)]
public class TodoItemController : TableController<TodoItem>
You will need to modify most of the functions in your TodoItemController but here is an example of the Get All function.
public IQueryable<TodoItem> GetAllTodoItems()
{
var currentUser = User as ServiceUser;
Guid id = new Guid(currentUser.Id);
return Query().Where(todo => todo.UserId == id);
}
Just a side note I am using UserId as Guid (uniqueidentifier) and you need to add this to the todo model definition. You can make the UserId as any type you want, e.g. Int32
Windows Phone/Store App
Please note that this is just an example and you should clean the code up in your main application once you have it working.
On your Client App
Install NuGet Package: Windows Azure Mobile Services
Go into App.xaml.cs and add this to the top
public static MobileServiceClient MobileService = new MobileServiceClient(
"http://localhost:50527/",
"[enter application key here]"
);
In the MainPage.xaml.cs I created
public class Token
{
public Guid UserId { get; set; }
public String token { get; set; }
}
In the main class add an Authenticate function
private bool Authenticate(String username, String password)
{
HttpClient client = new HttpClient();
// Enter your own localhost settings here
client.BaseAddress = new Uri("http://localhost:50527/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(String.Format("api/Account/Login?username={0}&password={1}", username, password)).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var token = Newtonsoft.Json.JsonConvert.DeserializeObject<Token>(response.Content.ReadAsStringAsync().Result);
App.MobileService.CurrentUser = new MobileServiceUser(token.UserId.ToString());
App.MobileService.CurrentUser.MobileServiceAuthenticationToken = token.token;
return true;
}
else
{
//Something has gone wrong, handle it here
return false;
}
}
Then in the Main_Loaded function
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Authenticate("test", "test");
RefreshTodoItems();
}
If you have break points in the WebAPI, you will see it come in, get the token, then come back to the ToDoItemController and the currentUser will be filled with the UserId and token.
You will need to create your own login page as with this method you can't use the automatically created one with the other identity providers. However I much prefer creating my own login screen anyway.
Any other questions let me know in the comments and I will help if I can.
Security Note
Remember to use SSL.
References
[] http://www.thejoyofcode.com/Exploring_custom_identity_in_Mobile_Services_Day_12_.aspx
[] http://www.contentmaster.com/azure/creating-a-jwt-token-to-access-windows-azure-mobile-services/
[] http://chrisrisner.com/Custom-Authentication-with-Azure-Mobile-Services-and-LensRocket
This is exactly how you do it. This man needs 10 stars and a 5 crates of beer!
One thing, I used the mobile Service LoginResult for login like:
var token = Newtonsoft.Json.JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
Hope to get this into Android now!

Quickbooks API V2 QBD - Looking for example of how to use RecordCountQuery

I am working in .NET, using the QuickBooks V2 API to try and fetch a count of the number of Items the user's QBD.
Does anyone have a working example of how to implement the "RecordCountQuery" class to find the # of Items in QBD?
Here is one of my attempt to do so:
//
// Get a record count of the items
//
var qbItemsCount = new RecordCountQuery();
var myResults = qbItemsCount.ExecuteQuery<Item>(_oQBIDataServices.ServiceContext);
Error:
Intuit.Ipp.Exception.IdsException was unhandled by user code
HResult=-2146233088
Message= The RecordCountQuery xml must wrap an existing supported query object. Please modify your query and try again.
Source=""
ErrorCode=-2015
I gather by this that I should be using an different type in the "ExecuteQuery" method like Intuit.Ipp.Data.QBD.ItemQuery. I tried this but got a different error.
So what I am asking for is not necessarily correction to the above code, but a WORKING EXAMPLE of the RecordCountQuery class in .NET.
Thank you.
Edit - Adding .net code
RecordCountQuery query = new RecordCountQuery();
CustomerQuery custQuery = new CustomerQuery();
query.Item1 = custQuery;
List<RecordCount> customerRecordCountQuery = query.ExecuteQuery<RecordCount>(context).ToList();
string customerCount = customerRecordCountQuery[0].Count;
I hv a working java code. Please check if it is useful.
API endpoint - https://services.intuit.com/sb/recordcount/v2/{*relam_id*}
POST body
<RecordCountQuery xmlns="http://www.intuit.com/sb/cdm/v2">
<CustomerQuery/>
</RecordCountQuery>
Response
<?xml version="1.0" encoding="UTF-8"?><!--XML GENERATED by IntuitDataSyncEngine (IDS) using \\SBDomainServices\CDM\branches\3.9.0-rel-1-->
<RestResponse xmlns="http://www.intuit.com/sb/cdm/v2"
xmlns:xdb ="http://xmlns.oracle.com/xdb"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation ="http://www.intuit.com/sb/cdm/v2 ../common/RestDataFilter.xsd"><RecordCounts>
<RecordCount>
<ObjectName>Customer</ObjectName>
<Count>392</Count>
</RecordCount>
</RecordCounts></RestResponse>
Java Code
public int testGetCount() {
int objectCount = 0;
try {
QBCustomerQuery CustomerQuery = QBObjectFactory.getQBObject(
context, QBCustomerQuery.class);
QBDRecordCountService iRecordCountSer = QBDServiceFactory
.getService(context, QBDRecordCountService.class);
List<QBRecordCountImpl> recordCounts = iRecordCountSer.getCount(
context, CustomerQuery);
Iterator<QBRecordCountImpl> iterator = recordCounts.iterator();
while (iterator.hasNext()) {
QBRecordCountImpl next = iterator.next();
objectCount = Integer.parseInt(next.getCount().toString());
}
System.out.println("Customer count - " + objectCount);
} catch (QBInvalidContextException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return objectCount;
}
Thanks

Facebook c# sdk get users email

I have a site which is using facebook for auth. I want to gather some basic info when a user signs up including their email address.
The code i have for the login is standard:
public ActionResult Login(string returnUrl)
{
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = AppSettings.GetConfigurationString("appId");
oAuthClient.RedirectUri = new Uri(AppSettings.GetConfigurationString("redirectUrl"));
var loginUri = oAuthClient.GetLoginUrl(new Dictionary<string, object> { { "state", returnUrl } });
return Redirect(loginUri.AbsoluteUri);
}
How do i add the request to access permissions in that? Or do i do it another way?
You need to use the email permission (the full list is here: http://developers.facebook.com/docs/authentication/permissions/ )
The way to add permissions to the authorization is by appending a comma separated list to &scope= , e.g.:
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream
Update: As you marked, the parameters are passed to the GetLoginUrl() method, although in the codeplex forum they also used ExchangeCodeForAccessToken(), which you might want to take a look at also.
A couple of examples using the C# SDK:
http://blog.prabir.me/post/Facebook-CSharp-SDK-Writing-your-first-Facebook-Application.aspx
Facebook .NET SDK: How to authenticate with ASP.NET MVC 2
http://facebooksdk.codeplex.com/discussions/244568
A snoop at the sdk code and i came up wiht:
public ActionResult Login(string returnUrl)
{
var oAuthClient = new FacebookOAuthClient();
oAuthClient.AppId = AppSettings.GetConfigurationString("appId");
oAuthClient.RedirectUri = new Uri(AppSettings.GetConfigurationString("redirectUrl"));
var parameters = new Dictionary<string, object>();
parameters["state"] = returnUrl;
parameters["scope"] = "email";
var loginUri = oAuthClient.GetLoginUrl(parameters);
return Redirect(loginUri.AbsoluteUri);
}
not tested it yet and the missus is shouting at me for working late so will have to test tomoz :)