PageRenderTime 5ms CodeModel.GetById 6ms app.highlight 130ms RepoModel.GetById 2ms app.codeStats 0ms

/S4M_pyramid/model/stemformatics/stemformatics_auth.py

https://bitbucket.org/TheSaturnTeam/s4m_pyramid
Python | 1606 lines | 1594 code | 8 blank | 4 comment | 38 complexity | d2c660c1b84ecdfc0ceadaddcba798a8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1#-------Last synchronised with Pylons repo (master) on---------------#
   2#-------------------------8 Feb 2018---------------------------------#
   3#-------------------------by WU Yan----------------------------------#
   4
   5#TODO-1
   6import logging
   7log = logging.getLogger(__name__)
   8
   9import sqlalchemy as SA
  10from sqlalchemy import or_, and_, desc
  11import psycopg2
  12import psycopg2.extras
  13
  14import re
  15import string
  16import json
  17
  18from S4M_pyramid.lib.deprecated_pylons_globals import magic_globals, url, config
  19from S4M_pyramid.lib.deprecated_pylons_abort_and_redirect import abort, redirect
  20
  21from decorator import decorator
  22import smtplib
  23
  24__all__ = ['Stemformatics_Auth']
  25
  26import formencode.validators as fe
  27
  28SUBSCRIBER_NAME = fe.Regex("[\w ]*", not_empty=False, if_empty="Anonymous User")
  29SUBSCRIBER_STATE = fe.Regex("[\w ]*", not_empty=False, if_empty="PENDING")
  30DESCRIPTIVE_TEXT = fe.Regex("[\w ]*", not_empty=False, if_empty="")
  31POS_INT = fe.Int(min=1, not_empty=True)
  32NUMBER = fe.Number(not_empty=True)
  33IDENTIFIER = fe.PlainText(not_empty=True)
  34URL = fe.URL(not_empty=True)
  35VQ = re.compile(r"[^\'\"\`\$\\]*")
  36
  37import hashlib
  38
  39from random import random
  40
  41import datetime
  42
  43import S4M_pyramid.lib.helpers as h
  44from S4M_pyramid.model import redis_interface_normal as r_server
  45
  46
  47
  48class Stemformatics_Auth(object):
  49    """\
  50    Stemformatics_Auth Model Object
  51    ========================================
  52
  53    A simple model of static functions to make the controllers thinner for login controller
  54
  55    Please note for most of these functions you will have to pass in the db object
  56
  57    All functions have a try that will return None if errors are found
  58
  59
  60    """
  61    @staticmethod
  62    def user_status_dict():
  63        status_dict = {0:'Inactive',1:'Active',2:'Pending'}
  64        return status_dict
  65
  66    @staticmethod
  67    def get_status_dict_by_name():
  68        status_dict = Stemformatics_Auth.user_status_dict()
  69        status_dict_by_name = {}
  70        for status_id in status_dict:
  71            name = status_dict[status_id]
  72            status_dict_by_name[name] = status_id
  73
  74        return status_dict_by_name
  75
  76    @staticmethod
  77    def set_smart_redirect(redirect_url):
  78        magic_globals.fetch()
  79        session = magic_globals.session
  80        session['redirect_url'] = redirect_url
  81        session.save()
  82        return True
  83
  84    """
  85    This is for checking if this uid is a real user, not using guest account either
  86    """
  87    @staticmethod
  88    def check_real_user(uid):
  89
  90        status_dict_by_name = Stemformatics_Auth.get_status_dict_by_name()
  91        status_id = status_dict_by_name['Active']
  92
  93        guest_username = config['guest_username']
  94
  95        conn_string = config['psycopg2_conn_string']
  96        conn = psycopg2.connect(conn_string)
  97        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
  98        sql = "select uid from stemformatics.users where uid = %s and status= %s and username != %s;"
  99        cursor.execute(sql,(uid,status_id,guest_username,))
 100
 101        # retrieve the records from the database
 102        result = cursor.fetchall()
 103        cursor.close()
 104        conn.close()
 105
 106        try:
 107            if result[0][0] == uid:
 108                real_user = True
 109            else:
 110                real_user = False
 111        except:
 112            real_user = False
 113
 114        return real_user
 115
 116
 117    @staticmethod
 118    def get_smart_redirect(default_redirect_url):
 119        magic_globals.fetch()
 120        session = magic_globals.session
 121        if 'redirect_url' in session:
 122            redirect_url = session['redirect_url']
 123        else:
 124            redirect_url = ""
 125        session['redirect_url'] = ""
 126        session.save()
 127        if redirect_url != "":
 128            return redirect_url
 129        else:
 130            return default_redirect_url
 131
 132
 133
 134
 135
 136    def __init__ (self):
 137        pass
 138
 139    @staticmethod
 140    def authorise(db=None):
 141        """\
 142
 143            Usage:
 144
 145                @Stemformatics_Auth.authorise()
 146                def summary(self):
 147
 148        """
 149        def check_authorised(func, *args, **kwargs):
 150
 151            log.debug('start of authorise')
 152
 153            magic_globals.fetch()
 154            c = magic_globals.c
 155            session = magic_globals.session
 156            request = magic_globals.request
 157            if 'path_before_login' in session:
 158                del session['path_before_login']
 159                session.save()
 160
 161            if 'user' in session:
 162                c.user = session.get('user').lower()
 163                c.uid = session.get('uid')
 164                c.full_name = session.get('full_name')
 165                c.role = session.get('role')
 166                c.notifications = 1
 167                return func(*args, **kwargs)
 168            else:
 169                c.user = None
 170                session['path_before_login'] = request.path_info + '?' + request.query_string
 171                session.save()
 172                return redirect(h.url('/auth/login'))
 173
 174        return decorator(check_authorised)
 175
 176
 177    @staticmethod
 178    def check_user_password(db,username,password): #CRITICAL-2
 179        username = username.lower()
 180        try:
 181            db.schema = 'stemformatics'
 182
 183            user = db.users
 184
 185            m = hashlib.sha1()
 186            m.update(password.encode('utf-8'))
 187            sha1_password = m.hexdigest()
 188
 189            where = and_(user.username==username,user.password==sha1_password,user.status == 1)
 190            result = db.users.filter(where).all()
 191
 192            if len(result) != 1:
 193                return None
 194
 195            db_user = result[0]
 196            return db_user
 197
 198        except:
 199            return None
 200
 201    @staticmethod
 202    def confirm_new_user(db,confirm_code,uid): #CRITICAL-2
 203        try:
 204            db.schema = 'stemformatics'
 205
 206            user = db.users
 207
 208            now_time = datetime.datetime.now()
 209            two_days = datetime.timedelta(days=2)
 210
 211            check_time = now_time - two_days
 212
 213            # where = and_(user.confirm_code==confirm_code,user.status==0,user.created > check_time)
 214            result = user.filter(user.uid==uid).all()
 215
 216            if len(result) != 1:
 217                return "This user does not exist. Please register."
 218
 219            if result[0].status == 1:
 220                return "This user is already registered"
 221
 222
 223            if result[0].confirm_code.strip() != confirm_code:
 224                return "This confirm code is invalid or has expired for this user"
 225
 226            if result[0].created < check_time:
 227                return "This confirm code has expired for this user"
 228
 229
 230            db_user = result[0]
 231
 232            result = user.filter(user.uid == db_user.uid).update({'status': 1, 'confirm_code': ''})
 233            db.commit()
 234
 235
 236            Stemformatics_Auth.create_base_export_key(db_user.uid)
 237
 238            db_user.status = 1
 239            db_user.confirm_code = ""
 240            Stemformatics_Auth.triggers_for_change_in_user(db,uid = None)
 241            return db_user
 242
 243        except:
 244            return "Unknown error with confirming"
 245
 246    @staticmethod
 247    def clear_expired_unconfirmed_users(db): #CRITICAL-2
 248        try:
 249            db.schema = 'stemformatics'
 250
 251            user = db.users
 252
 253            now_time = datetime.datetime.now()
 254            two_days = datetime.timedelta(days=2)
 255
 256            check_time = now_time - two_days
 257
 258            # change to status 2 instead of deleting just in case we have override options for this uid
 259            where = and_(user.status==0,user.created < check_time)
 260            result = db.users.filter(where).update({'status':2})
 261            db.commit()
 262
 263            return True
 264
 265        except:
 266            return False
 267
 268
 269    @staticmethod
 270    def remove_user(db,username): #CRITICAL-2
 271        username = username.lower()
 272        try:
 273            db.schema = 'stemformatics'
 274
 275            user = db.users
 276            gsi = db.gene_set_items
 277            gs = db.gene_sets
 278
 279            where = and_(user.username==username)
 280            result = user.filter(where).all()
 281
 282            for userFound in result:
 283                geneSets = gs.filter(gs.uid == userFound.uid).all()
 284                for geneSet in geneSets:
 285                    gsi.filter(gsi.gene_set_id == geneSet.id).delete()
 286                    gs.filter(gs.id == geneSet.id).delete()
 287
 288
 289            where = and_(user.username==username)
 290            user.filter(where).delete()
 291            db.commit()
 292
 293            return True
 294
 295        except:
 296            return False
 297
 298    @staticmethod
 299    def register_new_user(db,registration_data): #CRITICAL-2
 300
 301        username = registration_data['username'].lower()
 302
 303        # Story #179 have to check for users who are set as 0 or 1. If status of 2, then have to update and not create new user
 304        db.schema = 'stemformatics'
 305        where = and_(db.users.username==username)
 306        result = db.users.filter(where).all()
 307
 308        update_user = False
 309
 310        # check if username already available
 311        if len(result) == 1:
 312
 313            if result[0].status == 2:
 314                update_user = True
 315            else:
 316                return "This username is already taken"
 317
 318        if len(result) > 1:
 319            return "This username is already taken"
 320
 321        # check strong password
 322
 323        validation_regex_text = config['validation_regex']
 324
 325        validation_regex = re.compile(validation_regex_text)
 326
 327        m = validation_regex.match(registration_data['password'])
 328
 329        if m is None:
 330            return config['validation_warning']
 331
 332
 333
 334        m = re.search('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',username)
 335
 336        if m is None:
 337            return "This username is not valid, it must be a valid email address"
 338
 339
 340
 341        m = hashlib.sha1()
 342        m.update(registration_data['password'].encode('utf-8'))
 343        sha1_password = m.hexdigest()
 344
 345        base_confirm_code = m.update(str(random()).encode('utf-8'))
 346        confirm_code = m.hexdigest()
 347
 348        # create new user - but check that it's not an update for an existing user with status of 2
 349        if update_user:
 350
 351            now_time = datetime.datetime.now()
 352            dict_change = {'password':sha1_password,'created':now_time,'status': 0, 'confirm_code': confirm_code,'full_name': registration_data['full_name'], 'organisation': registration_data['organisation'], 'send_email_marketing': registration_data['send_email_marketing'], 'send_email_job_notifications': registration_data['send_email_job_notifications']}
 353            result = db.users.filter(db.users.username == username).update(dict_change)
 354        else:
 355            result = db.users.insert(username=username, password=sha1_password,organisation=registration_data['organisation'],full_name = registration_data['full_name'],confirm_code=confirm_code, send_email_marketing= registration_data['send_email_marketing'], send_email_job_notifications = registration_data['send_email_job_notifications'])
 356
 357        db.commit()
 358        db.flush()
 359
 360        where = and_(db.users.username==username)
 361        result = db.users.filter(where).all()
 362
 363        if len(result) != 1:
 364            return "The registration could not be saved"
 365
 366        return result[0]
 367        #except:
 368        #   return "Error in this application in register_new_user"
 369
 370    @staticmethod
 371    def set_confirm_forgot_password(db,username): #CRITICAL-2
 372        username = username.lower()
 373        try:
 374            db.schema = 'stemformatics'
 375            user = db.users
 376            # only select users with status of active
 377            where = and_(user.username==username, user.status == 1)
 378            result = user.filter(where).all()
 379
 380            # check if username already available
 381            if len(result) != 1:
 382                return None
 383
 384            m = hashlib.sha1()
 385            base_confirm_code = m.update(str(random()).encode('utf-8'))
 386            confirm_code = m.hexdigest()
 387
 388            now_time = datetime.datetime.now()
 389            two_hours = datetime.timedelta(hours=2)
 390
 391            expiry_password_time = now_time + two_hours
 392
 393            # update confirm code for user
 394            result = user.filter(user.username == username).update({'confirm_code':confirm_code , 'password_expiry': expiry_password_time})
 395
 396            db.commit()
 397            db.flush()
 398
 399            where = and_(user.username==username, user.confirm_code == confirm_code, user.status ==1)
 400            result = user.filter(where).all()
 401
 402            # check if found
 403            if len(result) != 1:
 404                return None
 405
 406            db_user = result[0]
 407
 408            return db_user
 409        except:
 410            return None
 411
 412    @staticmethod
 413    def get_user_from_confirm_code(db,confirm_code): #CRITICAL-2
 414        try:
 415            db.schema = 'stemformatics'
 416            user = db.users
 417
 418            where = and_(user.confirm_code == confirm_code)
 419            result = user.filter(where).all()
 420
 421            if len(result) != 1:
 422                return None
 423
 424            return result[0]
 425        except:
 426            return None
 427
 428
 429    @staticmethod
 430    def get_users_from_usernames(list_of_usernames):
 431
 432        if not isinstance(list_of_usernames,list):
 433            return []
 434
 435        conn_string = config['psycopg2_conn_string']
 436        conn = psycopg2.connect(conn_string)
 437        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 438        sql = "select * from stemformatics.users where username = ANY(%(list_of_usernames)s) ;"
 439        cursor.execute(sql,{'list_of_usernames': list_of_usernames})
 440
 441        # retrieve the records from the database
 442        result = cursor.fetchall()
 443        cursor.close()
 444        conn.close()
 445
 446        return result
 447
 448    @staticmethod
 449    def set_users_to_be_inactive_from_usernames(string_of_usernames):
 450        status_dict_by_name = Stemformatics_Auth.get_status_dict_by_name()
 451        status_id = status_dict_by_name['Inactive']
 452
 453        if not isinstance(string_of_usernames,str) and not isinstance(string_of_usernames,bytes):
 454            return []
 455
 456        list_of_usernames  = re.findall("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+", string_of_usernames)
 457
 458        user_result = Stemformatics_Auth.get_users_from_usernames(list_of_usernames)
 459        list_of_uids = []
 460        return_dict_of_usernames_and_uids = {}
 461        for row in user_result:
 462            uid = row['uid']
 463            list_of_uids.append(uid)
 464            return_dict_of_usernames_and_uids[uid] = row['username']
 465
 466        conn_string = config['psycopg2_conn_string']
 467        conn = psycopg2.connect(conn_string)
 468        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 469        sql = "update stemformatics.users set status = %(status_id)s where uid = ANY(%(list_of_uids)s) ;"
 470        cursor.execute(sql,{'list_of_uids': list_of_uids,'status_id':status_id})
 471
 472        conn.commit()
 473        cursor.close()
 474        conn.close()
 475
 476        return return_dict_of_usernames_and_uids
 477
 478    @staticmethod
 479    def unsubscribe_users_from_outage_critical_notifications(string_of_usernames):
 480
 481        if not isinstance(string_of_usernames,str) and not isinstance(string_of_usernames,bytes):
 482            return []
 483
 484        list_of_usernames  = re.findall("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+", string_of_usernames)
 485
 486        user_result = Stemformatics_Auth.get_users_from_usernames(list_of_usernames)
 487        list_of_uids = []
 488        return_dict_of_usernames_and_uids = {}
 489        for row in user_result:
 490            uid = row['uid']
 491            list_of_uids.append(uid)
 492            return_dict_of_usernames_and_uids[uid] = row['username']
 493
 494        conn_string = config['psycopg2_conn_string']
 495        conn = psycopg2.connect(conn_string)
 496        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 497        sql = "update stemformatics.users set send_email_outages_critical = False where uid = ANY(%(list_of_uids)s) ;"
 498        cursor.execute(sql,{'list_of_uids': list_of_uids})
 499
 500        conn.commit()
 501        cursor.close()
 502        conn.close()
 503
 504        return return_dict_of_usernames_and_uids
 505
 506
 507    @staticmethod
 508    def get_user_from_username(db,username): #CRITICAL-2
 509        username = username.lower()
 510        try:
 511            db.schema = 'stemformatics'
 512            user = db.users
 513            # only select users with blank confirm codes and status of active
 514            where = and_(user.username == username)
 515            result = user.filter(where).all()
 516
 517            if len(result) != 1:
 518                return None
 519
 520            return result[0]
 521        except:
 522            return None
 523
 524    @staticmethod
 525    def get_user_from_uid(db,uid): #CRITICAL-2
 526        try:
 527            db.schema = 'stemformatics'
 528            user = db.users
 529            # only select users with blank confirm codes and status of active
 530            where = and_(user.uid == uid)
 531            result = user.filter(where).all()
 532
 533            if len(result) != 1:
 534                return None
 535
 536            return result[0]
 537        except:
 538            return None
 539
 540    @staticmethod
 541    def reset_password(db,confirmed_user,confirm_code,password):  #CRITICAL-2
 542        try:
 543            db.schema = 'public'
 544            user = db.users
 545
 546            # check expiry of password
 547            now_time = datetime.datetime.now()
 548            if confirmed_user.password_expiry is None or confirmed_user.password_expiry < now_time:
 549                return "This has expired. Please try again"
 550
 551
 552            # reset password
 553            username = confirmed_user.username.lower()
 554            updated_user = Stemformatics_Auth.change_password(db,username,password)
 555            if isinstance(updated_user, str):
 556                return updated_user
 557
 558            # clear out expiry
 559            result = user.filter(user.uid == confirmed_user.uid).update({'confirm_code':'','password_expiry': None })
 560            db.commit()
 561            db.flush()
 562
 563            return result
 564        except:
 565            return "Error in application reset_password"
 566
 567    @staticmethod
 568    def clear_expired_password_resets(db): #CRITICAL-2
 569        try:
 570            db.schema = 'stemformatics'
 571
 572            user = db.users
 573
 574            now_time = datetime.datetime.now()
 575
 576            where = and_(user.status==1,user.password_expiry < now_time)
 577            result = db.users.filter(where).update({'confirm_code':'','password_expiry': None })
 578            db.commit()
 579
 580            return True
 581
 582        except:
 583            return False
 584
 585
 586    @staticmethod
 587    def change_password(db,username,password): #CRITICAL-2
 588        username = username.lower()
 589        try:
 590            validation_regex_text = config['validation_regex']
 591
 592            validation_regex = re.compile(validation_regex_text)
 593
 594            m = validation_regex.match(password)
 595
 596            if m is None:
 597                return config['validation_warning']
 598
 599            db.schema = 'stemformatics'
 600            user = db.users
 601
 602            where = and_(user.username==username)
 603            result = user.filter(where).all()
 604
 605            # check if username already available
 606            if len(result) != 1:
 607                return "There was an error finding this user"
 608
 609            m = hashlib.sha1()
 610            m.update(password.encode('utf-8'))
 611            sha1_password = m.hexdigest()
 612
 613            # update user
 614            result = user.filter(user.username == username).update({'password':sha1_password })
 615            db.commit()
 616            db.flush()
 617
 618            where = and_(user.username==username)
 619            check = user.filter(where).all()
 620
 621            if len(check) != 1:
 622                return "The user could not be updated"
 623
 624            if check[0].password != sha1_password:
 625                return "The password could not be saved"
 626
 627            return check[0]
 628        except:
 629            return "Error in application change_password"
 630
 631    @staticmethod
 632    def update_user(db,username,update_user): #CRITICAL-2
 633
 634        try:
 635            username = username.lower()
 636            db.schema = 'stemformatics'
 637            user = db.users
 638            where = and_(user.username==username)
 639            result = user.filter(where).all()
 640
 641            # check if username already available
 642            if len(result) != 1:
 643                return "There was an error finding this user"
 644
 645
 646            if 'password' in update_user:
 647
 648                # check strong password
 649                validation_regex_text = config['validation_regex']
 650
 651                validation_regex = re.compile(validation_regex_text)
 652
 653                m = validation_regex.match(update_user['password'])
 654
 655                if m is None:
 656                    return config['validation_warning']
 657
 658                m = hashlib.sha1()
 659                m.update(update_user['password'].encode('utf-8'))
 660                sha1_password = m.hexdigest()
 661
 662                # update password too
 663                result = user.filter(user.username == username).update({'password':sha1_password,'full_name': update_user['full_name'], 'organisation': update_user['organisation'], 'send_email_marketing': update_user['send_email_marketing'], 'send_email_job_notifications': update_user['send_email_job_notifications']})
 664            else:
 665                result = user.filter(user.username == username).update({'full_name': update_user['full_name'], 'organisation': update_user['organisation'], 'send_email_marketing': update_user['send_email_marketing'], 'send_email_job_notifications': update_user['send_email_job_notifications']})
 666
 667            db.commit()
 668            db.flush()
 669
 670            if result != 1:
 671                return "The update could not be saved"
 672
 673            return True
 674
 675        except:
 676            return "Error in this application in saving details"
 677
 678    @staticmethod
 679    def return_all_active_users(db):
 680        status_list = Stemformatics_Auth.get_status_dict_by_name()
 681        active_status = status_list['Active']
 682
 683        conn_string = config['psycopg2_conn_string']
 684        conn = psycopg2.connect(conn_string)
 685        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 686        sql = "select * from stemformatics.users where status= %(status_id)s ;"
 687        cursor.execute(sql,{'status_id': active_status})
 688
 689        # retrieve the records from the database
 690        result = cursor.fetchall()
 691        cursor.close()
 692        conn.close()
 693
 694        return result
 695
 696    @staticmethod
 697    def return_user_notifications(db): #CRITICAL-2
 698        db.schema = 'stemformatics'
 699        user = db.users
 700        result = db.users.filter(user.send_email_marketing == True).all()
 701        return result
 702
 703    @staticmethod
 704    def return_new_users(db,from_date): #CRITICAL-2
 705        db.schema = 'stemformatics'
 706        user = db.users
 707        result = db.users.filter(user.created >= from_date).all()
 708        return result
 709
 710
 711
 712    @staticmethod
 713    def check_stay_signed_in_md5(db,username,user_and_pwd_md5): #CRITICAL-2
 714        db.schema = 'stemformatics'
 715
 716        user = db.users
 717        if username is not None:
 718            username = username.lower()
 719        where = and_(user.username==username,user.status == 1)
 720        result = db.users.filter(where).all()
 721
 722        if len(result) != 1:
 723            return None
 724
 725        db_user = result[0]
 726
 727        sha1_password = db_user.password
 728
 729        h = hashlib.sha1()
 730        h.update(username.encode('utf-8') + sha1_password.encode('utf-8'))
 731        check_user_and_pwd_md5 = h.hexdigest()
 732
 733        if check_user_and_pwd_md5 == user_and_pwd_md5 :
 734            return db_user
 735        else:
 736            return None
 737
 738
 739
 740
 741    @staticmethod
 742    def create_stay_signed_in_md5(username,password): #CRITICAL-2
 743        username = username.lower()
 744        m = hashlib.sha1()
 745        m.update(password.encode('utf-8'))
 746        sha1_password = m.hexdigest()
 747
 748        h = hashlib.sha1()
 749        h.update(username.encode('utf-8') + sha1_password.encode('utf-8'))
 750        user_and_pwd_md5 = h.hexdigest()
 751
 752        return user_and_pwd_md5
 753
 754
 755
 756    @staticmethod
 757    def create_new_pending_user(db,username): #CRITICAL-2
 758
 759        username = username.lower()
 760
 761        # Story #179 have to check for users who are set as 0 or 1. If status of 2, then have to update and not create new user
 762        db.schema = 'stemformatics'
 763        where = and_(db.users.username==username)
 764        result = db.users.filter(where).all()
 765
 766        # check if username already available
 767        if len(result) == 1:
 768            return result[0]
 769
 770        # create new user
 771        result = db.users.insert(username=username,status=2)
 772        db.commit()
 773        db.flush()
 774
 775        where = and_(db.users.username==username)
 776        result = db.users.filter(where).all()
 777
 778        if len(result) != 1:
 779            return "The pending user could not be saved"
 780
 781        return result[0]
 782        #except:
 783        #   return "Error in this application in register_new_user"
 784
 785
 786    """
 787    This will check to see if the email already is assigned ot a user. If not it will create one and return the new user id.
 788    """
 789    @staticmethod
 790    def return_uid_from_email_for_sharing(db,email): #CRITICAL-2
 791        email = email.lower()
 792        return_user = Stemformatics_Auth.get_user_from_username(db,email)
 793        pending_user = False
 794        # if no uid then create one with status of 2 which is pending registration
 795        if return_user is None:
 796            # return the new user record
 797            new_user = Stemformatics_Auth.create_new_pending_user(db,email)
 798
 799            # if this is a string then something errored
 800            if isinstance(new_user,str):
 801                error_message = email + ": " + new_user + " "
 802                return error_message
 803            else:
 804                return_user_id = new_user.uid
 805                pending_user = True
 806        else:
 807            return_user_id = return_user.uid
 808            if return_user.status == 2:
 809                pending_user = True
 810
 811        return [return_user_id,pending_user]
 812
 813
 814    @staticmethod
 815    def update_user_status(db,uid,status): #CRITICAL-2
 816
 817        try:
 818
 819            db.schema = 'stemformatics'
 820            user = db.users
 821            where = and_(user.uid==uid)
 822            result = user.filter(where).all()
 823
 824            # check if username already available
 825            if len(result) != 1:
 826                return "There was an error finding this user"
 827
 828            result = user.filter(user.uid == uid).update({'status': status})
 829
 830            db.commit()
 831            db.flush()
 832
 833            if result != 1:
 834                return "The update could not be saved"
 835
 836            return True
 837
 838        except:
 839            return "Error in this application in saving details"
 840
 841    ''' datasets is a list of integers'''
 842    @staticmethod
 843    def save_multi_datasets(db,uid,db_id,datasets): #CRITICAL-2
 844
 845        md_name = 'multi_datasets_view_'+str(db_id)
 846        # turn list of integers into string comma separated list
 847        md_value = str(datasets).strip('[]').replace(' ','')
 848
 849        db.schema = 'stemformatics'
 850        u = db.users
 851        umd = db.users_metadata
 852
 853        where = and_(u.uid==uid)
 854        result = u.filter(where).all()
 855
 856        # check if user available
 857        if len(result) != 1:
 858            return "No user found"
 859
 860
 861        where = and_(umd.uid==uid,umd.md_name==md_name)
 862        result = umd.filter(where).all()
 863
 864        # check if user available
 865        if len(result) == 0:
 866            result_insert = umd.insert(uid=uid,md_name=md_name,md_value=md_value)
 867        else:
 868            umd.filter(where).update({'md_value':md_value})
 869
 870        db.commit()
 871        db.flush()
 872
 873
 874        return True
 875
 876
 877    @staticmethod
 878    def get_publish_gene_set_email_address():
 879        return config['publish_gene_set_email_address']
 880
 881
 882    @staticmethod
 883    def get_multi_datasets(db,uid,db_id): #CRITICAL-2
 884
 885        md_name = 'multi_datasets_view_'+str(db_id)
 886        db.schema = 'stemformatics'
 887        umd = db.users_metadata
 888
 889        where = and_(umd.uid==uid,umd.md_name==md_name)
 890
 891        try:
 892            result = umd.filter(where).one()
 893        except:
 894            return []
 895
 896        temp_md_value = result.md_value.split(',')
 897
 898        datasets = [ int(i) for i in temp_md_value ]
 899
 900        return datasets
 901
 902    # Method for making the dataset list to a dictionary of the keys
 903    @staticmethod
 904    def get_dict_users_private_datasets_metadata(ds_list):
 905        ds_id_list = []
 906        ds_attribute_list = ['Title', 'Organism']
 907        ds_dict = {}
 908
 909        # Makes a list of ds_id's to search metadata and filters out the duplicate entries by
 910        # overriding group permissions with user permissions.
 911        for ds_row in ds_list:
 912            ds_id = ds_row[0]
 913            status = ds_row[1]
 914            permissions = ds_row[2]
 915            try:
 916                tmp = ds_dict[ds_id]
 917                ds_id_list.append(ds_id)
 918            except:
 919                ds_dict[ds_id] = {}
 920                ds_id_list.append(ds_id)
 921
 922            ds_dict[ds_id]['status'] = status
 923            ds_dict[ds_id]['permissions'] = permissions
 924
 925        # Get the metadata based on the ds_id's collected
 926        conn_string = config['psycopg2_conn_string']
 927        conn = psycopg2.connect(conn_string)
 928        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 929
 930        # Joins the metadata table and the datasets table to get the tags above whether or not
 931        # it is a private dataset
 932        sql = "select  dm.ds_id, dm.ds_name, ds.handle, dm.ds_value, ds.private from dataset_metadata as dm left join datasets as ds on (dm.ds_id = ds.id) where dm.ds_name = any(%s) and dm.ds_id = any(%s);"
 933
 934        cursor.execute(sql,(ds_attribute_list,ds_id_list,))
 935        metadata = cursor.fetchall()
 936        cursor.close()
 937        conn.close()
 938
 939        #Add the information from the metadata dict to the dict containing the privalges and status
 940        for ds_row in metadata:
 941            ds_id = ds_row[0]
 942            ds_attribute = ds_row[1]
 943            attribute_val = ds_row[3]
 944            ds_dict[ds_id][ds_attribute] = attribute_val
 945            ds_dict[ds_id]["handle"] = ds_row[2]
 946            ds_dict[ds_id]["private"] = ds_row[4]
 947
 948        return ds_dict
 949
 950    # Method for getting private datasets, access and privleges for
 951    @staticmethod
 952    def get_list_users_private_datasets(uid):
 953        # Checks that the user id isn't going to cause an error
 954        if not isinstance(uid, int) or uid < 0:
 955            return None
 956
 957        conn_string = config['psycopg2_conn_string']
 958        conn = psycopg2.connect(conn_string)
 959        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 960
 961        # Makes a join on the private overrides table and group privileges table on a user and gives
 962        # the private datasets a user has access to either under group or user privileges
 963        sql = "select ds_id,o.role,o.object_type from stemformatics.override_private_datasets as o left join stemformatics.group_users as gu on o.object_id = CAST(gu.gid as TEXT) where (o.object_type = 'Group' and gu.uid = %s) or (o.object_type = 'User' and o.object_id = %s) order by object_type;"
 964
 965        cursor.execute(sql,(uid,str(uid),))
 966        result = cursor.fetchall()
 967        cursor.close()
 968        conn.close()
 969
 970        return result
 971
 972
 973
 974    @staticmethod
 975    def get_groups_for_uid(db,uid,role): #CRITICAL-2
 976        public_list = [0]
 977
 978        if not isinstance( uid, int ):
 979            return public_list # at least return public
 980
 981        if not isinstance( role, str) and not isinstance(role, bytes):
 982            role = '' # set role to none
 983
 984        if uid == 0:
 985            return public_list
 986
 987        if role in ['admin','annotator']:
 988
 989            conn_string = config['psycopg2_conn_string']
 990            conn = psycopg2.connect(conn_string)
 991            cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
 992            sql = "select * from stemformatics.groups;"
 993            cursor.execute(sql)
 994            result = cursor.fetchall()
 995            cursor.close()
 996            conn.close()
 997
 998            groups = [ row['gid'] for row in result ]
 999
1000
1001        else:
1002
1003            conn_string = config['psycopg2_conn_string']
1004            conn = psycopg2.connect(conn_string)
1005            cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1006            sql = "select * from stemformatics.group_users where uid = %s;"
1007            cursor.execute(sql,(uid,))
1008            result = cursor.fetchall()
1009            cursor.close()
1010            conn.close()
1011
1012            groups = [ row['gid'] for row in result ]
1013
1014        if 0 not in groups:
1015            groups.append(0) # public group
1016
1017        return sorted(groups)
1018
1019    @staticmethod
1020    def add_group(db,group_name): #CRITICAL-2
1021        db.schema = 'stemformatics'
1022        g = db.groups
1023        result = g.insert(group_name=group_name)
1024        db.commit()
1025        db.flush()
1026        return True
1027
1028
1029    @staticmethod
1030    def get_all_group_names(db): #CRITICAL-2
1031
1032        conn_string = config['psycopg2_conn_string']
1033        conn = psycopg2.connect(conn_string)
1034        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1035        sql = "select * from stemformatics.groups;"
1036        cursor.execute(sql)
1037        result = cursor.fetchall()
1038        cursor.close()
1039        conn.close()
1040
1041        group_names_dict = {}
1042        for group in result:
1043            gid = group['gid']
1044            group_name = group['group_name']
1045            group_names_dict[gid] = group_name
1046
1047        return group_names_dict
1048
1049    @staticmethod
1050    def get_ucsc_links_for_uid(db,uid,db_id): #CRITICAL-2
1051
1052        ucsc_links = {}
1053        if uid is None or not isinstance(uid, int):
1054            return ucsc_links
1055
1056
1057        conn_string = config['psycopg2_conn_string']
1058        conn = psycopg2.connect(conn_string)
1059        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1060        sql = "select gid from stemformatics.group_users where uid = %s;"
1061        cursor.execute(sql,(uid,))
1062        result = cursor.fetchall()
1063        cursor.close()
1064        conn.close()
1065
1066        gids = [0]  # Public group has 0 gid
1067        for row in result:
1068            gids.append(row['gid'])
1069
1070        conn = psycopg2.connect(conn_string)
1071        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1072        sql ="select gc.config_name as link_name,gc.config_value as url,gc.db_id,g.gid, g.group_name from stemformatics.group_configs as gc left join stemformatics.groups as g on g.gid = gc.gid where gc.gid = ANY (%s) and gc.db_id = %s and gc.config_type = 'UCSC Links';"
1073        cursor.execute(sql,(gids,db_id,))
1074        # retrieve the records from the database
1075        result = cursor.fetchall()
1076        cursor.close()
1077        conn.close()
1078        ucsc_links = {}
1079        for row in result:
1080            gid = row['gid']
1081            key_name = row['link_name'] + str(gid)
1082            ucsc_links[key_name] = {}
1083            ucsc_links[key_name]['link_name'] = row['link_name']
1084            ucsc_links[key_name]['url'] = row['url']
1085            ucsc_links[key_name]['db_id'] = db_id
1086            ucsc_links[key_name]['gid'] = gid
1087            ucsc_links[key_name]['group_name'] = row['group_name']
1088
1089        return ucsc_links
1090
1091    @staticmethod
1092    def add_user_to_group(db,uid,gid): #CRITICAL-2
1093        db.schema = 'stemformatics'
1094        gu = db.group_users
1095        # check if already there
1096        result_check = gu.filter(and_(gu.gid==gid,gu.uid==uid)).all()
1097        if len(result_check) == 0:
1098            # then create if already there
1099            result = gu.insert(gid=gid,uid=uid,role='User')
1100            Stemformatics_Auth.triggers_for_change_in_user(db,uid = None)
1101            db.commit()
1102            db.flush()
1103            return True
1104        else:
1105            return False
1106
1107
1108    @staticmethod
1109    def get_all_group_users(db): #CRITICAL-2
1110        db.schema = 'stemformatics'
1111        u = db.users
1112        gu = db.with_labels(db.group_users)
1113        join = db.join(gu,u,(gu.stemformatics_group_users_uid == u.uid))
1114        result = [ {'uid':row.uid,'gid':row.stemformatics_group_users_gid,'role':row.role, 'username':row.username,'status':row.status}  for row in join.all() ]
1115        return result
1116
1117    @staticmethod
1118    def hierarchy_roles(current_role,role): #CRITICAL-2
1119        new_role = current_role
1120        if role != current_role:
1121            if role == "admin":
1122                new_role = role
1123            else:
1124                if role == "annotator" and current_role != "admin":
1125                    new_role = role
1126                else:
1127                    if role == "view":
1128                        new_role = role
1129
1130        return new_role
1131
1132    @staticmethod
1133    def setup_dict_uid_permissions(db): #CRITICAL-2
1134        db.schema = 'stemformatics'
1135        o = db.override_private_datasets
1136        g = db.group_users
1137        dict_uid_permissions = {}
1138
1139        group_dict = {}
1140        all_group_users = g.all()
1141        for row in all_group_users:
1142            uid = row.uid
1143            gid = row.gid
1144            if gid not in group_dict:
1145                group_dict[gid] = []
1146            group_dict[gid].append(uid)
1147
1148
1149        # the order by means that Group comes before User,
1150        # so that even though a user is part of a group
1151        # we can give that user annotator rights
1152        all_overrides = o.order_by(o.object_type).all()
1153        for override_row in all_overrides:
1154            object_type = override_row.object_type
1155            object_id = override_row.object_id
1156            role = override_row.role
1157            ds_id = override_row.ds_id
1158            if object_type == "User":
1159                uid = int(object_id)
1160                if uid not in dict_uid_permissions:
1161                    dict_uid_permissions[uid] = {}
1162                if ds_id not in dict_uid_permissions[uid]:
1163                    dict_uid_permissions[uid][ds_id] = ""
1164
1165                current_role =dict_uid_permissions[uid][ds_id]
1166                dict_uid_permissions[uid][ds_id] = Stemformatics_Auth.hierarchy_roles(current_role,role)
1167
1168            if object_type == "Group":
1169                gid = int(object_id)
1170                users_for_group = group_dict[gid]
1171                for uid in users_for_group:
1172                    if uid not in dict_uid_permissions:
1173                        dict_uid_permissions[uid] = {}
1174                    if ds_id not in dict_uid_permissions[uid]:
1175                        dict_uid_permissions[uid][ds_id] = ""
1176
1177                    current_role = dict_uid_permissions[uid][ds_id]
1178                    dict_uid_permissions[uid][ds_id] = Stemformatics_Auth.hierarchy_roles(current_role,role)
1179
1180
1181        return dict_uid_permissions
1182
1183
1184    @staticmethod
1185    def get_dict_of_user_dataset_availability(db): #CRITICAL-2
1186        db.schema = 'public'
1187        ds = db.datasets
1188        db.schema = 'stemformatics'
1189        u = db.users
1190        all_ds = ds.all()
1191        all_users = u.all()
1192
1193        # this is the permissions that are per dataset/uid or dataset/group
1194        uid_permissions = Stemformatics_Auth.setup_dict_uid_permissions(db)
1195
1196        list_of_user_dataset_availability = {}
1197        for user_row in all_users:
1198            uid = user_row.uid
1199            role = user_row.role
1200            list_of_user_dataset_availability[uid] = {}
1201
1202            for ds_row in all_ds:
1203                ds_id = ds_row.id
1204                if role =="admin":
1205                    status_for_this_user = "Admin"
1206                else:
1207                    if role =="annotator":
1208                        status_for_this_user = "Annotate"
1209                    else:
1210                        status_for_this_user = Stemformatics_Auth.calculate_dataset_status(uid,ds_row,uid_permissions)
1211                list_of_user_dataset_availability[uid][ds_id] = status_for_this_user
1212
1213
1214        return list_of_user_dataset_availability
1215
1216    """ assumption is that uid is not an admin as this was checked beforehand """
1217    @staticmethod
1218    def calculate_dataset_status(uid,ds_row,uid_permissions):
1219        status_for_this_user = "Unavailable"
1220        ds_id = ds_row.id
1221        try:
1222            permission = uid_permissions[uid][ds_id]
1223        except:
1224            permission = None
1225
1226        if not ds_row.published:
1227            if permission == "admin":
1228                status_for_this_user = "Admin"
1229            if permission == "annotator":
1230                status_for_this_user = "Annotate"
1231        else:
1232            if ds_row.private:
1233
1234                if ds_row.show_limited:
1235                    if permission == "admin" :
1236                        status_for_this_user = "Admin"
1237                    else:
1238                        if permission == "annotator":
1239                            status_for_this_user = "Annotate"
1240                        else:
1241                            status_for_this_user = "Limited"
1242
1243                else:
1244                    if permission == "admin":
1245                        status_for_this_user = "Admin"
1246                    if permission == "view":
1247                        status_for_this_user = "Available"
1248                    if permission == "annotator":
1249                        status_for_this_user = "Annotate"
1250            else:
1251                status_for_this_user = "Available"
1252
1253        return status_for_this_user
1254
1255    @staticmethod
1256    def setup_redis_get_dict_of_user_dataset_availability(db):
1257        delimiter = config['redis_delimiter']
1258
1259        data_result = Stemformatics_Auth.get_dict_of_user_dataset_availability(db)
1260        guest_username = config['guest_username']
1261        db_user = Stemformatics_Auth.get_user_from_username(db,guest_username)
1262        guest_uid = db_user.uid
1263
1264        for uid in data_result:
1265            # for non-logged in users
1266            if uid == guest_uid:
1267                label_name = "user_dataset_availability"+delimiter+str(0)
1268                label_value = json.dumps(data_result[uid])
1269                r_server.set(label_name,label_value)
1270
1271
1272
1273            label_name = "user_dataset_availability"+delimiter+str(uid)
1274            label_value = json.dumps(data_result[uid])
1275            r_server.set(label_name,label_value)
1276
1277    @staticmethod
1278    def triggers_for_change_in_user(db,uid = None):
1279        Stemformatics_Auth.setup_redis_get_dict_of_user_dataset_availability(db)
1280
1281
1282    @staticmethod
1283    def send_email_for_pending_user(db,uid): #CRITICAL-2 #CRITICAL-6
1284        magic_globals.fetch()
1285        c = magic_globals.c
1286
1287        db.schema = 'stemformatics'
1288        users = db.users
1289        user = users.filter(users.uid==uid).one()
1290        from_email = config['from_email']
1291        to_email = user.username
1292        subject = c.site_name+" Pending User"
1293        feedback_email = config['feedback_email']
1294        external_base_url = url('/',qualified=True)
1295
1296        full_name = user.full_name
1297        username = user.username
1298        registration_url = external_base_url+url('auth/register?username=')+username
1299
1300        from S4M_pyramid.model.stemformatics.stemformatics_dataset import Stemformatics_Dataset
1301        dataset_names = ""
1302        datasets = Stemformatics_Dataset.getChooseDatasetDetails(db,uid)
1303        for ds_id in datasets:
1304            if datasets[ds_id]['private']:
1305                handle = datasets[ds_id]['handle']
1306                authors = datasets[ds_id]['name']
1307                title = datasets[ds_id]['title']
1308                dataset_names += "- "+title + " (" + authors + "). In "+c.site_name+" this is called " + handle  + ".\n"
1309
1310        feedback_email = config['feedback_email']
1311        body = "Hello %s, you have a pending user in %s that was created for you to get access to private datasets:\n\n%s\n\nBut first, you will need to register.  It is important that you use the email specified as your username. Click here to register: %s \n\nIf you have any questions or comments, please email us at %s " % (full_name,c.site_name,dataset_names,registration_url,feedback_email)
1312
1313        # raise Error
1314        # Send the message via our own SMTP server, but don't include the
1315        # envelope header.
1316        from S4M_pyramid.model.stemformatics.stemformatics_notification import Stemformatics_Notification # wouldn't work otherwise??
1317
1318        success = Stemformatics_Notification.send_email(from_email,to_email,subject,body)
1319        return success
1320
1321    @staticmethod
1322    def change_user_role_for_ds(db,ds_id,object_type,object_id,role):
1323
1324
1325
1326        ds_id = int(ds_id)
1327        object_id = str(object_id)
1328        conn_string = config['psycopg2_conn_string']
1329        conn = psycopg2.connect(conn_string)
1330        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1331
1332        cursor.execute("select * from stemformatics.override_private_datasets where ds_id = %s and object_type = %s and object_id = %s;",(ds_id,object_type,object_id))
1333
1334        result = cursor.fetchall()
1335        cursor.close()
1336        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1337
1338        if len(result) == 0:
1339            cursor.execute("insert into stemformatics.override_private_datasets (ds_id,uid,role,object_type,object_id) values (%s,%s,%s,%s,%s);",(ds_id,0,role,object_type,object_id))
1340        else:
1341            cursor.execute("update stemformatics.override_private_datasets set role = %s where ds_id = %s and object_type = %s and object_id = %s;",(role,ds_id,object_type,object_id))
1342
1343
1344        # retrieve the records from the database
1345        conn.commit()
1346        cursor.close()
1347        conn.close()
1348        return "Success"
1349
1350
1351    @staticmethod
1352    def get_user_role(db,uid): #CRITICAL-2
1353        if isinstance(uid,int):
1354            try:
1355                conn_string = config['psycopg2_conn_string']
1356                conn = psycopg2.connect(conn_string)
1357                cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1358                cursor.execute("select role from stemformatics.users where uid = %s;",(uid,))
1359                # retrieve the records from the database
1360                result = cursor.fetchall()
1361                cursor.close()
1362                conn.close()
1363                return result[0][0]
1364            except:
1365                return None
1366        else:
1367            return None
1368
1369    @staticmethod
1370    def get_number_of_active_users():
1371        conn_string = config['psycopg2_conn_string']
1372        conn = psycopg2.connect(conn_string)
1373        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1374        cursor.execute("select count(*) from stemformatics.users where status = 1;")
1375        # retrieve the records from the database
1376        result = cursor.fetchall()
1377        cursor.close()
1378        conn.close()
1379        number_of_active_users = result[0][0]
1380        return number_of_active_users
1381
1382    @staticmethod
1383    def create_base_export_key(uid):
1384        conn_string = config['psycopg2_conn_string']
1385        conn = psycopg2.connect(conn_string)
1386        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1387        cursor.execute("select * from stemformatics.users where uid = %s;",(uid,))
1388        # retrieve the records from the database
1389        result = cursor.fetchall()
1390        cursor.close()
1391        conn.close()
1392
1393        if len(result) ==1:
1394            username = result[0]['username']
1395            date_stamp = result[0]['created']
1396
1397            h = hashlib.sha1()
1398            h.update((date_stamp.strftime('%Y-%m-%d') + username + str(uid)).encode('utf-8'))
1399            base_export_key = h.hexdigest()
1400
1401
1402            conn = psycopg2.connect(conn_string)
1403            cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1404            cursor.execute("update stemformatics.users set base_export_key = %s where uid = %s;",(base_export_key,uid,))
1405            conn.commit()
1406            cursor.close()
1407            conn.close()
1408
1409            return True
1410        else:
1411            return False
1412
1413    @staticmethod
1414    def create_export_key(uid):
1415        """
1416        get uid and username
1417        create md5 value to return
1418        """
1419
1420        conn_string = config['psycopg2_conn_string']
1421        conn = psycopg2.connect(conn_string)
1422        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1423        cursor.execute("select username,base_export_key from stemformatics.users where uid = %s;",(uid,))
1424        # retrieve the records from the database
1425        result = cursor.fetchall()
1426        cursor.close()
1427        conn.close()
1428
1429        if len(result) ==1:
1430            username = result[0]['username']
1431            base_export_key = result[0]['base_export_key']
1432            server_name=url('/',qualified=True)
1433            h = hashlib.sha1()
1434            h.update((datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') + username + str(uid)).encode('utf-8'))
1435            export_key = h.hexdigest()
1436
1437            conn = psycopg2.connect(conn_string)
1438            cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1439            cursor.execute("insert into stemformatics.export_key values (%s, %s) ;",(uid,export_key))
1440            conn.commit()
1441            cursor.close()
1442            conn.close()
1443
1444            return export_key
1445        else:
1446            return None
1447
1448
1449    @staticmethod
1450    def validate_export_key(export_key,uid):
1451        conn_string = config['psycopg2_conn_string']
1452        conn = psycopg2.connect(conn_string)
1453        cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
1454        cursor.execute("select date_created from stemformatics.export_key where uid = %s and key = %s;",(uid,export_key,))
1455        # retrieve the records from the database
1456        result = cursor.fetchall()
1457        cursor.close()
1458        conn.close()
1459
1460        if len(result) ==1:
1461            date_created = result[0]['date_created']
1462            export_key_validity = int(config['export_key_validity'])
1463            expiry_time = date_created + datetime.timedelta(days=export_key_validity)
1464            current_date = datetime.datetime.now()
1465            if current_date <= expiry_time:
1466                return True
1467            return False
1468        else:
1469            return False
1470
1471
1472    @staticmethod
1473    def get_gid_by_name(group_name):
1474
1475        if not isinstance( group_name, str ) and not isinstance(group_name,bytes):
1476            return False
1477
1478
1479        conn_string = config['psycopg2_conn_string']
1480        conn = psycopg2.connect(conn_string)
1481        cursor = conn.cursor(cursor_factory=psycopg2.ext

Large files files are truncated, but you can click here to view the full file