Modifying Tickets API in Open Event Server to Return Hidden Tickets Only for Organizers and Admins

This blog article will illustrate how we can modify the permissions settings for an API to enable different kind of responses to users with different level of permissions. In this article we will discuss these changes with respect to Tickets API. Initially we had a query where we were returning only those tickets who were set to be visible by the admin. Query for this was: class TicketList(ResourceList): """ List Tickets based on different params """ def before_get(self, args, view_kwargs): """ before get method to get the resource id for assigning schema :param args: :param view_kwargs: :return: """ if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'): self.schema = TicketSchemaPublic def query(self, view_kwargs): """ query method for resource list :param view_kwargs: :return: """ query_ = self.session.query(Ticket).filter_by(is_hidden=False)   Problem with this query was that this returned same response irrespective of who is logged in. Hence even the organizers were not able to modify hidden tickets because they were not returned by server. Solution to this problem was to provide hidden tickets only to those who are organizer or are admin/super admins. For this we used the JWT token that was being sent from frontend in request headers for each authenticated request that was being made from frontend. We modified the code to something like this: class TicketList(ResourceList): """ List Tickets based on different params """ def before_get(self, args, view_kwargs): """ before get method to get the resource id for assigning schema :param args: :param view_kwargs: :return: """ if view_kwargs.get('ticket_tag_id') or view_kwargs.get('access_code_id') or view_kwargs.get('order_identifier'): self.schema = TicketSchemaPublic def query(self, view_kwargs): """ query method for resource list :param view_kwargs: :return: """ if 'Authorization' in request.headers: _jwt_required(current_app.config['JWT_DEFAULT_REALM']) if current_user.is_super_admin or current_user.is_admin: query_ = self.session.query(Ticket) elif view_kwargs.get('event_id') and has_access('is_organizer', event_id=view_kwargs['event_id']): query_ = self.session.query(Ticket) else: query_ = self.session.query(Ticket).filter_by(is_hidden=False) else: query_ = self.session.query(Ticket).filter_by(is_hidden=False)   Here we added some conditions which were used to check permission level of logged in user. After picking JWT token from request headers we check if the user was admin or super_admin, then we return all the tickets without any condition. Then we also check if the logged in user was organizer of event then also we send all the tickets without any conditions. However if request comes from unauthenticated users (without valid token) or users with normal privileges, then we returned tickets whose isHidden property was set to False. The functions such as is_organizer and is_super_admin acted as helpers as they were imported from other helper files where they were defined. Resources Open Event Server: Link to PR Open Event API Docs Open Event server ticketsAPI

Continue ReadingModifying Tickets API in Open Event Server to Return Hidden Tickets Only for Organizers and Admins

Integrating Firebase Cloud Functions In Badgeyay

Badgeyay is an open source project developed by FOSSASIA Community for generating badges for conferences and events. The Project is divided into two parts frontend, which is in ember, and backend, which is in flask. Backend uses firebase admin SDK (Python) and Frontend uses firebase javascript client with emberfire wrapper for ember. Whenever an user signs up on the website, database listener that is attached to to the Model gets triggered and uses flask-mail for sending welcome mail to the user and in case of email and password signup, verification mail as well. Problem is sending mail using libraries is a synchronous process and takes a lot of processing on the server. We can use messaging queues like RabbitMQ and Redis but that will be burden as server cost will increase. The workaround is to remove the code from the server and create a firebase cloud function for the same task. Firebase cloud functions lets you run backend code on the cloud and can be triggered with HTTP events or listen for the events on the cloud, like user registration. Procedure Firebase uses our Gmail ID for login, so make sure to have a Gmail ID and on the first sight we will be greeted with Firebase console, where we can see our created or imported firebase apps. Create the app by clicking on the Add Project Icon and write the name of the application (e.g. Test Application) and select the region, in my case it is India. Firebase will automatically generated an application ID for the app. Click on Create Project to complete creation of project After Completion, click on the project to enter into the project. You will be greeted with an overview saying to integrate firebase with your project. We will click on the Add Firebase to web App and save the config as JSON in a file as clientKey.json for later use. Now we need to install the firebase tools on our local machine so for that execute npm i -g firebase-tools Now login from the CLI so that firebase gets token for the Gmail ID of the user and can access the firebase account of that Gmail ID. firebase login After giving permissions to the firebase CLI from your Gmail account in the new tab opened in browser, create a folder named cloud_functions in the project directory and in that execute firebase init Select only functions from the list of options by pressing space. After this select the project from the list where you want to use the cloud function. You can skip the step if you later want to add the cloud function to project by selecting don’t setup a default project and can later be used by command firebase use --add Choose the language of choice If you want, you can enforce eslint on the project and after this the cloud function is set up and the directory structure looks as follows. We will write our cloud function in index.js. So let’s take…

Continue ReadingIntegrating Firebase Cloud Functions In Badgeyay

How to Change a Password and Forgot Password Feature in the SUSI.AI Server

The accounting system of SUSI.AI provides its users the option to change the password of their accounts. This features gives us two options, either we can change our password by entering the older password or if the user forgot the password, they are provided a link on their email address through which we can change our password. Using either option, the user has to authenticate themselves before they can actually change their passwords. If the user has the current password, it is considered as a parameter of authentication. In other case the user has to check their email account for the link which also confirms the authenticity of user. In this post we will discuss how both options works on SUSI. (more…)

Continue ReadingHow to Change a Password and Forgot Password Feature in the SUSI.AI Server

Delete User Account Service using LoginService.java API in SUSI.AI

SUSI.AI has an api to handle all account related services called accounts.susi.ai. This API provides services like change password and delete account. the main goal of accounts.susi.ai is to centralise the accounts’ related settings from web, android and iOS clients into a single place like other accounting services. In this post we will discuss one of these features which is the delete user account from SUSI.AI.

The api accounts.susi.ai has a react file DeleteAccount.react.js. This file handle the delete account service and interacts with the LoginServce.java api, which is the core file for authentication. I will discuss in details how these two interact with each other and with other files. (more…)

Continue ReadingDelete User Account Service using LoginService.java API in SUSI.AI

How to integrate SUSI.AI with Google Sign In API

Google Sign-In manages the OAuth 2.0 flow and token lifecycle, simplifying our integration with Google APIs. A user always has the option to revoke access to an application at any time. Users can see a list of all the apps which they have given permission to access their account details and are using the login API. In this blog post I will discuss how to integrate this API with susi server API to enhance our AAA system. More on Google API here. (more…)

Continue ReadingHow to integrate SUSI.AI with Google Sign In API

Integrating Firebase Cloud Functions In Badgeyay

Badgeyay is an open source project developed by FOSSASIA Community for generating badges for conferences and events. The Project is divided into two parts frontend, which is in ember, and backend, which is in flask. Backend uses firebase admin SDK (Python) and Frontend uses firebase javascript client with emberfire wrapper for ember. Whenever an user signs up on the website, database listener that is attached to to the Model gets triggered and uses flask-mail for sending welcome mail to the user and in case of email and password signup, verification mail as well. Problem is sending mail using libraries is a synchronous process and takes a lot of processing on the server. We can use messaging queues like RabbitMQ and Redis but that will be burden as server cost will increase. The workaround is to remove the code from the server and create a firebase cloud function for the same task. Firebase cloud functions lets you run backend code on the cloud and can be triggered with HTTP events or listen for the events on the cloud, like user registration. Procedure Firebase uses our Gmail ID for login, so make sure to have a Gmail ID and on the first sight we will be greeted with Firebase console, where we can see our created or imported firebase apps. Create the app by clicking on the Add Project Icon and write the name of the application (e.g. Test Application) and select the region, in my case it is India. Firebase will automatically generated an application ID for the app. Click on Create Project to complete creation of project After Completion, click on the project to enter into the project. You will be greeted with an overview saying to integrate firebase with your project. We will click on the Add Firebase to web App and save the config as JSON in a file as clientKey.json for later use. Now we need to install the firebase tools on our local machine so for that execute npm i -g firebase-tools   Now login from the CLI so that firebase gets token for the Gmail ID of the user and can access the firebase account of that Gmail ID. firebase login   After giving permissions to the firebase CLI from your Gmail account in the new tab opened in browser, create a folder named cloud_functions in the project directory and in that execute firebase init   Select only functions from the list of options by pressing space. After this select the project from the list where you want to use the cloud function. You can skip the step if you later want to add the cloud function to project by selecting don’t setup a default project and can later be used by command firebase use --add Choose the language of choice If you want, you can enforce eslint on the project and after this the cloud function is set up and the directory structure looks as follows. We will write our cloud function in index.js.…

Continue ReadingIntegrating Firebase Cloud Functions In Badgeyay

Adding Face Recognition based Authentication to SUSI MagicMirror Module

SUSI MagicMirror Module is a module designed for MagicMirror that helps you get SUSI Intelligence right on your Mirror. You may then ask it questions in the way the Queen in the tale “Snow White and the Seven Dwarfs” asked. One key feature that was missing in it was that the user could be recognized and queries he asked are answered in a personalized manner. This could be achieved if SUSI uses the account dedicated to that person to answer his/her queries. Thus, we need an authentication support. The authentication on MagicMirror is not as trivial as on Web, Android and iOS client apps for SUSI. Key difference here is that user, while using the MagicMirror, does not have access to a keyboard and mouse. Therefore, we cannot simply ask him to input email and password. Furthermore, a MagicMirror installed in your home may be used by several members of your family. Thus, we need a mechanism to tell each user apart. This was done with the help of MMM-Facial-Recognition module which brings face recognition support to MagicMirror. MMM-Facial-Recognition module provides support for recognizing multiple faces and setting the modules on the mirror screen based on the user facing the mirror using OpenCV. Other modules can also take advantage of knowing about the person with the help of module notifications sent by MMM-Facial-Recognition Module. To add Face based Authentication support to SUSI with MMM-Facial-Recognition, we first need to add the latter to MagicMirror. It can be added easily by first cloning the repository to modules directory of MagicMirror. $ git clone https://github.com/paviro/MMM-Facial-Recognition Go inside the directory and install dependencies $ npm run install Now, we need to train a model for the users who are going to use the MagicMirror. This can be done by the MMM-Facial-Recognition-Tools. This tool captures photos from the camera and trains a model for Face Recognition. The guide to use the tool is very well written on the Github page so I am not including it here. After training for faces of the users, you will get a training.xml file. This file contains the information about the facial features of every person so that it can tell users apart. You need to copy this file to the Module directory for MMM-Facial-Recognition module i.e. MagicMirror/module/MMM-Facial-Recognition. After this we can add the module to MagicMirror, by modifying the config file. Add the following lines in the config file (config.js). Copy and paster username array from the training script in the asked position. { module: 'MMM-Facial-Recognition', config: { // 1=LBPH | 2=Fisher | 3=Eigen recognitionAlgorithm: 1, lbphThreshold: 50, fisherThreshold: 250, eigenThreshold: 3000, useUSBCam: true, trainingFile: 'modules/MMM-Facial-Recognition/training.xml', interval: 2, logoutDelay: 15, // Array with usernames (copy and paste from training script) users: [], defaultClass: "default", everyoneClass: "everyone", welcomeMessage: true } } You may configure the show and hide behavior of modules based on the person. Find more information about it in the official guide on the repository. After setting up it recognizes and shows welcome message to each user…

Continue ReadingAdding Face Recognition based Authentication to SUSI MagicMirror Module

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