Skip to content

Commit

Permalink
api changes to read data store
Browse files Browse the repository at this point in the history
  • Loading branch information
unknown authored and unknown committed Aug 7, 2015
1 parent e563a1e commit 57341c3
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.json
data/*
*.pem
42 changes: 42 additions & 0 deletions controllers/AESCipher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
__author__ = '[email protected]'
# -*- coding: utf-8 -*-
'''
This module serve as crypto util to encrypt and decrypt using AES
Created on Aug 4, 2015
@author: nmallav1
'''
from Crypto.Cipher import AES
import base64
from Crypto import Random
import logging
import string

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * '\f'
unpad = lambda s : s.rstrip('\f')

class Cipher:


@staticmethod
def decrypt( enc,key ):
enc = base64.b64decode(enc)
#logging.info(enc);
iv = enc[:16]
cipher = AES.new(key, AES.MODE_CBC, iv )
dec = cipher.decrypt( enc[16:] )
#logging.info(dec)
#logging.info( unpad(dec))
return unpad(dec)

@staticmethod
def encrypt( raw,key ):
raw = pad(raw)
iv = Random.new().read( 16 )
cipher = AES.new(key, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw ) )



Binary file added controllers/AESCipher.pyc
Binary file not shown.
156 changes: 156 additions & 0 deletions controllers/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
__author__ = '[email protected]'
# -*- coding: utf-8 -*-
'''
This module serve as WSGI end points for people search application REST Calls
Created on Jul 31, 2015
@author: nmallav1
'''
import webapp2
import json
from decorators import decorator
from urllib2 import HTTPError
import logging
import re

SCOPES = ["https://www.googleapis.com/auth/admin.directory.user.readonly",
"https://www.googleapis.com/auth/admin.directory.group.readonly"]

FIELDS = ['nextPageToken',
'users(name,relations,organizations,phones,thumbnailPhotoUrl,primaryEmail,addresses,emails,externalIds)'
]


def responde_with_results(self, results):
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps(results))

safeString = lambda s : "".join(c for c in s if c.isalnum() or c in (' ','.','_')).rstrip()
@decorator.get_oauth_build
def search_google_users(params,directory_service):

page_token = None
all_users = []
while True:
try:
if page_token:
params['pageToken'] = page_token
current_page = directory_service.users().list(**params).execute()
if( 'users' in current_page ):
all_users.extend(current_page['users'])
page_token = current_page.get('nextPageToken')
if not page_token:
break
except HTTPError as error:
logging.error( 'An error occurred: %s' % error)
break
return all_users


@decorator.get_oauth_build
def search_google_groups(params,directory_service):

page_token = None
all_users = []
while True:
try:
if page_token:
params['pageToken'] = page_token
current_page = directory_service.groups().list(**params).execute()
logging.info(current_page)
if( 'users' in current_page ):
all_users.extend(current_page['users'])
page_token = current_page.get('nextPageToken')
if not page_token:
break
except HTTPError as error:
logging.error( 'An error occurred: %s' % error)
break
return all_users


@decorator.get_oauth_build
def get_google_user(params,directory_service):
current_page = directory_service.users().get(**params).execute()
logging.info(current_page)
return current_page

class SimpleUserSearchHandler(webapp2.RequestHandler):
@decorator.app_auth_required
def get(self, keywords):
logging.info(keywords)

if not r':' in keywords:
params = self.extract_params(keywords)
''' default seach with Family name '''
query_result = search_google_users(params)
''' search by Given Name '''
query_result.extend(search_google_users(self.extract_params(keywords,'givenName')))
if len(keywords.split(' ')) > 1:
query_result = filter(lambda x: self.filterResults(x,keywords.split(' ')) , query_result)
else:
# paramterised query
r_v = keywords.split(':')
params = self.extract_params(r_v[1],r_v[0])
''' default seach with Family name '''
query_result = search_google_users(params)
# further filter the results to


responde_with_results(self,query_result)

def filterResults(self,x,value):

if ( ( bool(re.search(r"\b"+max(value),x.get('name').get('givenName'), re.I)) and bool(re.search(r"\b"+min(value), x.get('name').get('familyName'), re.I)) ) \
or (bool(re.search( r"\b"+min(value),x.get('name').get('givenName'), re.I)) and bool(re.search(r"\b"+max(value), x.get('name').get('familyName'), re.I)) ) ):
return True
else :
return False

def extract_params(self,query,criteira='familyName'):
""" Extract the query parameters from the URL and, after validation returns them as a
dictionary.
"""
prefix_list = ['familyName','givenName','email']

query = safeString(query)

q_l = query.split(' ')
if len(q_l) > 1:
query = max(q_l)

if criteira in prefix_list:
query = ':{'+query+'}*'
else:
query = '='+query

return {'domain': 'globalfoundries.com',
'orderBy':'email',
'viewType':'admin_view',
'fields': ','.join(FIELDS),
'query':criteira+query }



class UserGetHandler(webapp2.RequestHandler):
def get(self, keywords):
params = {'userKey':keywords,
'projection':'full'}
query_result = get_google_user(params)
responde_with_results(self,query_result)


class SimpleGroupSearchHandler(webapp2.RequestHandler):
@decorator.app_auth_required
def get(self, keywords):
logging.info(keywords)
params = {'domain': 'globalfoundries.com',

}
query_result = search_google_groups(params)
# further filter the results to


responde_with_results(self,query_result)

Binary file added controllers/api.pyc
Binary file not shown.
Binary file added controllers/users.pyc
Binary file not shown.
9 changes: 8 additions & 1 deletion decorators/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,20 @@ def check_app(self,*args):



employee = Application(name='Baldy',
'''employee = Application(name='Baldy',
key_value='30268571906095969171095037735651',
owner='John Ruby',
registered=datetime.datetime.now())
employee.put()
employee = Application(name='SaR',
key_value='13330882595296274438817752025604',
owner='Gregg Reynolds',
registered=datetime.datetime.now())
employee.put()'''
q = db.Query(Application)
for app in q:
KEY = app.key_value
Expand Down
Binary file modified decorators/decorator.pyc
Binary file not shown.
52 changes: 52 additions & 0 deletions endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
__author__ = '[email protected]'
# -*- coding: utf-8 -*-
"""
This module serve as WSGI Gateway for people search application
Attributes:
app : WSGI interface to extrenal world
"""

import os, sys
lib_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'controllers')
sys.path.insert(0, lib_path)

import webapp2
import logging

from controllers import add_lib_path
add_lib_path()
from controllers import api


endpoints = webapp2.WSGIApplication([
('/api/users/([^/]+)/?', api.SimpleUserSearchHandler),
('/api/user/([^/]+)/?', api.UserGetHandler),
('/api/groups/([^/]+)/?', api.SimpleGroupSearchHandler),

], debug=True)


# Extra Hanlder like 404 500 etc
def handle_404(request, response, exception):
"""module level function to handle page not found exception
parameter lsit::
request (type): description
http request object
response (type): description
http response object
exception (type): description
exception raised by WSGI inteface
Returns:
response: Http response with 404 handle
"""
logging.exception(exception)
response.write('{"error": "404 not_found"}')
response.set_status(404)

endpoints.error_handlers[404] = handle_404

Binary file added endpoints.pyc
Binary file not shown.
Empty file added model/__init__.py
Empty file.
Binary file added model/__init__.pyc
Binary file not shown.
31 changes: 31 additions & 0 deletions model/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
__author__ = '[email protected]'
# -*- coding: utf-8 -*-
'''
This model class to represent application keys
Created on Jul 31, 2015
@author: nmallav1
'''
from google.appengine.ext import db

class Application(db.Model):
"""Models an individual Appliction entry with keys and date."""
app = db.StringProperty()
owner = db.StringProperty()
registered = db.DateTimeProperty()
key_value = db.StringProperty()

class Activity(db.Model):
"""Models an individual Appliction entry with keys and date."""
app = db.StringProperty()
user = db.StringProperty()
time = db.DateTimeProperty()
request = db.StringProperty()
payload = db.IntegerProperty()

@classmethod
def query_book(cls, ancestor_key):
return cls.query(ancestor=ancestor_key).order(-cls.date)


Binary file added model/application.pyc
Binary file not shown.

0 comments on commit 57341c3

Please sign in to comment.