How to check if an app has already been purchased - CodenameOne - codenameone

My application can buy an in-app product which I have configured on the google developer account.
The product is a buy-once product. I would like to know how to check if this item has already been bought (in codenameone) and handle it based on result of query.
Here is a code extract:
if(p.isManagedPaymentSupported()) {
if(p.wasPurchased(id)){
boolUpdate = true;
Form f = (Form)createContainer(resPath,"Search");
beforeSearch(f);
f.show();
}else{
Display.getInstance().callSerially(new Runnable() {
public void run() {
Boolean confirmAction = Dialog.show("Buy Product?","","Yes","No");
if(confirmAction){
p.purchase(id);
}
}
});
}
}
According to the codenameone API doc, The "p.wasPurchased(id)" method is supposed to provide this functionality. But this is not the case after installing on my device and making a purchase. The payment process begins again even after the product has been bought. Meaning the "wasPurchased()" check is returning false.
I would like to check if the item is already purchased and based on that either go to the next screen, or begin the purchase process. Please how can I implement this on codenameone?
Thanks

Currently managed purchases aren't supported on Android which I'm assuming is the platform you are referring to?
There is an RFE and some code to resolve it but we didn't get around to do it as of this writing: http://code.google.com/p/codenameone/issues/detail?id=731

Related

Codename One: Use Google Calendar

I'd like to access the Google Calendar of a user after Login, since I want to mirror certain labeled events in my Apps event class.
I guess the Google Calendar API Java Library can't be simply used here, so I was sent to this Library by the Codename One Support.
Does anyone have experience or Code examples for this Library?
How did you guys handle access to Google Calendar API if not with this library?
I did some of the initial work on that but haven't kept up with the changes done by the other authors so I can't say I have actual experience with this library...
From the code something like this should work:
DeviceCalendar dc = DeviceCalendar.getInstance();
if(!dc.hasPermissions()) {
// show message
return;
}
String calName = Preferences.get("selectedCalendar", null);
if(calName == null) {
Collection<String> calendarNames = dc.getCalendars()
calName = promptUserToPickCalendar(calendarNames);
if(calName == null) {
return;
}
Preferences.set("selectedCalendar", calName);
}
String calId = dc.openCalendar(calName, false);
Collection<EventInfo> events = dc.getEvents(calId, startDate, endDate);
// merge your events then use removeEvent/saveEvent respectively to apply your changes

How does JBehave work with Java?

I have a task for work that I can't seem to complete because I don't fully get the toolset at hand. I am supposed to use JBehave along with Selenium Web Driver to be able to add a certain book to a wishlist on an amazon account. I have a given story and I supposed to use the previously mentioned tools to be used for "learning purposes". I understand that JBehave is a framework for BDD. So, I have some sort of story that I want to test. However, what confuses me is the configuration and "step definition" part which I don't really get. My problem is I don't really understand how to get all those parts working together. Where does Selenium WebDriver fit in the equation? Note that I have used Selenium with Java and that was a breeze.
I want to give you an example of a story in gherkin format and I would appreciate any insights on this subject matter, maybe a clarification on how all the pieces fit together.
Given user <username> with password <password> has a valid amazon.com account
And has a wish list
And wants to purchase book <title> at a later date
When a request to place the book in the wish list is made
Then the book is placed in the wish list
And the book <title> appears in the wish list when <username> logs in at a later date.
Now that you have your Story you need your Steps. The steps are the Java code that will be executed by the story. Each line in your story gets mapped to a Java Step. See the documentation on Candidate Steps.
Here is a really simple stab at what your story and steps might look like. But it should at least give you an idea of how the stories and steps tie together.
Story
Given user username with password passcode is on product page url
When the user clicks add to wish list
Then the wish list page is displayed
And the product title appears on the wish list
Steps
public class WishlistSteps {
WebDriver driver = null;
#BeforeScenario
public void scenarioSetup() {
driver = new FirefoxDriver;
}
#Given("user $username with password $passcode is on product page $url")
public void loadProduct(String username, String passcode, String url) {
doUserLogin(driver, username, passcode); // defined elsewhere
driver.get(url);
}
#When("the user clicks add to wishlist")
public void addToWishlist() {
driver.findElement(By.class("addToWishlist")).click();
}
#Then("the wish list page is displayed")
public void isWishlistPage() {
assertTrue("Wishlist page", driver.getCurrentUrl().matches(".*/gp/registry/wishlist.*"));
}
#Then("the product $title appears on the wish list")
public void checkProduct(String title) {
// check product entries
// assert if product not found
}
#AfterScenario
public void afterScenario() {
driver.quit();
}
}
Next you will need a runner which actually finds and runs the stories. See the documentation on Running Stories. Below is a very simple runner that would run as a JUnit test.
Runner
public class JBehaveRunner extends JUnitStories {
public JBehaveRunner() {
super();
}
#Override
public injectableStepsFactory stepsFactory() {
return new InstanceStepsFactory( configuration(),
new WishlistSteps() );
}
#Override
protected List<String> storyPaths() {
return Arrays.asList("stories/Wishlist.story");
}
}
This runner would then be executed as a JUnit test. You can configure your IDE to run it, or use Maven or Gradle (depending on your setup).
mvn test
I have found that the pages below provide a great overview of the whole setup. And the examples from the JBhave repository are useful as well.
Automated Acceptance-Testing using JBehave
JBehave Configuration Tutorial
JBehave Examples

Authenticate user in WinForms (Nothing to do with ASP.Net)

Note: Cross-posted to ServerFault, based on comments.
Intro
I need to password protect some actions in my application, such as loading/saving files, clicking check-boxes, etc. This is a standard C# .Net 4.0, WinForms application which will run on Windows 7 in a corporate network.
I was about to roll my own very basic system (read obfuscation with wide open backdoors) with a text file of users/passwords/permissions (hashed and salted) until after some searching I found what looks like a
tantalizingly simple approach , but I'm having trouble finding a good tutorial on Roles that isn't about ASP.NET.
Question
So does anyone know of one or more tutorials that show me how to:
Create a Windows User/Group and give that User/Group a Role or Permission.
Note that I'm testing this from my company's networked laptop, but will deploy it on the customer's corporate network (Not sure if this is an issue, or how tricky this will get).
Create winforms/console app sample with even just a single method that prints "Hello World" if I'm authenticated or throws an exception if I'm not?
I've never done Network Admin or anything related and I keep reading about Active Directory and Local Users Vs Networked Users... I was hoping for an approach where I could build to an Interface and just ask Windows if the current user has permission ABC and not care too much about how Windows figured that out. Then I can make a concrete implementation for each Local/Network/ActiveDirectory/etc. use case as required (or if required... as I don't even know that right now).
Background
- read if interested, but not required to answer question
Just to make sure I'm going in the right direction here, basically I need/want to test this on my development PC to make sure it's going to have a good end-user experience for my customer. The problem is that currently they run an Auto-login script for each computer that runs my application and there are several different operators that use my application throughout the day. The customer wants password protection on certain features of my app and only provide that to certain operators. I have no problem fitting this in, as I've expected the request for a while, I just haven't ever programmed authentication before.
I think it's worthwhile to convince my customer to give each operator their own network account and assign whatever permissions they want to that operator or group, in case they need to fire somebody, change permissions, etc. It also means I just open several options for them and they can group those permissions however they see fit based on internal corporate policies, which I really shouldn't have to be worried about (but will be if I have to roll my own, as they're IT department knows almost nothing of my application).
From what I can tell it also makes my life a lot easier by not having to deal with hashing passwords and encryption, etc. and just handle which Role is required to click this or that button.
First of all, you'd have to determine, if you really want a simple role-based-authentication (you may want to read: http://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/)
If you're sure it's absolutely sufficient, you're already on the right way with the SO link you provided in your question. It's kind of confusing that there is no support of 'roles' by default in Windows, but there are groups. Groups can be local or remote (e.g. ActiveDirectory), so an admin could assign users to certain groups, that are specific for your application (for an example look here: http://msdn.microsoft.com/en-us/library/ms731200(v=vs.110).aspx)
One key is: You have to prepare your application's central principal, hence fill it with roles, supported for the current user.
Therefore, On the very startup of your application you then check the current active user and set your application wide principal and role(s). This may look like this (just a very simple example):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Security.Principal;
using System.Text;
using System.Threading;
namespace WindowsPrincipalTrial
{
public class Program
{
// you could also move these definitions to a config file
private static IDictionary<string, string> _groupRoleMappings = new Dictionary<string, string>()
{
{"MYAPPUSERGRP", MyRoles.Standard},
{"MYAPPSUPPORTGRP", MyRoles.Extended},
{"MYAPPADMINGRP", MyRoles.Admin},
};
private static void Main(string[] args)
{
var windowsId = WindowsIdentity.GetCurrent();
if (windowsId != null)
{
var allRoleNames = getGroupCorrespondingRoles(windowsId);
var newPrincipal = new GenericPrincipal(windowsId, allRoleNames);
Thread.CurrentPrincipal = newPrincipal;
}
else
{
throw new NotSupportedException("There must be a logged on Windows User.");
}
}
private static string[] getGroupCorrespondingRoles(WindowsIdentity id)
{
// you also could do this more elegant with LINQ
var allMappedRoleNames = new List<string>();
string roleName;
foreach (var grp in id.Groups)
{
var groupName = grp.Translate(typeof(NTAccount)).Value.ToUpper();
if (_groupRoleMappings.TryGetValue(groupName, out roleName))
{
allMappedRoleNames.Add(roleName);
}
}
return allMappedRoleNames.ToArray();
}
}
public static class MyRoles
{
public const string Standard = "standard_role";
public const string Extended = "extended_role";
public const string Admin = "admin_role";
}
}
Then your Application-Principal is set up.
Now you could check access in your code like this:
public void DoSomethingSpecial()
{
if (Thread.CurrentPrincipal.IsInRole(MyRoles.Extended))
{
// do your stuff
}
else
{
// maybe display an error
}
}
Or more drastically:
public void DoSomethingCritical()
{
var adminPermission = new PrincipalPermission(null, MyRoles.Admin);
adminPermission.Demand();
// do stuff
}
what is possible even declarative, as known from ASP.NET:
[PrincipalPermission(SecurityAction.Demand, Role=MyRoles.Admin)]
public void DoSomethingMoreCritical()
{
// do stuff
}
The ugly thing with the latter two examples is, that they throw exceptions, when the right role isn't hit.
So the mapping between roles and groups you have to do quite at the start of your app, according to the systems you want to use (local groups, AD groups, LDAP groups etc.).
If you, however, prefer authentication with actions and roles, after all, have a look at Windows Identity Foundation and Claims Based Authorization! There are already some ready-to-use frameworks out there (e.g. https://github.com/thinktecture/Thinktecture.IdentityModel).
UPDATE:
When it comes to activity based and thereby claims based authorization, I will try in short, how you could achieve it, by using Thinktecture's IdentityModel.
Generally that approach still uses roles internally, but has a kind of translation layer in between. Thinktecture already encapsulates many things needed. Authorization checks in code are then done via claim permissions. They are technically kind of request for an access to a certain resource. For the sake of simplicity I limit my example for actions only, by using one single default resource (since ClaimPermission doesn't accept an empty resource).
If you want to use action#resource pairs, you'd have to modify the code respectively.
At first you need a ClaimsAuthorizationManager
public class MyClaimsAuthorizationManager : ClaimsAuthorizationManager
{
private IActivityRoleMapper _actionToRolesMapper;
public MyClaimsAuthorizationManager(IActivityRoleMapper mapper)
{
_actionToRolesMapper = mapper;
}
public override bool CheckAccess(AuthorizationContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
var action = getActionNameFromAuthorizationContext(context);
var sufficientRoles = _actionToRolesMapper.GetRolesForAction(action)
.Select(roleName => roleName.ToUpper());
var principal = context.Principal;
return CheckAccessInternal(sufficientRoles, principal);
}
catch (Exception ex)
{
return false;
}
}
protected virtual bool CheckAccessInternal(IEnumerable<string> roleNamesInUpperCase, IClaimsPrincipal principal)
{
var result = principal.Identities.Any(identity =>
identity.Claims
.Where(claim => claim.ClaimType.Equals(identity.RoleClaimType))
.Select(roleClaim => roleClaim.Value.ToUpper())
.Any(roleName => roleNamesInUpperCase.Contains(roleName)));
return result;
}
// I'm ignoring resources here, modify this, if you need'em
private string getActionNameFromAuthorizationContext(AuthorizationContext context)
{
return context.Action
.Where(claim => claim.ClaimType.Equals(ClaimPermission.ActionType))
.Select(claim => claim.Value)
.FirstOrDefault();
}
}
As you may have guessed, IActivityRoleMapper is an interface for a class, that returns the names of all roles, that include permission for a given action.
This class is very individual and I guess you'll find your way implementing it, because it's not the point here. You could do it by hardcoding, loading from xml or from a database. Also you would have to change/extend it, if you wanted to you action#resource pairs for permission requests.
Then you'd have to change the code in main() method to:
using Thinktecture.IdentityModel;
using Thinktecture.IdentityModel.Claims;
using Microsoft.IdentityModel.Web;
private static void Main(string[] args)
{
var windowsId = WindowsIdentity.GetCurrent();
if (windowsId != null)
{
var rolesAsClaims = getGroupCorrespondingRoles(windowsId)
.Select(role => new Claim(ClaimTypes.Role, role))
.ToList();
// just if you want, remember the username
rolesAsClaims.Add(new Claim(ClaimTypes.Name, windowsId.Name));
var newId = new ClaimsIdentity(rolesAsClaims, null, ClaimTypes.Name, ClaimTypes.Role);
var newPrincipal = new ClaimsPrincipal(new ClaimsIdentity[] { newId });
AppDomain.CurrentDomain.SetThreadPrincipal(newPrincipal);
var roleMapper = new ActivityRoleMapper(); // you have to implement
// register your own authorization manager, so IdentityModel will use it per default
FederatedAuthentication.ServiceConfiguration.ClaimsAuthorizationManager = new MyClaimsAuthorizationManager(roleMapper);
}
else
{
throw new NotSupportedException("There must be a logged on Windows User.");
}
}
Finally you can check access this way:
public const string EmptyResource = "myapplication";
public void DoSomethingRestricted()
{
if (!ClaimPermission.CheckAccess("something_restricted", EmptyResource))
{
// error here
}
else
{
// do your really phat stuff here
}
}
Or again, with exceptions:
private static ClaimPermission RestrictedActionPermission = new ClaimPermission(EmptyResource, "something_restricted");
public void DoSomethingRestrictedDemand()
{
RestrictedActionPermission.Demand();
// play up, from here!
}
Declarative:
[ClaimPermission(SecurityAction.Demand, Operation = "something_restricted", Resource = EmptyResource)]
public void DoSomethingRestrictedDemand2()
{
// dostuff
}
Hope this helps.

Silverlight4 calling ASMX web service

I have a Visual Studio solution with a Silverlight project, and a web project which hosts the Silverlight app. The web project also contains an ASMX web service which is called by the Silverlight ap.
As described below, certain calls to the web service work fine, and yet others cause a CommunicationException to be thrown, wrapping a WebException - both with the message "The server returned the following error: 'not found'".
Firstly, here's my original method, which failed as described above (entity names changed for simplicity):
[WebMethod]
public Customer GetCustomer(int id)
{
CustomerDataContext dc = new CustomerDataContext();
return dc.Customers.SingleOrDefault(x => x.Id == id);
}
Secondly, to debug the problem I took Linq to SQL and the database out of the picture, and the below code worked fine:
[WebMethod]
public Customer GetCustomer(int id)
{
Customer c = new Customer() { ID=1, Name="Bob", History = new EntitySet<CustomerHistory>() };
return c;
}
Third, thinking about this, one difference between the two methods is that the first one would include values in the customer history. I extended the second method to include this, and it started failing again:
[WebMethod]
public Customer GetCustomer(int id)
{
Customer c = new Customer() { ID=1, Name="Bob", History = new EntitySet<CustomerHistory>() };
c.History.Add(new CustomerHistory() { Id=1, CustomerId=1, Text="bla" });
return c;
}
I'm stuck with regards to how to progress - my current thinking is that this could be a deserialization issue on the Silverlight side, when the object graph is deeper. This rationally doesn't make sense, but I can't think of anything else. I've confirmed that the transfer size and buffer size are big enough (2GB by default).
Any pointers would be appreciated.
Ahhhh the famous "Not Found" error, try to get details from that error using the tag in your web.config. That will create a log file providing details of the error.
The following link explains exaclty how to do it :
http://blogs.runatserver.com/lppinson/post/2010/04/15/Debugging-WCF-Web-Services.aspx

Provide a database packaged with the .APK file or host it separately on a website?

Here is some background about my app:
I am developing an Android app that will display a random quote or verse to the user. For this I am using an SQLite database. The size of the DB would be approximately 5K to 10K records, possibly increasing to upto 1M in later versions as new quotes and verses are added. Thus the user would need to update the DB as and when newer versions are of the app or DB are released.
After reading through some forums online, there seem to be two feasible ways I could provide the DB:
1. Bundle it along with the .APK file of the app, or
2. Upload it to my app's website from where users will have to download it
I want to know which method would be better (if there is yet another approach other than these, please do let me know).
After pondering this problem for some time, I have these thoughts regarding the above approaches:
Approach 1:
Users will obtain the DB along with the app, and won't have to download it separately. Installation would thereby be easier. But, users will have to reinstall the app every time there is a new version of the DB. Also, if the DB is large, it will make the installable too cumbersome.
Approach 2:
Users will have to download the full DB from the website (although I can provide a small, sample version of the DB via Approach 1). But, the installer will be simpler and smaller in size. Also, I would be able to provide future versions of the DB easily for those who might not want newer versions of the app.
Could you please tell me from a technical and an administrative standpoint which approach would be the better one and why?
If there is a third or fourth approach better than either of these, please let me know.
Thank you!
Andruid
I built a similar app for Android which gets periodic updates with data from a government agency. It's fairly easy to build an Android compatible db off the device using perl or similar and download it to the phone from a website; and this works rather well, plus the user gets current data whenever they download the app. It's also supposed to be possible to throw the data onto the sdcard if you want to avoid using primary data storage space, which is a bigger concern for my app which has a ~6Mb database.
In order to make Android happy with the DB, I believe you have to do the following (I build my DB using perl).
$st = $db->prepare( "CREATE TABLE \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')");
$st->execute();
$st = $db->prepare( "INSERT INTO \"android_metadata\" VALUES ('en_US')");
$st->execute();
I have an update activity which checks weather updates are available and if so presents an "update now" screen. The download process looks like this and lives in a DatabaseHelperClass.
public void downloadUpdate(final Handler handler, final UpdateActivity updateActivity) {
URL url;
try {
close();
File f = new File(getDatabasePath());
if (f.exists()) {
f.delete();
}
getReadableDatabase();
close();
url = new URL("http://yourserver.com/" + currentDbVersion + ".sqlite");
URLConnection urlconn = url.openConnection();
final int contentLength = urlconn.getContentLength();
Log.i(TAG, String.format("Download size %d", contentLength));
handler.post(new Runnable() {
public void run() {
updateActivity.setProgressMax(contentLength);
}
});
InputStream is = urlconn.getInputStream();
// Open the empty db as the output stream
OutputStream os = new FileOutputStream(f);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024 * 1000];
int written = 0;
int length = 0;
while (written < contentLength) {
length = is.read(buffer);
os.write(buffer, 0, length);
written += length;
final int currentprogress = written;
handler.post(new Runnable() {
public void run() {
Log.i(TAG, String.format("progress %d", currentprogress));
updateActivity.setCurrentProgress(currentprogress);
}
});
}
// Close the streams
os.flush();
os.close();
is.close();
Log.i(TAG, "Download complete");
openDatabase();
} catch (Exception e) {
Log.e(TAG, "bad things", e);
}
handler.post(new Runnable() {
public void run() {
updateActivity.refreshState(true);
}
});
}
Also note that I keep a version number in the filename of the db files, and a pointer to the current one in a text file on the server.
It sounds like your app and your db are tightly bound -- that is, the db is useless without the database and the database is useless without the app, so I'd say go ahead and put them both in the same .apk.
That being said, if you expect the db to change very slowly over time, but the app to change quicker, and you don't want your users to have to download the db with each new app revision, then you might want to unbundle them. To make this work, you can do one of two things:
Install them as separate applications, but make sure they share the same userID using the sharedUserId tag in the AndroidManifest.xml file.
Install them as separate applications, and create a ContentProvider for the database. This way other apps could make use of your database as well (if that is useful).
If you are going to store the db on your website then I would recommend that you just make rpc calls to your webserver and get data that way, so the device will never have to deal with a local database. Using a cache manager to avoid multiple lookups will help as well so pages will not have to lookup data each time a page reloads. Also if you need to update the data you do not have to send out a new app every time. Using HttpClient is pretty straight forward, if you need any examples please let me know

Resources