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'
|
__author__ = 'sagi'
|
||||||
import json
|
import json
|
||||||
from GithubAPI.GithubAPI import GitHubAPI_Keys
|
from GithubAPI.GithubAPI import GitHubAPI_Keys
|
||||||
|
@ -14,10 +15,13 @@ from flask.ext.autodoc import Autodoc
|
||||||
|
|
||||||
# DB Models
|
# DB Models
|
||||||
from models.User import User
|
from models.User import User
|
||||||
|
from models.Course import Course
|
||||||
|
from models.Project import Project
|
||||||
from models.Campus import Campus
|
from models.Campus import Campus
|
||||||
|
|
||||||
#Validation Utils Libs
|
#Validation Utils Libs
|
||||||
from SE_API.Validation_Utils import *
|
from SE_API.Validation_Utils import *
|
||||||
|
from SE_API.Respones_Utils import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +45,70 @@ def page_not_found(e):
|
||||||
def wellcomePage():
|
def wellcomePage():
|
||||||
return app.send_static_file('index.html')
|
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')
|
@app.route('/api/help')
|
||||||
def documentation():
|
def documentation():
|
||||||
return auto.html()
|
return auto.html()
|
||||||
|
@ -67,8 +135,8 @@ def getUserByToken(token):
|
||||||
|
|
||||||
for u in query.run(limit=5):
|
for u in query.run(limit=5):
|
||||||
return Response(response=u.to_JSON(),
|
return Response(response=u.to_JSON(),
|
||||||
status=201,
|
status=201,
|
||||||
mimetype="application/json") # Real response!
|
mimetype="application/json") # Real response!
|
||||||
|
|
||||||
return Response(response=json.dumps({'message' : 'No User Found'}),
|
return Response(response=json.dumps({'message' : 'No User Found'}),
|
||||||
status=400,
|
status=400,
|
||||||
|
@ -95,7 +163,7 @@ def oauth(oauth_token):
|
||||||
|
|
||||||
print user_data["login"]
|
print user_data["login"]
|
||||||
|
|
||||||
for u in resault.run(limit=5):
|
for u in resault.run():
|
||||||
print "Exists!!!"
|
print "Exists!!!"
|
||||||
u.seToken = str(uuid.uuid4())
|
u.seToken = str(uuid.uuid4())
|
||||||
u.accessToken = oauth_token
|
u.accessToken = oauth_token
|
||||||
|
@ -111,12 +179,58 @@ def oauth(oauth_token):
|
||||||
else:
|
else:
|
||||||
tempEmail = user_data["email"]
|
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.put(user)
|
||||||
db.save
|
db.save
|
||||||
return cookieMonster(user.seToken)
|
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'])
|
@app.route('/api/Campuses/<string:token>', methods=['GET'])
|
||||||
@auto.doc()
|
@auto.doc()
|
||||||
def get_campuses(token):
|
def get_campuses(token):
|
||||||
|
@ -135,7 +249,7 @@ def get_campuses(token):
|
||||||
....
|
....
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
}
|
}req
|
||||||
]
|
]
|
||||||
|
|
||||||
code 403: Forbidden - Invalid Token
|
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'
|
__author__ = 'sagi'
|
||||||
from google.appengine.ext import db
|
from google.appengine.ext import db
|
||||||
from models.User import User
|
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 = User.all()
|
||||||
query.filter("seToken = ", token)
|
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 True
|
||||||
return False
|
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)
|
master_user_id = db.IntegerProperty(required=True)
|
||||||
|
|
||||||
def to_JSON(self):
|
def to_JSON(self):
|
||||||
dick = {'title': self.title,
|
data = {'title': self.title,
|
||||||
'email_ending': self.email_ending,
|
'email_ending': self.email_ending,
|
||||||
'master_user_id': self.master_user_id,
|
'master_user_id': self.master_user_id,
|
||||||
'avatar_url': self.avatar_url
|
'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):
|
class User(db.Model):
|
||||||
username = db.StringProperty(required=True)
|
username = db.StringProperty(required=True)
|
||||||
name = db.StringProperty(required=True)
|
name = db.StringProperty(required=False)
|
||||||
email = db.StringProperty(required=True)
|
email = db.StringProperty(required=True)
|
||||||
isLecturer = db.BooleanProperty(required=True)
|
isLecturer = db.BooleanProperty(required=True)
|
||||||
accsessToken = db.StringProperty(required=True)
|
accessToken = db.StringProperty(required=True)
|
||||||
seToken = db.StringProperty(required=True)
|
seToken = db.StringProperty(required=True)
|
||||||
avatar_url = db.StringProperty(required=True)
|
avatar_url = db.StringProperty(required=True)
|
||||||
isFirstLogin = db.BooleanProperty(default=True)
|
isFirstLogin = db.BooleanProperty(default=True)
|
||||||
|
campuses_id_list = db.StringListProperty(default=[])
|
||||||
|
classes_id_list = db.StringListProperty(default=[])
|
||||||
|
|
||||||
def to_JSON(self):
|
def to_JSON(self):
|
||||||
dick = {'username' : self.username,
|
data = {'username' : self.username,
|
||||||
'name' : self.name,
|
'name' : self.name,
|
||||||
'email' : self.email,
|
'email' : self.email,
|
||||||
'isLecturer' : self.isLecturer,
|
'isLecturer' : self.isLecturer,
|
||||||
'seToken' : self.seToken,
|
'seToken' : self.seToken,
|
||||||
'avatar_url' : self.avatar_url,
|
'avatar_url' : self.avatar_url,
|
||||||
'isFirstLogin' : self.isFirstLogin,
|
'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
|
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);
|
return $http(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue