From 57341c3152a6786ac29c47a4ce9903c553f4357f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Aug 2015 08:30:09 -0700 Subject: [PATCH] api changes to read data store --- .gitignore | 3 + controllers/AESCipher.py | 42 ++++++++++ controllers/AESCipher.pyc | Bin 0 -> 1672 bytes controllers/api.py | 156 ++++++++++++++++++++++++++++++++++++++ controllers/api.pyc | Bin 0 -> 5942 bytes controllers/users.pyc | Bin 0 -> 2708 bytes decorators/decorator.py | 9 ++- decorators/decorator.pyc | Bin 3972 -> 4098 bytes endpoints.py | 52 +++++++++++++ endpoints.pyc | Bin 0 -> 1538 bytes model/__init__.py | 0 model/__init__.pyc | Bin 0 -> 134 bytes model/application.py | 31 ++++++++ model/application.pyc | Bin 0 -> 1379 bytes 14 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 controllers/AESCipher.py create mode 100644 controllers/AESCipher.pyc create mode 100644 controllers/api.py create mode 100644 controllers/api.pyc create mode 100644 controllers/users.pyc create mode 100644 endpoints.py create mode 100644 endpoints.pyc create mode 100644 model/__init__.py create mode 100644 model/__init__.pyc create mode 100644 model/application.py create mode 100644 model/application.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af7ba3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.json +data/* +*.pem \ No newline at end of file diff --git a/controllers/AESCipher.py b/controllers/AESCipher.py new file mode 100644 index 0000000..17c11cd --- /dev/null +++ b/controllers/AESCipher.py @@ -0,0 +1,42 @@ +__author__ = 'nuthankumar.mallavaram@globalfoundries.com' +# -*- 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 ) ) + + + diff --git a/controllers/AESCipher.pyc b/controllers/AESCipher.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69f897fc36a9cfb64ce78592b43c7e79dc3d1d9a GIT binary patch literal 1672 zcmb_cO>fgc5FOk3XxdaQw6ql$5C;@-=&9-fp{i{toG8c<2ck&P)?U)2{)lX+Rixxp z{sBLS8-Ix(0Pl^{R&XUzc09AYGxPS%?0Ub}SATr}`8klq&%^f^BcDQqB3(#FLRTV3 zVpqDZIJ7;9Jn4G6R*|S8aaFq2`?Z>MYr2Mgb?Me6#PW)SHTi~+4GHV2tV)PU$Og?@ zkuTjf#_qJ%2;mh(GAS-iay5xfwjY})GS?3zEwH){q zJjBUa=e)FPuzZt**s=*V;1-SwMjIo43NeEl{tlH}hx*PQ4!XVDX}MTF&*{-rz2L-Y zN3%pWDU)zHZ$XHP{196Eb?^PVlkqt3o$D!jpKLmgY{!}`xaTI2o?|?qW^zTn4h3LGS|C9F8z}JJ2NeV%wJ82u_D zJ;qRMny17cU`~I^5w!dzghkOEu`U~mg?89FG@U!MB7TWKpd+K-SLYlC$}zet&0LQS z*XMIrP>Yc#GZYL;MP{ztdNRk1C!;Fq!MWogFE=+C@4~hoW z!-LQUX=r^IWj7`EM(gt7-xF`sBl8jB*qNaUelR&>$cB<_%yw)Uv z7Fk!|yqr=rk#iR#Uxg5N!(DauoGnj@B#HM#c3^b_t&~C~r7e1B zpv>I(8+72+^?4nZ!`coay}-x`MBJwH1gw?y<4nJwnArCF1@ZU$aT-n{nj||fOfd{% zTU@50&k3Kw9$=~V9}j@f-r8m&vQYCj*2>sSwZLQWo}?M@@DXT}v2?$@fF;E|f;L>a zrlnARqjWGBCIemL!;lPoUO0b?g26QT^3GB|W+i<``bP5As5Lg7ro+*6Yfi&yxPJg< C_etOY literal 0 HcmV?d00001 diff --git a/controllers/api.py b/controllers/api.py new file mode 100644 index 0000000..9a51ace --- /dev/null +++ b/controllers/api.py @@ -0,0 +1,156 @@ +__author__ = 'nuthankumar.mallavaram@globalfoundries.com' +# -*- 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) + diff --git a/controllers/api.pyc b/controllers/api.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7852d2e987538688b1a5ff4895da2339774b28c GIT binary patch literal 5942 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 Lv*iolzA*M5L`ua0 literal 0 HcmV?d00001 diff --git a/controllers/users.pyc b/controllers/users.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52e6cc355c629b27ba7ddcfdb7404a5d78c78ee6 GIT binary patch literal 2708 zcmb_eUvC>l5TCOhCw7v$EtINMNGCy&X^m4=C=XGAwjrfRRfx`s3Q?rfz?4Q~F&2MI1|7*Ry^yeQ3AuT?2 z{60W4zd%Gphma0MHA);hgi`4>I;@Far=(74gANlHerJLHb~nNIPvgJw+3h-5WLtbq73Mmy zxqfAOvcJE#qjj#$Czvp{wlG^88?)K0Kg#n_qJkoptu_L9-3X#I&iYZTRft{Y{n99H zK7GxFeXW8h&yu-a#}1h~wR^!x?dMaK8AO9*^KKTTs;5;F*f`HjFV~|Wi@#g+igBJP z)3f6;Jxk;+ zB9c>hbazgz4nphNv2vf6O3&SbW2r1)b%#1nW#qtn>IPZVbAurU+>;=QBLTqG%9c7a zJS%kr;|6Va@rmM)0RskovEerG7qc{PLHq|>Y!mh<2Sk}&f+}FyWoWsMlzud~ZRkP) z|0Gs3yMit&`}0D{{yo`Z7^@^QW(}jmAdQpxE^f5-y+x4RPrn#+c@J+DLS{YplP+`;VeUcO-a7j7@x!7pN4t_GM|&zS z5;ahP4#!7fo>`qI3D7+fcJ+(7<-7v-I1av`Z?3~)E<;eG<6Lz*wYIa2?`0=s_y6L} zT^LXfD(XyxEB6r3Gt1B?pCO(B+Hnii4oQ%|nUh#>9Z%4B9qM2^cgC8LO{q%DXe`?O!Al(hVgiqxrz&_ zn}=bkwTiafTc*pYBSF|j#S&#-m&$wZg*l0hmDs3L6_yAj;{{r(ERraXl=Y;Jb3P{d zXcT87@h-k9n(&f}!S)K&mu1>Vl|G3>CHc!|_bnG$xeDG7UoK#odUD{5^I)XBTQIyi zMYz})Nk6}OQ7U)*kQo<(>P@HVw46HRx^vT6bKZ73&{rU@z-~Dk2XTrlKEOSyOn!oL zh%63yJ%1RPM`(uct?fQh3b94`?9Av8|K~}Hr<5ivdOyvA^AL2^BL-@@iYO^S~k!1wuS^?hN5@27cGCg{q-SMEi7&C=@i;Q4bt z11Cq*>2gh7xZ}SQxrTS<^GqG165jJT)H43^kBaeNBAHa`B#DpjNfuNXGv5c>U+?V< zJl?rNpP{xL2xN?(vm5`ojFU(LA;sQPK-$;^hvbm|&wT~f`xTI%$xHh#&e3eG0r|`L RuGQ*Ji(9?bX*I51`v-Vmd0YSh literal 0 HcmV?d00001 diff --git a/decorators/decorator.py b/decorators/decorator.py index 5062ef7..c3b4b23 100644 --- a/decorators/decorator.py +++ b/decorators/decorator.py @@ -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 diff --git a/decorators/decorator.pyc b/decorators/decorator.pyc index a9ec9d21f968797604ec1d19554dfeb3a52f5e04..0073b01fa778e9263bec89ef3b9fcf56721beedd 100644 GIT binary patch delta 259 zcmX|%KTE?v9ERWDgd`f31&Fzy$U~gzh4WttBhHm)(g2 zpg8SLqM9wOb)4ra?WC&HR#}qhJa1)Ls$!M4<76Dv(c!4q??>I<;m@y?G;>F&EQ0hRN1k=98CknJ{upzRe}A?#0l-z)%B3j0`=D48et7 z4B;u947KbGDO@1oEFOj|E`}8D$+Fz?tUL_C8oZMoxi@V#=2^ffAj1Fz>^zKYKq$n- p#WeXXuL7gl5T89KPJFSG(4$T1Q$GrV-OfM2M4_@cA$Cq+jlCwpD&Ko{LUooLBlT7QhFw?ZkXwgVpBCU)+=Kp}1 zLGAh4p#RNxgKr<)AAIJIZYyrd?{4ICXY1P|T~&C0m}vC5GtE`eZ`OjSx-quXCFT^6 zMeop8w)FU4LDtrPL%DJJUt!)_y3Bag$@D7udVKapVoJhUmZNwUyc;3auJpryxH?Rp zH36-Cxiqv$9)A3Aoz7tI-{<7NJVEEII~gV?qUH>zA;TxH&Cgtx^H3q$VavkK=cb%f zhxr>1LoZx9LrAfd5-IhRQSJNE7UABy0<_D5O(sXuLVey136t=2cyadmldAF;=V2x; zzC>FUIL6H7iwi7uWjTI-T3v;wn!ZTIX@>D_0Xyiao(g{V-{WJjOVfgpF14P- zGk@htdQavgFiQcKFte!-LgBS>rSz4!o~AQXAfw1(Gh!sq8g30o;qoO;v#R=JB+w(? zFp|j}$-{KOM5@Rk7ADW6c}ct+n-z!ooH3eEpM{2Zw9h(`o*`{S_ioJ3WG4S=FK>S3 zYHSL$N!Liq60ky@(@r=;e@#K&jmWtPOp>lIX%Z~*n#0EJ6)Qtdz{7XvW^ E0F@dY2mk;8 literal 0 HcmV?d00001 diff --git a/model/application.py b/model/application.py new file mode 100644 index 0000000..416de13 --- /dev/null +++ b/model/application.py @@ -0,0 +1,31 @@ +__author__ = 'nuthankumar.mallavaram@globalfoundries.com' +# -*- 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) + + diff --git a/model/application.pyc b/model/application.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bda0de4be11552204ff35007f49c18d0279e69c9 GIT binary patch literal 1379 zcmb_b&2G~`5FR^e(qCEu7le>}v^eCz4TP$eRv;v(DhCdYB3WDS)N#7rHM{E+OTED} z@Ibs04*)Y8n)XadwBy;onQ!*{ruS=S^Z3Wl&jtMb_2_#*!+jtl0VZT4kTIwT>KG<5 zM6w4M!@LIA7JUwzMpcFImC-BMeC7=ew@(HMHbEmB1NLCv zXMhs|xAF(UABOeyJL?;ejYB^7lHz$^Jr1}4Vn^~d?8eeDNW$kxEC}%dNqCbma1^mlR(7u z6iuUWjKUVPDIr8PrL;FsJZid(Uw4~^<6MJi5N(HlsPM4x^fbO(QNc_FD$dBc4;4(; zW}s*baGPbwQj1`+!z^){`>|AT2p;^ClI zbl%vMZwHRPv}n5}TUHWVecE6-1gL?{LOIXxcyl)=qVCO3kXFc@pBr=el;S(C3gVPS zm9d{O$czC6wPh@+Y(OS}Y#rK+)f#4=#1-^uk)k^9cWLLn_E@4_iH`N#h)x+HLr)e; zI7jzpMrIFb@3yMo{j2b}-5=3#T*ax-} l!mobWWL$P=>Y(V1qyHbEK@qQ)-M!D<;uzduV=sO(`~#txJU##b literal 0 HcmV?d00001