Chatter Back End

Cover Page

DUE Fri, 06/07, 11:59pm

At the end of the lab, you’ll be prompted to keep a clean copy of your working solution and it will form the starting point for all subsequent labs.

A hosted server

You need an Internet-accessible server running

You can use a real physical host or a virtual machine on Aliyun, TencentCloud, Amazon Web Services (AWS), Google Cloud Platform (GCP), Microsoft Azure, etc. as long as they support the above systems. Note that AWS, GCP, Microsoft Azure may ask you to fill billing information that requires a visa card. The steps presented here have been verified to work on Ubuntu 20.04 hosted on a local Linux KVM, Aliyun, AWS, and GCP. These platforms give free trial or credit to students and new users. We provide instructions on how to set up the labs’ back-end server on Aliyun, AWS, and GCP. Please click on the service you want to use below to reveal the instructions.

Aliyun (Recommended)

Aliyun provides a free ECS machine for students and new users, where an ECS machine is a virtual machine running on Alibaba Cloud hardware.

Create an account

Following the steps at the Aliyun Developer to create an acount for students or new users. If registering as a student, you may be asked to verify your student identity.

Start instance

Navigate to the Aliyun home page with your account logged in. Select the “产品” dropdown menu, then “云服务ECS”.

Click “立即购买” to create an instance or “管理控制台” to know more about Aliyun management console. Following is the page for VM configuration after clicking “立即购买” as a common new user (you might see a different page as a student). Remember to select Ubuntu 20.04 as your OS. At the bottom of the page, you should see keywords “试用周期” and “免费试用”. You can create an instance by clicking “免费试用”.

Instance status and configuration

After your instance is created, you can see it at the Aliyun management console under the “实例” tab. You can find YOUR_SERVER_IP in the instance list.

Click “更多” > “密码/密钥” > “重置实例密钥” to reset the password for remotely logging in the VM.

Click “更多” > “网络和安全组” > “安全组设置” to see the list of “安全组”.

Click “配置规则” to see a list of firewall rules.

Add firewall rules to allow SSH, HTTP, HTTPS, and “Custom TCP Rule” for port 8000 (Django) traffic in and out of your instance.

ssh to instance

On your development host (laptop), type

ssh root@YOUR_SERVER_IP

and enter the password you set before. If this is your first time logging in the VM, you will be asked if you want to continue connecting. Choose Yes.

You can also use ssh keys to log in the VM without typing the password every time. Detailed instruction can be found here.

Stop instance

Stopping your instance may change its alloted IP address and undo some of the customizations you’ve done following this spec. Keep your instance up while your lab is being graded. Please remember to check if your instance IP is changed and update the server IP when you stop the instance and start it again.

AWS

The instructions to set up an AWS instance here is adapted from EECS 485’s tutorial.

Create an account

Create an AWS account at the AWS Registration. You should be eligible for their free tier, which means that you will be able to run an instance for free for the duration of the course.

Despite that, you will need to enter a credit card number on the account, even if you only use free tier resources. This is how Amazon charges, in case you request more resources than provided in the free tier. Do not launch any additional instances other than the one we specify in order to avoid additional charges.

Optionally, you may redeem extra benefits as a student, including $100 in AWS credits.

Start instance

Navigate to the AWS Management Console. Select the “Services” dropdown menu, then “EC2”. An EC2 “instance” is a virtual machine running on Amazon AWS hardware.

Click launch an instance. It may take a few minutes to initialize before it’s running.

Select the “Ubuntu Server 20.04 LTS” Amazon Machine Image (AMI).

Select the “t2.micro” instance type. You should see “free tier eligible”. Click “Next”.

Click “Next”

Click “Next”

Click “Next”

Add a rule to allow SSH, HTTP, HTTPS, and “Custom TCP Rule” for port 8000 (Django) traffic in and out of your instance. Then, click “Review and Launch”.

Click “Launch”. Ignore a warning about “Improve your instances’ security”.

When you create an instance, AWS automatically creates user “ubuntu” for you on the instance. Create a key pair for user “ubuntu” and download it. You’ll use this later to ssh to the instance. Finally, click “Launch Instances”.

Click “View Instances”.

Instance status

Navigate to the AWS Management Console. Select the “Services” dropdown menu, then “EC2”.

Click “Instances”.

Select one of the instances and view its status and Public DNS.

In the remainder of this spec, we will refer to your “IPv4 Public IP” as YOUR_SERVER_IP (in the image it’s 3.141.23.144) and “Public DNS (IPv4)” as YOUR_SERVER_DNS (in the image it’s ec2-3-141-23-144.us-east-2.compute.amazonaws.com). Note that YOUR_SERVER_IP always follows ec2 in YOUR_SERVER_DNS, with your “region” listed next (in this case us-east-2).

ssh to instance

On your development host (laptop):

If AWS gave you a eec441.cer instead of eecs441.pem, just use eecs441.cer everywhere you see eecs441.pem in this spec.

MacOS on Terminal:

laptop$ cd YOUR_LABSFOLDER
laptop$ mv ~/Downloads/eecs441.pem eecs441.pem
laptop$ chmod 400 eecs441.pem
laptop$ ssh -i eecs441.pem ubuntu@YOUR_SERVER_IP

Windows on PowerShell [thanks to Jad Beydoun (F21) for use of icacls]:

PS laptop> cd YOUR_LABSFOLDER
PS laptop> mv ~\Downloads\eecs441.pem eecs441.pem
PS laptop> icacls eecs441.pem /grant "$($env:username):(r)" /inheritance:r
PS laptop> ssh -i eecs441.pem ubuntu@YOUR_SERVER_IP

In both cases, what the above does:

  1. change working directory to YOUR_LABSFOLDER,
  2. move the private ssh key you created and downloaded earlier to YOUR_LABSFOLDER,
  3. set its permissions to read-only, and
  4. ssh to your AWS instance as user “ubuntu” using the downloaded private key.

You must use YOUR_SERVER_IP, not YOUR_SERVER_DNS, to ssh to your AWS instance. The DNS hostname assigned by AWS is too long for ssh.

And make sure your instance is running. See Instance status.

Stop instance

DO NOT STOP YOUR INSTANCE. Please leave your EC2 instance running for grading purposes. Stopping your instance will change its alloted IP address and undo some of the customizations you’ve done following this spec. When we’re done with all the labs, after lab3 has been graded, in about 2.5 months, and if you don’t need your instance for your course project, then you can stop your instance, to avoid using your AWS credits.

The AWS free credit refreshes every month. So don’t fret if you get an email from AWS near the end of a month saying you’ve used up 85% of your free credit. It should reset when the new month rolls around.

Check your Instance status.

Right click on your instance > Instance State >Stop.

You should now see that your instance is stopped.

Appendix

Command line tools

To administer AWS EC2 instance from the Ubuntu command line, install the following:

server$ sudo apt install cloud-utils awscli

Useful commands:

server$ ec2metadata
server$ aws configure
server$ aws ec2 help

The command ec2metadata shows the instance’s public-ip and public-hostname.

The command aws configure asks for AWS Access Key ID, which can be obtained from:

server$ aws iam list-access-keys

It also asks for AWS Secret Access Key, which is shown only at creation time at the IAM console.

The Default region name is listed in the public-hostname following the public-ip.

The command aws ec2 is the main interface to configure ec2. The help sub-command lists all the sub-commands such as describe-security-groups, from which one can obtain the group name/id needed to run sub-command authorize-security-group-ingress, for example.

To add IPv6 CIDR block use --ip-permissions, e.g.,

server$ aws ec2 authorize-security-group-ingress --group-id YOUR_GROUP_ID --ip-permissions IpProtocol=tcp,FromPort=8000,ToPort=8000,Ipv6Ranges=[{CidrIpv6=::/0}]
GCP

Google Cloud Platform has a free-tier, with free credits that are easy to qualify for.

Log in to Google Account

You’ll need a personal Google account to use the Google Cloud Platform. Do not use your umich email address. The following steps are adapted from Google Cloud’s Quickstart using a Linux VM, though they have been adapted to the course. For example, we choose an E2 instance that is eligible for the free-tier.

Create Project

Go to the Google Cloud Platform Project Selector page and create a project. Click AGREE AND CONTINUE if you agreed to Google’s Terms of Service.

Create a project by clicking on the Create Project button.

Give your project a name unique to you and click Create.

Add billing

Add a billing method to your project.

When you fill out your billing information, select “individual” as account type. Make sure you see something like this:

Add a credit or debit card. If your backend qualifies for free-tier (it should), this card will not be charged. Select START MY FREE TRIAL. Return to the project console.

Enable Compute Engine API

Visit GCP’s Compute Engine API site and select ENABLE.

Create VM instance

Return to the console. Hover over Compute Engine on the left navigation bar and select VM Instances.

Select CREATE INSTANCE.

Review the free tier options at the Google Cloud Free Program page by scrolling to the section titled “Free Tier usage limits”. Look under the “Compute Engine” section and check regions eligible for free tier. Free tier usage is governed by time used. Currently, an E2 in Oregon, Iowa, or South Carolina is eligible for free tier if used for the number of hours in a month.

Give the instance a name and carefully select the regions that are available as free tier with an e2-micro configuration.

The monthly estimate does not factor in free tier. If the steps are followed, your account should not be billed.

Scroll down until you see the **Boot disk**** section. Click “CHANGE” under Boot disk and configure it to Ubuntu 20.04 LTS. Be sure to select STANDARD PERSISTENT DISK. Any other Boot Disk type option will cost you.

After you’ve chosen “Ubuntu 20.04 LTS” and “Standard persistent disk”, click the blue SELECT button.

Back in the “Machine configuration” page, scroll down further, pass the “Boot disk” section, to get to the “Firewall” section. In the “Firewall” section, allow both HTTP and HTTPS traffic. You should see two boxes like this:

Press “CREATE” to create the instance. Wait for the instance to initialize. When the loading animations are done, write down the external IP address shown on the screen. You will need it for the rest of the term. You’ll never need the internal IP (and GCP doesn’t provide any public DNS for your instance).

Next select the triple dots on your E2. Select “Network Details”.

Select “Firewall”. We have to change one more firewall setting to allow us to test the web server we’ll be setting up later.

Create a firewall rule.

Give your rule a name. Scroll down to “Targets”. Enter “http-server” into the “Target tags” box. Enter 0.0.0.0/0 into the source IPv4 ranges box. Enter port 8000 into the tcp box. Press “CREATE”.

ssh to instance

To build your back end as user ubuntu, please do the following:

First generate a public/private key pair for user “ubuntu”:

laptop$ ssh-keygen -C ubuntu

when ssh-keygen prompts you for the file in which to save the key, enter “eecs441.pem”. It will then prompt you for a passphrase. Leave it empty. Hit return or enter, twice. You should see output similar to this:

Your identifcation has been saved in eecs441.pem
Your public key has been saved in eecs441.pem.pub

Go to GCP Metadata page, open the SSH KEYS tab and click on EDIT.

On the edit page, click + ADD ITEM, copy and paste the content of your “eecs441.pem.pub” to the empty box that + ADD ITEM brought up, and hit the blue SAVE button.

Your SSH KEYS tab should now list “ubuntu” under Username with its corresponding public key:

Keep both your “eecs441.pem.pub” and “eecs441.pem” in a safe place you can easily remember, for example, YOUR_LABSFOLDER:

laptop$ mv eecs441.pem YOUR_LABS_FOLDER
laptop$ mv eecs441.pem.pub YOUR_LABS_FOLDER
laptop$ cd YOUR_LABS_FOLDER
laptop$ chmod 400 eecs441.pem

To ssh to your instance, change folder to YOUR_LABS_FOLDER and ssh to your GCP instance as user “ubuntu” using the generated private key.

laptop$ cd YOUR_LABS_FOLDER
laptop$ ssh -i eecs441.pem ubuntu@YOUR_SERVER_IP

where YOUR_SERVER_IP always refers to the external IP address you’ve noted down earlier.

Stop instance

DO NOT STOP YOUR INSTANCE. Please leave your E2 instance running for grading purposes. Stopping your instance will change its alloted IP address and undo some of the customizations you’ve done following this spec. When we’re done with all the labs, after lab3 has been graded, in about 2.5 months, and if you don’t need your instance for your course project, then you can stop your instance, to avoid using your GCP credits.

GCP should have given you the minimum of 90 days and $300 of credit upon signing up. That is, if your E2 runs more than 3 months and is not eligible for free tier after that (this should not happen anyways) you will get billed a small amount.

Head to your E2 dashboard. Select “Compute Engine”.

When you are completely done with your E2, delete it to ensure you are not charged. A day or two later, ensure that there are no charges for your E2 at all.

Web server

The following are based on DigitalOcean’s How To Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 20.04 though the instructions have been customized to the specifics of our Chatter project, especially when it comes to directory and variable naming, for the sake of narrative consistency across all our labs.

Installing packages

We next need to install and setup the following packages using the apt package manager:

We will later use the Python package manager pip to install:

Before we start, we first ensure that you have the latest apt package manager’s index. Then we download and install the packages and set python3 to be your default python:

server$ sudo apt update
server$ sudo apt install python3-pip python3-dev python3-venv libpq-dev postgresql postgresql-contrib nginx curl
server$ sudo ln -s /usr/bin/python3 /usr/bin/python
Troubleshooting python

To verify that python3 is setup correctly, enter:

server$ python --version
# output:
Python 3.8.10

If you get any error message, try:

server$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
# output:
update-alternatives: using /usr/bin/python3 to provide /usr/bin/python (python) in auto mode
server$ sudo update-alternatives --list python
# output:
/usr/bin/python3
server$ python --version
# output:
Python 3.8.10

Installing updates

Every time you ssh to your server, you will see something like:

N updates can be installed immediately.

if N is not 0, run the following:

server$ sudo apt update
server$ sudo apt upgrade

Failure to update your packages could lead to the lab back end not performing correctly and also make you vulnerable to security hacks.

If you see *** System restart required *** when you ssh to your server, please run:

server$ sync
server$ sudo reboot

Your ssh session will be ended at the server. Wait a few minutes for the system to reboot before you ssh to your server again.

PostgreSQL

Clone your 441 GitHub repo to your back end server

We need to clone your 441 GitHub repo so that we can push your back-end files for submission:

If all goes well, your 441 repo should be cloned to ~/441. Check that:

server$ ls ~/441

shows the content of your 441 git repo, including your lab1 front end.

Python virtual environment

We next install Python within a virtual environment for easier management.

Django web framework

Testing Nginx

Aliyun(Recommended)

To run and test your development server:

  (env):chatter$ ./manage.py runserver 0.0.0.0:8000
AWS

Following the initial server setup guide, you should have a ufw firewall protecting your server. In order to test our back end, we now allow access to port 8000 which we’ll be using for testing:

  (env):chatter$ sudo ufw allow 8000

To run and test your development server:

  (env):chatter$ ./manage.py runserver YOUR_SERVER_DNS:8000

You MUST use YOUR_SERVER_DNS not YOUR_SERVER_IP with runserver. Though you can use either when accessing the test server from a browser as per below.

GCP

To run and test your development server:

  (env):chatter$ ./manage.py runserver 0.0.0.0:8000

In your web browser on your laptop, visit http://YOUR_SERVER_IP:8000/.

You should see the default Django index page:

https://assets.digitalocean.com/articles/django_gunicorn_nginx_1804/django_index.png

When you are satisfied, hit Ctl-C in server’s terminal window to shut down the development server.

Testing Gunicorn

System-level setup

Configuring Gunicorn

We have tested that Gunicorn can interact with our Django application, we now implement a more robust way of starting and stopping the application server. For this, we’ll rely on systemd service and socket files.

The Gunicorn socket will be created at boot and will listen for connections. When a connection occurs, systemd will automatically start the Gunicorn process to handle the connection.

Testing socket

Nginx2Gunicorn

Now that Gunicorn is set up, we need to configure Nginx to pass traffic to it.

Summary: configuration files

In summary, here are the configuration files for the three packages we rely on to provide our back-end service:

Nginx: web server that listens on port 80 file: /etc/nginx/sites-enabled/chatter, if modified run:

server$ sudo nginx -t
server$ sudo systemctl restart nginx

Gunicorn: serves Django project file: /etc/systemd/system/gunicorn.service, if modified run:

server$ sudo systemctl daemon-reload
server$ sudo systemctl restart gunicorn

Django: framework to route HTTP requests to your python code directory: ~/441/chatter/routing/, in particular urls.py (see below). If modified run:

server$ sudo systemctl restart gunicorn

Server-side HTTPS

Begining in 2017, Apple required apps to use HTTPS, the secure version of HTTP. In Aug. 2018, with the release of Android Pie (API level 28), Android also defaulted to blocking all cleartext (HTTP) traffic. To support HTTPS, we need to enable it on the hosting server.

Obtaining a public key

To that end, we must first obtain a public key signed by a Certification Authority (CA). Since obtaining such a certificate usually requires a host with a fully qualified domain name (FQDN), such as www.sjtu.edu.cn, which your server does not have, we have decided to be our own CA and generate and use a self-signed certificate in this course. Typically, a self-signed certificate is used only during development.

Starting with iOS 13 (and macOS 10.15 Catalina), Apple added some security requirements that all server certificates must comply with. To support both iOS and Android clients, a back-end server must thus comply with these security requirements also.

Congrats! You have generated a public-key and put it inside a self-signed certificate! Now to use it.

HTTPS web server

Adapted from Self-Signed SSL Cert.

Our next step is to modify our Nginx configuration to use the new key and certificate files.

HTTPS redirect

Congratulations! Your host is all set up for the rest of the term! Now to implement the Chatter back end.

Chatter back end

We will be creating a python app to serve as Chatter back end.

Start by creating the model-view-controller (MVC) framework expected by Django for all python projects:

server$ cd ~/441/chatter
server$ source env/bin/activate
(env):chatter$ ./manage.py startapp app
(env):chatter$ deactivate

This will create a directory ~/441/chatter/app with the necessary python files in it. In your ~/441/chatter project directory, you should now have two directories that were created by Django:

These are distinct directories and both must be retained (don’t delete or merge them!).

Chatter’s API

Chatter is a simple CRUD app. We have previously created a chatts table in our PostgreSQL database to hold submitted chatts. It consists of three columns: username, message, and time, with time being automatically filled in by the database when an entry is added. We associate a username with each message in a chatt. The getchatts API is for retrieving posted chatts (HTTP GET). To create and post a chatt, the front end will use the postchatt API (HTTP POST). Chatter doesn’t provide “replace” (HTTP PUT) and “delete” (HTTP DELETE) functions.

To start with, chatter has only two APIs:

The protocol handshakes:

url
<- request
-> response

/getchatts/
< HTTP GET {}
> { list of chatts } 200 OK

/postchatt/
<- HTTP POST { username, message }
> {} 200 OK

Data formats

The getchatts API will send back all accumulated chatts in the form of a JSON object with the key being “chatts” and the value being an array of string arrays. Each string array consists of three elements “username”, “message”, and “timestamp”. For example:

{ 
    "chatts": [["username0", "message0", "timestamp0"],
               ["username1", "message1", "timestamp1"], 
               ... 
              ]
}

Each element of the string array may have a value of JSON null or the empty string ("").

To post a chatt with the postchatt API, the front-end client sends a JSON object consisting of “username” and “message”. For example:

{	
   "username": "ubuntu",	
   "message": "Hello world!"	
}

Both APIs will be implemented in ~/441/chatter/app/views.py.

Adding getchatts

Add to ~/441/chatter/app/views.py:

from django.http import JsonResponse, HttpResponse

def getchatts(request):
    if request.method != 'GET':
        return HttpResponse(status=404)
    response = {}
    response['chatts'] = ['Replace Me', 'DUMMY RESPONSE'] # **DUMMY response!**
    return JsonResponse(response)

Routing getchatts

In ~/441/chatter/routing/urls.py add:

from app import views

and add to the urlpatterns array:

    path('getchatts/', views.getchatts, name='getchatts'),

Your urls.py should now look like this:

from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('getchatts/', views.getchatts, name='getchatts'),
    path('admin/', admin.site.urls),
]

Testing getchatts

Everytime you make changes to either views.py or urls.py, you MUST restart Gunicorn:

server$ sudo systemctl restart gunicorn

Test getchatts with:

laptop$ curl --insecure https://YOUR_SERVER_IP/getchatts/

or by browsing, on Chrome, to https://YOUR_SERVER_IP/getchatts/. You should see displayed:

{"chatts": ["Replace Me", "DUMMY RESPONSE"]}

Retrieving chatts

Add to app/views.py:

from django.db import connection

We will use the database cursor to retrieve chatts. We will add the following to your python getchatts(request) function:

    cursor = connection.cursor()
    cursor.execute('SELECT * FROM chatts ORDER BY time DESC;')
    rows = cursor.fetchall()

The following shows where to add the above code to getchatts(). Once you have retrieved all the rows from the database, you need to insert it into the response dictionary to be returned to the front end. Don’t forget to replace the dummy response above with the rows retrieved from the database.

def getchatts(request):
    if request.method != 'GET':
        return HttpResponse(status=404)

    cursor = connection.cursor()
    cursor.execute('SELECT * FROM chatts ORDER BY time DESC;')
    rows = cursor.fetchall()

    response = {}
    response['chatts'] = rows       # <<<<< NOTE: REPLACE dummy response WITH chatts <<<
    return JsonResponse(response)

Adding postchatt

Django wants CSRF (cross-site request forgery) cookies by default, since we’re not implementing it, we ask for exemption. In views.py add:

from django.views.decorators.csrf import csrf_exempt
import json

@csrf_exempt
def postchatt(request):
    if request.method != 'POST':
        return HttpResponse(status=404)
    json_data = json.loads(request.body)
    username = json_data['username']
    message = json_data['message']
    cursor = connection.cursor()
    cursor.execute('INSERT INTO chatts (username, message) VALUES '
                   '(%s, %s);', (username, message))
    return JsonResponse({})

For Python-PostgreSQL interaction, see Passing parameters to SQL queries.

Once we have the view define, we need to tell Django how to route to it. In routing/urls.py add the following entry to the urlpatterns array:

    path('postchatt/', views.postchatt, name='postchatt'),

As before, everytime you make changes to either app/views.py or routing/urls.py, you need to restart Gunicorn:

server$ sudo systemctl restart gunicorn

Testing postchatt

with curl

To test HTTP POST (or HTTP PUT or other) requests, we can again use curl:

laptop$ curl -X POST -d '{ "username": "Test", "message": "Hello World" }' --insecure https://YOUR_SERVER_IP/postchatt/

wth Postman

We can’t test using a browser unfortunately. Instead, we could use Postman, which has a nice graphical interface and is free. The instructions for Postman in this and subsequent labs are intended for the desktop version of Postman. If you’re proficient with the web version, you can use the web version.

To test with Postman, first disable Preferences > SSL certificate verification in Postman. Your certificate wasn’t signed by a trusted certification authority, it was self signed.

with HTTPie

If you’re familiar with HTTPie, you can also use it to test from the command line:

laptop$ echo '{ "username": "weepie", "message": "Yummy!" }' | http --verify=no POST https://YOUR_SERVER_IP/postchatt/
# output:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 2
Content-Type: application/json
Date: Wed, 22 Jul 2022 17:45:53 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{}

The --verify=no option is to tell HTTPie to not try to verify our self-signed certificate. Incidentally, you can also use HTTPie to test getchatts:

laptop$ http --verify=no https://YOUR_SERVER_IP/getchatts/
# output:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 116
Content-Type: application/json
Date: Wed, 22 Jul 2022 17:46:32 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "chatts": [
        [
            "Postman",
            "Ring! Ring!",
            "2022-07-22T17:33:25.947"
        ],
        [
            "weepie",
            "Yummy!",
            "2022-07-22T17:45:53.177"
        ]
    ]
}

Preparing self-signed certificate for the front-end

For your Chatter front end to communicate with your back end, you need to install your self-signed certificate on your device (or emulator or simulator). Some versions of the front-end OS require the certificate to be in binary (DER) format. To convert the certificate to the DER format do (Replace USERNAME with root on Aliyun and ubuntu on AWS and GCP):

server$ cd ~/441/chatter
server$ sudo openssl x509 -inform PEM -outform DER -in /etc/ssl/certs/selfsigned.cert -out selfsigned.crt
server$ sudo chown USERNAME selfsigned.crt

That is all we need to do to prepare the back end. Before you return to work on your front end, wrap up your work here by submitting your files to GitHub.

Back-end submission guidelines

We will only grade files committed to the main branch. If you use multiple branches, please merge them all to the main branch for submission.

Navigate to your back end folder:

server$ cd ~/441/chatter
server$ cp /etc/nginx/sites-enabled/chatter nginx-site    

and tell git to add the files we’ve added or changed:

server$ git add selfsigned.crt nginx-site app/views.py routing/urls.py routing/settings.py

You can check git status by running:

server$ git status

You should see the newly added files.

Commit the new changes to the local repo:

server$ git commit -m "lab1 back end"

and push them to the remote GitHub repo:

server$ git push

If git push fails due to other new changes made to the remote repo, you must run git pull first. Then you may have to resolve any conflicts before you can git push again.

Go the GitHub website to confirm that your back-end files have been uploaded to your GitHub repo.

You can now return to complete the front end: Android | iOS.

Resources and References

Setup:

Intro:

HTTPS, SSL, TLS

Working with self-signed certificate


Prepared for EECS 441 by Tiberiu Vilcu, Wendan Jiang, Alexander Wu, Benjamin Brengman, Ollie Elmgren, Luke Wassink, Yibo Pi, and Sugih Jamin Last updated May 13th, 2023