Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sac #25

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Sac #25

Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
Make_Tables/__pycache__/
.env
2 changes: 1 addition & 1 deletion .env → .sampleenv
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ DATABASE_HOST=localhost
DATABASE_PORT=3306
#Default Host is localhost with Port: 3306
DATABASE_USER=root
DATABASE_PASSWORD=Priyam@0911
DATABASE_PASSWORD=
2 changes: 1 addition & 1 deletion Make_Tables/createdatabase.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
mycursor.execute("use sac_data")

#Creating the tables
mycursor.execute("CREATE TABLE Users(userID char(6) primary key, email varchar(30) unique, password varchar(64), name varchar(64), admin boolean);")
mycursor.execute("CREATE TABLE Users(userID char(6) primary key, email varchar(30) unique, password varchar(256), name varchar(64), admin boolean);")
print("Successfully Created Table Users ") #To Store the login details

mycursor.execute("CREATE TABLE Clubs(clubID char(6) primary key, clubName varchar(64) NOT NULL, about varchar(600), type set('open','close'));")
Expand Down
4 changes: 2 additions & 2 deletions Make_Tables/mysqlconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
directory = os.getcwd()
envindex = directory.find('Make_Tables')
if envindex!=-1: #If current working directory is Make_Tables
load_dotenv(directory[:envindex]+"/.env")
load_dotenv(directory[:envindex]+"/.sampleenv")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • read from .env only, .sampleenv is so that people know what their .env requires.
    (This is so that people don't have to worry about git tracking changes to .env also add a step to readme about creating .env using .sampleenv)

else:
load_dotenv(directory+"/.env")
load_dotenv(directory+"/.sampleenv")

mydb = mysql.connector.connect(
host = os.environ.get("DATABASE_HOST"),
Expand Down
128 changes: 115 additions & 13 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,126 @@
from flask import url_for,render_template,redirect,Flask,flash
from forms import LoginForm
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging, jsonify
from passlib.hash import sha256_crypt
Milind712000 marked this conversation as resolved.
Show resolved Hide resolved
from forms import RegisterForm, LoginForm
from Make_Tables.mysqlconnect import mydb, mycursor, create_insert_statement #Imported the mysqlconnect.py file from Make_tables folder
import gc
from helper import not_logged_in, is_logged_in
from MySQLdb import escape_string as thwart


app=Flask(__name__,static_url_path='/public')
app.config['SECRET_KEY']='c828b6ff21f45063fd7860e5c1b1d233'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'


# Home page before logging in
@app.route('/')
def home():
return render_template('index.html')

@app.route("/login",methods=['GET','POST'])
def Login():
form=LoginForm()
if form.validate_on_submit():
if form.email.data[1:6].isdecimal() and form.email.data[6:]=='@students.iitmandi.ac.in' :
flash('You have logged-in successfully!')
return redirect(url_for('home'))
return 'Home page of SAC-Portal.'


# User Registration
@app.route('/register', methods=['GET', 'POST'])
Milind712000 marked this conversation as resolved.
Show resolved Hide resolved
@not_logged_in
def register():

form = RegisterForm(request.form)

if request.method == 'POST' and form.validate():

userID = form.userID.data
email = form.email.data
name = form.name.data
password = sha256_crypt.hash(str(form.password.data))
admin = 0

mycursor.execute("""SELECT * FROM Users WHERE userID = %s""", (thwart(userID),))

row = mycursor.fetchone()

if row != None: #checking for duplicate Users(if User already registered, can't register again)
return 'This User already exists!'
else:

# Execute query
admin = b'0'
mycursor.execute("""INSERT INTO Users(userID, email, password, name, admin) VALUES(%s, %s, %s, %s, %s)""", (thwart(userID), thwart(email), thwart(password), thwart(name), thwart(admin)))

# Commit to DB
mydb.commit()

flash('You are now registered and can log in!', 'success')
gc.collect() #garbage collection for memory issues

return redirect(url_for('login'))

return jsonify(form.errors)



# User login by filling userID and password fields (userID and password must be enough as our userID(roll no.) and email represent same content)

# A Login WTForm for logging in similar to RegisterForm


@app.route('/login', methods=['GET', 'POST'])
Milind712000 marked this conversation as resolved.
Show resolved Hide resolved
@not_logged_in
def login():

form = LoginForm(request.form)

if request.method == 'POST' and form.validate():

# Get Form Fields
userID = form.userID.data
password_candidate = form.password.data

# Get User by userID
mycursor.execute("""SELECT * FROM Users WHERE userID = %s""", (thwart(userID),))


# Get stored data from database
row = mycursor.fetchone() #data get stored in tuple
if row == None:
return 'userID not found!'
else:
flash('Login Unsuccessful. Invalid Email/Password')
return render_template('login.html',title='Login | SAC Portal, IIT Mandi',form=form)
password = row[2] #hashed password from database
email = row[1]
admin = row[4]


# Compare Passwords
if sha256_crypt.verify(password_candidate, password):
# Passed

session['logged_in'] = True
session['userID'] = userID
session['email'] = email
session['admin'] = admin

flash('You are now logged in!', 'success')
return redirect(url_for('dashboard'))
else:
return 'Password is incorrect!'


return jsonify(form.errors)


#Dashboard (page) after Logging in
@app.route('/dashboard')
@is_logged_in
def dashboard():
return 'Welcome to SAC-Portal!'

# Logout
@app.route('/logout')
@is_logged_in
def logout():
session.clear()
flash('You are now logged out!', 'success')
return redirect(url_for('home'))



if __name__=="__main__":
app.run(debug=True)
43 changes: 34 additions & 9 deletions forms.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Email

class LoginForm(FlaskForm):
email=StringField('Email',validators=[DataRequired(),Email()])
password=PasswordField('Password',validators=[DataRequired()])
remme=BooleanField('Remember Me')
submit=SubmitField('Login')
from wtforms import Form, StringField, TextAreaField, PasswordField, validators, SubmitField, BooleanField, ValidationError

# I didn't use validators.Email() to validate email address since it is very primitive and needs furthur verification by other means such as email activation or lookups.

# userID is our roll no.
#email is [email protected]

# Register Form Class

def userID_check(form, field):
u = form.userID.data
l = ['b','d','t','s','v']
if (len(u) != 6 or u[0] not in l or u[1:6].isdecimal == False) :
raise ValidationError('Please enter valid userID!')

def email_check(form, field):
e = form.email.data
if (len(e) != 30 or e[0:6] != form.userID.data or e[6:] != '@students.iitmandi.ac.in') :
raise ValidationError('Please enter valid email address!')

class RegisterForm(Form):
userID = StringField('UserID', [userID_check])
email = StringField('Email', [email_check])
password = PasswordField('Password', [validators.DataRequired(),validators.EqualTo('confirm', message='Passwords must match!')])
confirm = PasswordField('Confirm Password')
name = StringField('Name', [validators.Length(min=1, max=30)])
submit = SubmitField('Register')


#Login Form Class
class LoginForm(Form):
userID = StringField('UserID', [validators.Length(6)])
password = PasswordField('Password', [validators.DataRequired()])
submit = SubmitField('Login')
22 changes: 22 additions & 0 deletions helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from functools import wraps
from flask import session
# Route guard to prevent logged in user access to login and register page
def not_logged_in(f):
@wraps(f)
def wrap(*args, **kwargs):

if 'logged_in' in session:
return 'Unauthorised! You are already logged in.'
else:
return f(*args, **kwargs)
return wrap

# Check if user is logged-in or not
def is_logged_in(f):
@wraps(f)
def wrap(*args, **kwargs):
if 'logged_in' in session:
return f(*args, **kwargs)
else:
return 'Unauthorized! Please login.'
return wrap
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ python-dotenv==0.12.0
six==1.14.0
Werkzeug==1.0.0
WTForms==2.2.1
passlib==1.7.1
libmysqlclient-dev==5.7.29
6 changes: 6 additions & 0 deletions templates/dashboard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% extends 'layout.html' %}

{% block content %}
<h1>Dashboard</h1>
<p>Welcome back, {{ name }}!</p>
{% endblock %}