Merge branch 'master' of https://github.com/sagidayan/SE-Hub into API_Dev
Conflicts: SE_API/API.py
This commit is contained in:
commit
7edd66ff70
10 changed files with 222 additions and 19 deletions
|
@ -16,6 +16,10 @@ from flask.ext.autodoc import Autodoc
|
||||||
from models.User import User
|
from models.User import User
|
||||||
from models.Course import Course
|
from models.Course import Course
|
||||||
from models.Project import Project
|
from models.Project import Project
|
||||||
|
from models.Campus import Campus
|
||||||
|
|
||||||
|
#Validation Utils Libs
|
||||||
|
from SE_API.Validation_Utils import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +43,40 @@ 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/documentation')
|
@app.route('/api/validatation/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():
|
def documentation():
|
||||||
return auto.html()
|
return auto.html()
|
||||||
|
|
||||||
|
@ -65,8 +102,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,
|
||||||
|
@ -74,8 +111,6 @@ def getUserByToken(token):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/githubOAuth')
|
@app.route('/githubOAuth')
|
||||||
@cross_origin('*')
|
@cross_origin('*')
|
||||||
@github.authorized_handler
|
@github.authorized_handler
|
||||||
|
@ -102,10 +137,7 @@ def oauth(oauth_token):
|
||||||
u.put()
|
u.put()
|
||||||
return cookieMonster(u.seToken)
|
return cookieMonster(u.seToken)
|
||||||
|
|
||||||
if user_data["name"] == "":
|
tempName = ";"
|
||||||
tempName = ";"
|
|
||||||
else:
|
|
||||||
tempName = user_data["name"]
|
|
||||||
|
|
||||||
if user_data["email"] == "":
|
if user_data["email"] == "":
|
||||||
for email in userEmails:
|
for email in userEmails:
|
||||||
|
@ -114,13 +146,55 @@ 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, accsessToken=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/<string:token>', methods=['GET'])
|
||||||
|
@auto.doc()
|
||||||
|
def get_campuses(token):
|
||||||
|
"""
|
||||||
|
This Call will return an array of all Campuses available
|
||||||
|
:param token: user seToken
|
||||||
|
:return:
|
||||||
|
code 200:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'title': 'JCE',
|
||||||
|
'email_ending': '@post.jce.ac.il',
|
||||||
|
'master_user_id': 123453433341, (User that created the campus)
|
||||||
|
'avatar_url': 'http://some.domain.com/imagefile.jpg'
|
||||||
|
},
|
||||||
|
....
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}req
|
||||||
|
]
|
||||||
|
|
||||||
|
code 403: Forbidden - Invalid Token
|
||||||
|
code 500: internal server error
|
||||||
|
"""
|
||||||
|
if is_user_token_valid(token):
|
||||||
|
arr = []
|
||||||
|
query = Campus.all()
|
||||||
|
for c in query.run():
|
||||||
|
arr.append(dict(json.loads(c.to_JSON())))
|
||||||
|
print arr
|
||||||
|
if len(arr) != 0:
|
||||||
|
return Response(response=json.dumps(arr),
|
||||||
|
status=200,
|
||||||
|
mimetype="application/json")
|
||||||
|
else:
|
||||||
|
return Response(response=[],
|
||||||
|
status=200,
|
||||||
|
mimetype="application/json")
|
||||||
|
else:
|
||||||
|
return Response(response=json.dumps({'message': 'Invalid Token'}),
|
||||||
|
status=403,
|
||||||
|
mimetype="application/json")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/login')
|
@app.route('/login')
|
||||||
|
|
57
SE_API/Validation_Utils.py
Normal file
57
SE_API/Validation_Utils.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
__author__ = 'sagi'
|
||||||
|
from google.appengine.ext import db
|
||||||
|
from models.User import User
|
||||||
|
from google.appengine.api import mail
|
||||||
|
|
||||||
|
|
||||||
|
def is_user_token_valid(token):
|
||||||
|
query = User.all()
|
||||||
|
query.filter("seToken = ", token)
|
||||||
|
|
||||||
|
for u in query.run():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def send_validation_email(token, email, name):
|
||||||
|
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/validatation/confirm/"""+token+"""
|
||||||
|
to access you virtual class.
|
||||||
|
|
||||||
|
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'>
|
||||||
|
</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/validatation/confirm/"""+token+"""<br><br>
|
||||||
|
|
||||||
|
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()
|
32
models/Campus.py
Normal file
32
models/Campus.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
__author__ = 'sagi'
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from google.appengine.ext import db
|
||||||
|
|
||||||
|
class Campus(db.Model):
|
||||||
|
title = db.StringProperty(required=True)
|
||||||
|
avatar_url = db.StringProperty(required=True)
|
||||||
|
email_ending = db.StringProperty(required=True)
|
||||||
|
master_user_id = db.IntegerProperty(required=True)
|
||||||
|
|
||||||
|
def to_JSON(self):
|
||||||
|
dick = {'title': self.title,
|
||||||
|
'email_ending': self.email_ending,
|
||||||
|
'master_user_id': self.master_user_id,
|
||||||
|
'avatar_url': self.avatar_url
|
||||||
|
}
|
||||||
|
return json.dumps(dick)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
DEBUG Script - To create a campus:
|
||||||
|
"""
|
||||||
|
is_jce_in = False
|
||||||
|
query = Campus.all()
|
||||||
|
query.filter('title =', 'JCE')
|
||||||
|
for c in query.run():
|
||||||
|
is_jce_in = True
|
||||||
|
if not is_jce_in:
|
||||||
|
jce = Campus(title='JCE', email_ending='@post.jce.ac.il', master_user_id=111, avatar_url='https://yt3.ggpht.com/--ZkWxybWGOM/AAAAAAAAAAI/AAAAAAAAAAA/_nAICC_kzzI/s88-c-k-no/photo.jpg')
|
||||||
|
db.put(jce)
|
|
@ -12,6 +12,8 @@ class User(db.Model):
|
||||||
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()
|
||||||
|
classes_id_list = db.StringListProperty()
|
||||||
|
|
||||||
def to_JSON(self):
|
def to_JSON(self):
|
||||||
data = {'username' : self.username,
|
data = {'username' : self.username,
|
||||||
|
@ -21,5 +23,7 @@ class User(db.Model):
|
||||||
'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(data)
|
return json.dumps(data)
|
|
@ -39,7 +39,6 @@ body.noscroll
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width:40%;
|
width:40%;
|
||||||
height:400px;
|
height:400px;
|
||||||
z-index:200;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 15%;
|
margin-top: 15%;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var DEBUG = false;
|
var DEBUG = true;
|
||||||
|
|
||||||
var welcome = angular.module('welcome', ['ngMaterial', 'seHub.services', 'ngRoute' , 'ngCookies']);
|
var welcome = angular.module('welcome', ['ngMaterial', 'seHub.services', 'ngRoute' , 'ngCookies']);
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,12 @@ angular.module('SeHub')
|
||||||
$scope.loadingData = true;
|
$scope.loadingData = true;
|
||||||
|
|
||||||
apiService.getUserByToken(token).success(function(data){
|
apiService.getUserByToken(token).success(function(data){
|
||||||
|
console.log(data);
|
||||||
if(data.message == 'No User Found')
|
if(data.message == 'No User Found')
|
||||||
console.error("No User Found!");
|
console.error("No User Found!");
|
||||||
|
|
||||||
$scope.user = data._entity;
|
$scope.user = data;
|
||||||
$rootScope.user = data._entity;
|
$rootScope.user = data;
|
||||||
if($scope.user.isFirstLogin)
|
if($scope.user.isFirstLogin)
|
||||||
$location.path('/register')
|
$location.path('/register')
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,5 +10,21 @@ angular.module('SeHub')
|
||||||
$scope.userHasNoName = true;
|
$scope.userHasNoName = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///TESTING
|
||||||
|
$scope.campuses = [
|
||||||
|
{
|
||||||
|
title: 'JCE',
|
||||||
|
capus_avatar: "http://asdasfa.asdasd.com/img.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'JCE1',
|
||||||
|
capus_avatar: "http://asdasfa.asdasd.com/img.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "JCE2",
|
||||||
|
capus_avatar: "http://asdasfa.asdasd.com/img.jpg"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
}])
|
|
||||||
|
}]);
|
|
@ -1,4 +1,4 @@
|
||||||
var DEBUG = false;
|
var DEBUG = true;
|
||||||
|
|
||||||
var service = angular.module('seHub.services', []);
|
var service = angular.module('seHub.services', []);
|
||||||
|
|
||||||
|
@ -12,6 +12,15 @@ service.factory('apiService', ['$http', function($http) {
|
||||||
method : "GET",
|
method : "GET",
|
||||||
url : url
|
url : url
|
||||||
|
|
||||||
|
};
|
||||||
|
return $http(req);
|
||||||
|
},
|
||||||
|
getAllCampuses: function(token){
|
||||||
|
var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/Campuses/" + token;
|
||||||
|
req = {
|
||||||
|
method : "GET",
|
||||||
|
url : url
|
||||||
|
|
||||||
};
|
};
|
||||||
return $http(req);
|
return $http(req);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<div class="register">
|
<div class="register">
|
||||||
|
|
||||||
<md-content layout-padding>
|
<md-content layout-padding>
|
||||||
<h1 style="margin-left:15px"><i class="fa fa-pencil"></i> Registration</h1>
|
<h1 style="margin-left:15px"><i class="fa fa-pencil"></i> Registration</h1>
|
||||||
<md-card class="wellcome-float" style="margin-top: 15px;">
|
<md-card class="wellcome-float" style="margin-top: 15px;">
|
||||||
|
@ -21,6 +20,18 @@
|
||||||
</md-switch>
|
</md-switch>
|
||||||
</div>
|
</div>
|
||||||
<center>
|
<center>
|
||||||
|
<div class = "dropDown">
|
||||||
|
<md-select placeholder="Pick your Campus" ng-model="campus" style="z-index: 9999" ng-change="dropdownClicked()">
|
||||||
|
<md-option ng-repeat="c in campuses" value="{{c.title}}">{{c.title}}</md-option>
|
||||||
|
</md-select>
|
||||||
|
</div>
|
||||||
|
<div class = "disabledSubmitButton">
|
||||||
|
<md-button ng-disabled="!campusChecked" class="md-raised md-primary">Submit</md-button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- <div class = "submitButton">
|
||||||
|
<md-button class="md-raised md-primary">Submit</md-button>
|
||||||
|
</div> -->
|
||||||
<p>
|
<p>
|
||||||
<b>Note:</b> This setting can be changed in the future. <br>
|
<b>Note:</b> This setting can be changed in the future. <br>
|
||||||
But Choose Now for easy Registration...
|
But Choose Now for easy Registration...
|
||||||
|
|
Loading…
Reference in a new issue