Author: Mohan Shobana
LinkedIn: https://www.linkedin.com/in/mohan-shobana-018m93/
Contact: shobana.m@northeastern.edu
TASK: Build an image repository.
The task was to create an Image Repository. The challenge has been tackled to provide all the basic features in the form of API endpoints to the users. Also a basic UI has been created (nothing too fancy, just to test the functionality).
-
GITHUB/ GOOGLE OAuth2 Setup
The application uses GITHUB and GOOGLE OAuth2 for authentication. Hence we need to generate the client-id and client-secret for access the APIs and run the application.
The Application.properties(https://github.com/SHOBANAM93/image-repo/blob/92d81095c051478cb5ba291cd78380e5a4da7c36/src/main/resources/application.properties) file has the keys where you might need to key in your GITHUB/GOOGLE client-id and client-secret.
-
PostGreSQL database setup The application uses PostgresSQL as a relational DB to store images and associated information.
The Application.properties(https://github.com/SHOBANAM93/image-repo/blob/92d81095c051478cb5ba291cd78380e5a4da7c36/src/main/resources/application.properties) file has the keys where you might need to change values as per your POSTGRES setup.
- Authentication
- Upload Images
- Search/Retrieve Images
- Encryption
With the use of GITHUB and GOOGLE OAuth2, I have enabled the authentication of user. User cannot access APIs without getting authorized.
Once the application is running:
You can launch the website by opening the following URL(http://localhost:8080/) in any browser:
You can click either the GITHUB or GOOGLE login to authorize the application to use your data and authenticate you to use the application.
GITHUB
GOOGLE
The authenticated user would re-routed back to the homepage using the redirect-url for the application.
Using the logged-in user's principal values we fetch the name
We add the JSESSIONID and XSRF-TOKEN with each API call.
API : /user
The upload API can be used to upload SINGLE image or multiple images as per user's need.
The user's image size limit (max-file-size) is mentioned in the application.properties (https://github.com/SHOBANAM93/image-repo/blob/92d81095c051478cb5ba291cd78380e5a4da7c36/src/main/resources/application.properties). Also altogether all files cannot exceed max-request-size.
Both these properties can be edited as per need.
Once that is set, the application is running and user is authenticated, we can click upload button to get the upload images form.
- Using the browse button, select all images.
- Next, we can give space-separated tagnames to the images being uploaded. Using these tags we can later retrieve them.
- Finally we can select if these images are for private view only or for public view also.
- Click submit.
This invokes the upload API.
API: /upload
Method: HTTP POST
RequestBody: The files, tags and privacy for the images.
JSESSIONID and XSRF-TOKEN are added.
Network tab shows request
Respose
There are two APIs which could be used to fetch images. We can fetch images by giving the tags or by giving the exact image name.
The /retrieve/{imageName} API can be used to fetch the exact images matching the imageName.
The /retrieve/tags API can be used to fetch the images using the tag name.
API: /retrieve/{imageName}
Method: HTTP GET
Params: imageName - image name
JSESSIONID and XSRF-TOKEN are added.
UI
Request
Response
{"message":"Image retrieved","imageSet":[{"email":"shobanasneha.14@gmail.com","name":"restart.gif","type":"image/gif","privacy":"public","picByte":"image in bytes","tags":null}]}
API: /retrieve/tags
Method: HTTP POST
Request Body: tags (space separated)
JSESSIONID and XSRF-TOKEN are added.
UI
Request
Response
In the backend I'm compressing the image bytes using java.util.zip.Inflater(https://github.com/SHOBANAM93/image-repo/blob/70d29e4db468162128b6d1b7d4e750dacfc6bbad/src/main/java/com/interview/imageRepository/utils/CompressionUtils.java) and then encrypting the image bytes further by using AES encryption (https://github.com/SHOBANAM93/image-repo/blob/70d29e4db468162128b6d1b7d4e750dacfc6bbad/src/main/java/com/interview/imageRepository/utils/CryptoUtils.java).
And while retrieving them back, I'm first decrypting the image bytes and then decompressing the image before adding it to the response.
Using PostGreSQL as the relational DB to store the images in byte format. The tag table stores the tags associated to the images. There is one-to-many relationship between image and tag table. one image can have many tags associated to it.
Image Table
Tag table