Merge branch 'master' of https://github.com/sagidayan/SE-Hub into matanBranch
This commit is contained in:
commit
32f0ffa9a0
9 changed files with 296 additions and 13 deletions
124
SE_API/API.py
124
SE_API/API.py
|
@ -1,3 +1,4 @@
|
|||
|
||||
__author__ = 'sagi'
|
||||
import json
|
||||
from GithubAPI.GithubAPI import GitHubAPI_Keys
|
||||
|
@ -14,10 +15,13 @@ from flask.ext.autodoc import Autodoc
|
|||
|
||||
# DB Models
|
||||
from models.User import User
|
||||
from models.Course import Course
|
||||
from models.Project import Project
|
||||
from models.Campus import Campus
|
||||
|
||||
#Validation Utils Libs
|
||||
from SE_API.Validation_Utils import *
|
||||
from SE_API.Respones_Utils import *
|
||||
|
||||
|
||||
|
||||
|
@ -41,6 +45,70 @@ def page_not_found(e):
|
|||
def wellcomePage():
|
||||
return app.send_static_file('index.html')
|
||||
|
||||
@app.route('/api/validation/confirm/<string:validation_token>')
|
||||
@auto.doc()
|
||||
def confirm_user_to_campus(validation_token):
|
||||
"""
|
||||
This Function is will re
|
||||
:param validation_token: 'seToken|email_suffix'
|
||||
:return:
|
||||
200 - redirect to home + new cookie
|
||||
403 - Invalid Token
|
||||
"""
|
||||
#TODO
|
||||
token = str(validation_token).split('|')[0]
|
||||
email_sufix = '@'+str(validation_token).split('|')[1]
|
||||
|
||||
user = get_user_by_token(token)
|
||||
|
||||
if user is None:
|
||||
return forbidden('Forbidden: invalid Token')
|
||||
else:
|
||||
campus = get_campus_by_suffix(email_sufix)
|
||||
if campus is None:
|
||||
return bad_request('Bad Request: Email Suffix ' + email_sufix + ' Not Found')
|
||||
user.isFirstLogin = False
|
||||
user.seToken = str(uuid.uuid4())
|
||||
if str(campus.key().id()) not in user.campuses_id_list:
|
||||
user.campuses_id_list.append(str(campus.key().id()))
|
||||
db.put(user)
|
||||
return cookieMonster(user.seToken)
|
||||
|
||||
|
||||
|
||||
@app.route('/api/validation/sendmail/<string:token>', methods=['POST'])
|
||||
@auto.doc()
|
||||
def send_activation(token):
|
||||
"""
|
||||
This Method Will Send An Email To The User - To Confirm his Account
|
||||
:param token: - seToken
|
||||
:payload: JSON - {email: 'academic@email.ac.com'}
|
||||
:return:
|
||||
200 - Email Sent - No Response
|
||||
400 - Bad Request
|
||||
403 - Invalid Token
|
||||
"""
|
||||
if not request.data:
|
||||
return Response(response=json.dumps({'message': 'Bad Request'}),
|
||||
status=400,
|
||||
mimetype="application/json")
|
||||
payload = json.loads(request.data)
|
||||
if not is_user_token_valid(token):
|
||||
return Response(response=json.dumps({'message': 'Not A Valid Token!'}),
|
||||
status=403,
|
||||
mimetype="application/json")
|
||||
query = User.all()
|
||||
query.filter('seToken =', token)
|
||||
for u in query.run(limit=1):
|
||||
try:
|
||||
send_validation_email(token=token, name=u.username, email=payload["email"])
|
||||
except Exception:
|
||||
return Response(response=json.dumps({'message': 'Bad Request'}),
|
||||
status=400,
|
||||
mimetype="application/json")
|
||||
|
||||
return Response(status=200)
|
||||
|
||||
@app.route('/api/help')
|
||||
def documentation():
|
||||
return auto.html()
|
||||
|
@ -67,8 +135,8 @@ def getUserByToken(token):
|
|||
|
||||
for u in query.run(limit=5):
|
||||
return Response(response=u.to_JSON(),
|
||||
status=201,
|
||||
mimetype="application/json") # Real response!
|
||||
status=201,
|
||||
mimetype="application/json") # Real response!
|
||||
|
||||
return Response(response=json.dumps({'message' : 'No User Found'}),
|
||||
status=400,
|
||||
|
@ -95,7 +163,7 @@ def oauth(oauth_token):
|
|||
|
||||
print user_data["login"]
|
||||
|
||||
for u in resault.run(limit=5):
|
||||
for u in resault.run():
|
||||
print "Exists!!!"
|
||||
u.seToken = str(uuid.uuid4())
|
||||
u.accessToken = oauth_token
|
||||
|
@ -111,12 +179,58 @@ def oauth(oauth_token):
|
|||
else:
|
||||
tempEmail = user_data["email"]
|
||||
|
||||
user = User(username=user_data["login"], name=tempName, avatar_url=user_data["avatar_url"], email=tempEmail, isLecturer=False, accsessToken=oauth_token, seToken=str(uuid.uuid4()))
|
||||
user = User(username=user_data["login"], name=tempName, avatar_url=user_data["avatar_url"], email=tempEmail, isLecturer=False, accessToken=oauth_token, seToken=str(uuid.uuid4()))
|
||||
db.put(user)
|
||||
db.save
|
||||
return cookieMonster(user.seToken)
|
||||
|
||||
|
||||
@app.route('/api/Campuses/create/<string:token>', methods=['POST'])
|
||||
@auto.doc()
|
||||
def create_campus(token):
|
||||
"""
|
||||
This call will create a new campus in the DB
|
||||
:param token: user seToken
|
||||
Payload
|
||||
{'title': self.title,
|
||||
'email_ending': self.email_ending,
|
||||
'avatar_url': self.avatar_url
|
||||
}
|
||||
:return:
|
||||
code 200
|
||||
"""
|
||||
print "1\n"
|
||||
if not request.data:
|
||||
return Response(response=json.dumps({'message': 'Bad Request0'}),
|
||||
status=400,
|
||||
mimetype="application/json")
|
||||
payload = json.loads(request.data)
|
||||
if not is_lecturer(token): #todo: change to lecturer id
|
||||
return Response(response=json.dumps({'message': 'Invalid token or not a lecturer!'}),
|
||||
status=403,
|
||||
mimetype="application/json")
|
||||
|
||||
user = get_user_by_token(token)
|
||||
|
||||
#todo: check legality
|
||||
|
||||
|
||||
try:
|
||||
campus = Campus(title=payload['title'], email_ending=payload['email_ending'], master_user_id=user.key().id(), avatar_url=payload['avatar_url'])
|
||||
except Exception:
|
||||
return Response(response=json.dumps({'message': 'Bad Request1'}),
|
||||
status=400,
|
||||
mimetype="application/json")
|
||||
|
||||
db.put(campus)
|
||||
db.save
|
||||
return Response(response=json.dumps(campus.to_JSON()),
|
||||
status=200,
|
||||
mimetype="application/json")
|
||||
|
||||
|
||||
|
||||
|
||||
@app.route('/api/Campuses/<string:token>', methods=['GET'])
|
||||
@auto.doc()
|
||||
def get_campuses(token):
|
||||
|
@ -135,7 +249,7 @@ def get_campuses(token):
|
|||
....
|
||||
{
|
||||
...
|
||||
}
|
||||
}req
|
||||
]
|
||||
|
||||
code 403: Forbidden - Invalid Token
|
||||
|
|
15
SE_API/Respones_Utils.py
Normal file
15
SE_API/Respones_Utils.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
__author__ = 'Aran'
|
||||
|
||||
from flask import Response
|
||||
import json
|
||||
|
||||
def bad_request(message='Bad Request'):
|
||||
return Response(response=json.dumps({'message': message}),
|
||||
status=400,
|
||||
mimetype="application/json")
|
||||
|
||||
|
||||
def forbidden(message='Forbidden'):
|
||||
return Response(response=json.dumps({'message': message}),
|
||||
status=403,
|
||||
mimetype="application/json")
|
|
@ -1,11 +1,81 @@
|
|||
__author__ = 'sagi'
|
||||
from google.appengine.ext import db
|
||||
from models.User import User
|
||||
from models.Campus import Campus
|
||||
from google.appengine.api import mail
|
||||
|
||||
def is_user_token_valid(token):
|
||||
|
||||
def get_user_by_token(token):
|
||||
query = User.all()
|
||||
query.filter("seToken = ", token)
|
||||
|
||||
for u in query.run():
|
||||
for u in query.run(limit = 1):
|
||||
return u
|
||||
return None
|
||||
|
||||
def get_campus_by_suffix(suffix):
|
||||
query = Campus.all()
|
||||
query.filter("email_ending = ", suffix)
|
||||
|
||||
for c in query.run(limit = 1):
|
||||
return c
|
||||
return None
|
||||
|
||||
def is_user_token_valid(token):
|
||||
user = get_user_by_token(token)
|
||||
if user is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_lecturer(token):
|
||||
user = get_user_by_token(token)
|
||||
if user is None:
|
||||
return False
|
||||
return user.isLecturer
|
||||
|
||||
|
||||
def send_validation_email(token, email, name):
|
||||
emailSuffix = str(email).split('@')[1]
|
||||
message = mail.EmailMessage(sender="SE-Hub Support <se-hub@appspot.gserviceaccount.com>",
|
||||
subject="SE-Hub Activate Account")
|
||||
|
||||
message.to = email
|
||||
|
||||
message.body = """
|
||||
Dear """+name+""":
|
||||
|
||||
To Activate your SE-Hub Account please click on the link below:<br>
|
||||
http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+"""
|
||||
to get access to your Campus :)
|
||||
|
||||
Please let us know if you have any questions.
|
||||
|
||||
SE-Hub (c) 2015 niptop Team.
|
||||
"""
|
||||
|
||||
message.html = """
|
||||
<html><head></head><body>
|
||||
<div>
|
||||
<center>
|
||||
<img src='https://cloud.githubusercontent.com/assets/2984053/6825467/7c9d0402-d303-11e4-9827-62a6d66f937a.png'>
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
|
||||
</center>
|
||||
</div>
|
||||
<div style='width:70%'>
|
||||
<h1>Hey """+name+"""- Just one More Step...</h1>
|
||||
<h3>Dear """+name+""":</h3>
|
||||
|
||||
To Activate your SE-Hub Account please click on the link below:<br>
|
||||
http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+"""
|
||||
|
||||
to access you virtual class.
|
||||
</div>
|
||||
<br><br>
|
||||
Please let us know if you have any questions.
|
||||
<br>
|
||||
SE-Hub (c) 2015 niptop Team.
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
message.send()
|
||||
|
|
|
@ -11,12 +11,12 @@ class Campus(db.Model):
|
|||
master_user_id = db.IntegerProperty(required=True)
|
||||
|
||||
def to_JSON(self):
|
||||
dick = {'title': self.title,
|
||||
data = {'title': self.title,
|
||||
'email_ending': self.email_ending,
|
||||
'master_user_id': self.master_user_id,
|
||||
'avatar_url': self.avatar_url
|
||||
}
|
||||
return json.dumps(dick)
|
||||
return json.dumps(data)
|
||||
|
||||
|
||||
"""
|
||||
|
|
22
models/Course.py
Normal file
22
models/Course.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
import json
|
||||
|
||||
__author__ = 'Aran'
|
||||
from google.appengine.ext import db
|
||||
|
||||
class Course(db.Model):
|
||||
courseName = db.StringProperty(required=True)
|
||||
campusName = db.StringProperty(required=True)
|
||||
projects = db.StringListProperty(required=True)
|
||||
startDate = db.DateProperty(required=True)
|
||||
endDate = db.DateProperty(required=False)
|
||||
taskFlag = db.BooleanProperty(required=True)
|
||||
|
||||
def to_JSON(self):
|
||||
data = {'courseName' : self.courseName,
|
||||
'campusName' : self.campusName,
|
||||
'projects' : self.projects,
|
||||
'startDate' : self.startDate,
|
||||
'endDate' : self.endDate,
|
||||
'taskFlag' : self.taskFlag,
|
||||
}
|
||||
return json.dumps(data)
|
20
models/Project.py
Normal file
20
models/Project.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
import json
|
||||
|
||||
__author__ = 'Aran'
|
||||
from google.appengine.ext import db
|
||||
|
||||
class Project(db.Model):
|
||||
projectName = db.StringProperty(required=True)
|
||||
grade = db.IntegerProperty(required=True)
|
||||
logo_url = db.StringProperty(required=True)
|
||||
gitRepository = db.StringProperty(required=True)
|
||||
membersId = db.StringListProperty(required=True)
|
||||
|
||||
def to_JSON(self):
|
||||
data = {'projectName' : self.projectName,
|
||||
'grade' : self.grade,
|
||||
'logo_url' : self.logo_url,
|
||||
'gitRepository' : self.gitRepository,
|
||||
'membersId' : self.membersId,
|
||||
}
|
||||
return json.dumps(data)
|
24
models/Task.py
Normal file
24
models/Task.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
import json
|
||||
|
||||
__author__ = 'Aran'
|
||||
from google.appengine.ext import db
|
||||
|
||||
class Task(db.Model):
|
||||
title = db.StringProperty(required=True)
|
||||
description = db.StringProperty(required=True)
|
||||
dueDate = db.DateProperty(required=True)
|
||||
isProject = db.BooleanProperty(required=True)
|
||||
isClose = db.BooleanProperty(required=True)
|
||||
isDone = db.BooleanProperty(required=True)
|
||||
taskGrade = db.IntegerProperty(required=True)
|
||||
|
||||
def to_JSON(self):
|
||||
data = {'title' : self.title,
|
||||
'description' : self.description,
|
||||
'dueDate' : self.dueDate,
|
||||
'isProject' : self.isProject,
|
||||
'isClose' : self.membersId,
|
||||
'isDone' : self.isDone,
|
||||
'taskGrade' : self.taskGrade,
|
||||
}
|
||||
return json.dumps(data)
|
|
@ -5,21 +5,25 @@ from google.appengine.ext import db
|
|||
|
||||
class User(db.Model):
|
||||
username = db.StringProperty(required=True)
|
||||
name = db.StringProperty(required=True)
|
||||
name = db.StringProperty(required=False)
|
||||
email = db.StringProperty(required=True)
|
||||
isLecturer = db.BooleanProperty(required=True)
|
||||
accsessToken = db.StringProperty(required=True)
|
||||
accessToken = db.StringProperty(required=True)
|
||||
seToken = db.StringProperty(required=True)
|
||||
avatar_url = db.StringProperty(required=True)
|
||||
isFirstLogin = db.BooleanProperty(default=True)
|
||||
campuses_id_list = db.StringListProperty(default=[])
|
||||
classes_id_list = db.StringListProperty(default=[])
|
||||
|
||||
def to_JSON(self):
|
||||
dick = {'username' : self.username,
|
||||
data = {'username' : self.username,
|
||||
'name' : self.name,
|
||||
'email' : self.email,
|
||||
'isLecturer' : self.isLecturer,
|
||||
'seToken' : self.seToken,
|
||||
'avatar_url' : self.avatar_url,
|
||||
'isFirstLogin' : self.isFirstLogin,
|
||||
'campuses_id_list': self.campuses_id_list,
|
||||
'classes_id_list': self.classes_id_list
|
||||
}
|
||||
return json.dumps(dick)
|
||||
return json.dumps(data)
|
||||
|
|
|
@ -22,6 +22,20 @@ service.factory('apiService', ['$http', function($http) {
|
|||
url : url
|
||||
|
||||
};
|
||||
return $http(req);
|
||||
},
|
||||
sendValidationMail: function(token, email){
|
||||
var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/validation/sendmail/" + token;
|
||||
payload = {
|
||||
email: email
|
||||
};
|
||||
|
||||
req = {
|
||||
method: "POST",
|
||||
url: url,
|
||||
data: payload
|
||||
};
|
||||
|
||||
return $http(req);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue