Fetch Five Star Skill Rating from getSkillList API in SUSI.AI Android

SUSI.AI had a thumbs up/down rating system till now, which has now been replaced by a five star skill rating system. Now, the user is allowed to rate the skill based on a five star rating system. The UI components include a rating bar and below the rating bar is a section that displays the skill rating statistics - total number of ratings, average rating and a graph showing the percentage of users who rated the skill with five stars, four stars and so on. SUSI.AI Skills are rules that are defined in SUSI Skill Data repo which are basically the processed responses that SUSI returns to the user queries. When a user queries something from the SUSI Android app, a query to SUSI Server is made which in turn fetches data from SUSI Skill Data and returns a JSON response to the app. Similarly, to get skill ratings, a call to the ‘/cms/getSkillList.json’ API is made. In this API, the server checks the SUSI Skill Data repo for the skills and returns a JSON response consisting of all the required information like skill name, author name, description, ratings, etc. to the app. Then, this JSON response is parsed to extract individual fields to display the appropriate information in the skill details screen of the app. API Information The endpoint to fetch skills is ‘/cms/getSkillList.json’ The endpoints takes three parameters as input - model - It tells the model to which the skill belongs. The default value is set to general. group - It tells the group(category) to which the skill belongs. The default value is set to All. language - It tells the language to which the skill belongs. The default value is set to en. Since all skills have to be fetched, this API is called for every group individually. For instance, call “https://api.susi.ai/cms/getSkillList.json?group=Knowledge” to get all skills in group “Knowledge”. Similarly, call for other groups. Here is a sample response of a skill named ‘Capital’ from the group Knowledge : "capital": { "model": "general", "group": "Knowledge", "language": "en", "developer_privacy_policy": null, "descriptions": "A skill to tell user about capital of any country.", "image": "images/capital.png", "author": "chashmeet singh", "author_url": "https://github.com/chashmeetsingh", "skill_name": "Capital", "terms_of_use": null, "dynamic_content": true, "examples": ["What is the capital of India?"], "skill_rating": { "negative": "0", "positive": "4", "feedback_count" : 0, "stars": { "one_star": 0, "four_star": 1, "five_star": 0, "total_star": 1, "three_star": 0, "avg_star": 4, "two_star": 0 } }, "creationTime": "2018-03-17T17:11:59Z", "lastAccessTime": "2018-06-06T00:46:22Z", "lastModifiedTime": "2018-03-17T17:11:59Z" }, It consists of all details about the skill called ‘Capital’: Model (model) Group (group) Language (language) Developer Privacy Policy (developer_privacy_policy) Description (descriptions) Image (image) Author (author) Author URL (author_url) Skill name (skill_name) Terms of Use (terms_of_use) Content Type (dynamic_content) Examples (examples) Skill Rating (skill_rating) Creation Time (creationTime) Last Access Time (lastAccessTime) Last Modified Time (lastModifiedTime) From among all this information, the information of interest for this blog is Skill Rating. This blog mainly deals with showing how to parse the JSON response to get the skill rating star values, so as to…

Continue ReadingFetch Five Star Skill Rating from getSkillList API in SUSI.AI Android

Invalidating user login using JWT in Open Event Orga App

User authentication is an essential part of Open Event Orga App (Github Repo), which allows an organizer to log in and perform actions on the event he/she organizes. Backend for the application, Open Event Orga Server sends an authentication token on successful login, and all subsequent privileged API requests must include this token. The token is a JWT (Javascript Web Token) which includes certain information about the user, such as identifier and information about from when will the token be valid, when will it expire and a signature to verify if it was tampered. Parsing the Token Our job was to parse the token to find two fields: Identifier of user Expiry time of the token We stored the token in our shared preference file and loaded it from there for any subsequent requests. But, the token expires after 24 hours and we needed our login model to clear it once it has expired and shown the login activity instead. To do this, we needed to parse the JWT and compare the timestamp stored in the exp field with the current timestamp and determine if the token is expired. The first step in the process was to parse the token, which is essentially a Base 64 encoded JSON string with sections separated by periods. The sections are as follows: Header ( Contains information about algorithm used to encode JWT, etc ) Payload ( The data in JWT - exp. Iar, nbf, identity, etc ) Signature ( Verification signature of JWT ) We were interested in payload and for getting the JSON string from the token, we could have used Android’s Base64 class to decode the token, but we wanted to unit test all the util functions and that is why we opted for a custom Base64 class for only decoding our token. So, first we split the token by the period and decoded each part and stored it in a SparseArrayCompat public static SparseArrayCompat<String> decode(String token) { SparseArrayCompat<String> decoded = new SparseArrayCompat<>(2); String[] split = token.split("\\."); decoded.append(0, getJson(split[0])); decoded.append(1, getJson(split[1])); return decoded; }   The getJson function is primarily decoding the Base64 string private static String getJson(String strEncoded) { byte[] decodedBytes = Base64Utils.decode(strEncoded); return new String(decodedBytes); } The decoded information was stored in this way 0={"alg":"HS256","typ":"JWT"}, 1={"nbf":1495745400,"iat":1495745400,"exp":1495745800,"identity":344} Extracting Information Next, we create a function to get the expiry timestamp from the token. We could use GSON or Jackson for the task, but we did not want to map fields into any object. So we simply used JSONObject class which Android provides. It took 5 ms on average to parse the JSON instead of 150 ms by GSON public static long getExpiry(String token) throws JSONException { SparseArrayCompat<String> decoded = decode(token); // We are using JSONObject instead of GSON as it takes about 5 ms instead of 150 ms taken by GSON return Long.parseLong(new JSONObject(decoded.get(1)).get("exp").toString()); }   Next, we wanted to get the ID of user from token to determine if a new user is logging in or an old one, so…

Continue ReadingInvalidating user login using JWT in Open Event Orga App