<s> import json <EOL> import uuid <EOL> import copy <EOL> import logging <EOL> from pynamodb . exceptions import PutError <EOL> from flask import request <EOL> from flask import jsonify <EOL> from botocore . exceptions import ClientError <EOL> from confidant import app <EOL> from confidant import iam <EOL> from confidant import keymanager <EOL> from confidant import authnz <EOL> from confidant import stats <EOL> from confidant import graphite <EOL> from confidant . ciphermanager import CipherManager <EOL> from confidant . models . credential import Credential <EOL> from confidant . models . service import Service <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' , '<STR_LIT:POST>' ] ) <EOL> @ authnz . require_auth <EOL> def get_user_info ( ) : <EOL> '''<STR_LIT>''' <EOL> response = jsonify ( { '<STR_LIT:email>' : authnz . get_logged_in_user_email ( ) } ) <EOL> response . set_cookie ( '<STR_LIT>' , authnz . get_csrf_token ( ) ) <EOL> return response <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_service_list ( ) : <EOL> services = [ ] <EOL> for service in Service . data_type_date_index . query ( '<STR_LIT>' ) : <EOL> services . append ( { <EOL> '<STR_LIT:id>' : service . id , <EOL> '<STR_LIT>' : service . enabled , <EOL> '<STR_LIT>' : service . revision , <EOL> '<STR_LIT>' : service . modified_date , <EOL> '<STR_LIT>' : service . modified_by <EOL> } ) <EOL> return jsonify ( { '<STR_LIT>' : services } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_iam_roles_list ( ) : <EOL> try : <EOL> roles = [ x . name for x in iam . roles . all ( ) ] <EOL> except ClientError : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> return jsonify ( { '<STR_LIT>' : roles } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_service ( id ) : <EOL> '''<STR_LIT>''' <EOL> if authnz . user_in_role ( '<STR_LIT>' ) and not authnz . user_is_service ( id ) : <EOL> logging . warning ( '<STR_LIT>' . format ( id ) ) <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> logging . debug ( '<STR_LIT>' . format ( id ) ) <EOL> try : <EOL> service = Service . get ( id ) <EOL> except Service . DoesNotExist : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> if ( service . data_type != '<STR_LIT>' and <EOL> service . data_type != '<STR_LIT>' ) : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> try : <EOL> credentials = _get_credentials ( service . credentials ) <EOL> except KeyError : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : service . id , <EOL> '<STR_LIT>' : credentials , <EOL> '<STR_LIT>' : service . enabled , <EOL> '<STR_LIT>' : service . revision , <EOL> '<STR_LIT>' : service . modified_date , <EOL> '<STR_LIT>' : service . modified_by <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_archive_service_revisions ( id ) : <EOL> try : <EOL> service = Service . get ( id ) <EOL> except Service . DoesNotExist : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> if ( service . data_type != '<STR_LIT>' and <EOL> service . data_type != '<STR_LIT>' ) : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> revisions = [ ] <EOL> _range = range ( <NUM_LIT:1> , service . revision + <NUM_LIT:1> ) <EOL> ids = [ ] <EOL> for i in _range : <EOL> ids . append ( "<STR_LIT>" . format ( id , i ) ) <EOL> for revision in Service . batch_get ( ids ) : <EOL> revisions . append ( { <EOL> '<STR_LIT:id>' : revision . id , <EOL> '<STR_LIT>' : revision . revision , <EOL> '<STR_LIT>' : revision . enabled , <EOL> '<STR_LIT>' : list ( revision . credentials ) , <EOL> '<STR_LIT>' : revision . modified_date , <EOL> '<STR_LIT>' : revision . modified_by <EOL> } ) <EOL> return jsonify ( { <EOL> '<STR_LIT>' : sorted ( <EOL> revisions , <EOL> key = lambda k : k [ '<STR_LIT>' ] , <EOL> reverse = True <EOL> ) <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_archive_service_list ( ) : <EOL> services = [ ] <EOL> for service in Service . data_type_date_index . query ( <EOL> '<STR_LIT>' , scan_index_forward = False ) : <EOL> services . append ( { <EOL> '<STR_LIT:id>' : service . id , <EOL> '<STR_LIT>' : service . revision , <EOL> '<STR_LIT>' : service . enabled , <EOL> '<STR_LIT>' : list ( service . credentials ) , <EOL> '<STR_LIT>' : service . modified_date , <EOL> '<STR_LIT>' : service . modified_by <EOL> } ) <EOL> return jsonify ( { '<STR_LIT>' : services } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT>' ] ) <EOL> @ authnz . require_auth <EOL> @ authnz . require_csrf_token <EOL> def ensure_grants ( id ) : <EOL> try : <EOL> _service = Service . get ( id ) <EOL> if _service . data_type != '<STR_LIT>' : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> except Service . DoesNotExist : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> try : <EOL> keymanager . ensure_grants ( id ) <EOL> except keymanager . ServiceCreateGrantError : <EOL> msg = '<STR_LIT>' <EOL> logging . error ( msg ) <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> try : <EOL> grants = keymanager . grants_exist ( id ) <EOL> except keymanager . ServiceGetGrantError : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : id , <EOL> '<STR_LIT>' : grants <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_grants ( id ) : <EOL> try : <EOL> _service = Service . get ( id ) <EOL> if _service . data_type != '<STR_LIT>' : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> except Service . DoesNotExist : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> try : <EOL> grants = keymanager . grants_exist ( id ) <EOL> except keymanager . ServiceGetGrantError : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : id , <EOL> '<STR_LIT>' : grants <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT>' ] ) <EOL> @ authnz . require_auth <EOL> @ authnz . require_csrf_token <EOL> def map_service_credentials ( id ) : <EOL> data = request . get_json ( ) <EOL> try : <EOL> _service = Service . get ( id ) <EOL> if _service . data_type != '<STR_LIT>' : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> revision = _service . revision + <NUM_LIT:1> <EOL> _service_credential_ids = _service . credentials <EOL> except Service . DoesNotExist : <EOL> revision = <NUM_LIT:1> <EOL> _service_credential_ids = [ ] <EOL> if data . get ( '<STR_LIT>' ) : <EOL> conflicts = _pair_key_conflicts_for_credentials ( <EOL> copy . deepcopy ( data [ '<STR_LIT>' ] ) <EOL> ) <EOL> if conflicts : <EOL> ret = { <EOL> '<STR_LIT:error>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : conflicts <EOL> } <EOL> return jsonify ( ret ) , <NUM_LIT> <EOL> if revision == <NUM_LIT:1> : <EOL> try : <EOL> keymanager . ensure_grants ( id ) <EOL> except keymanager . ServiceCreateGrantError : <EOL> msg = '<STR_LIT>' . format ( id ) <EOL> logging . error ( msg ) <EOL> try : <EOL> Service ( <EOL> id = '<STR_LIT>' . format ( id , revision ) , <EOL> data_type = '<STR_LIT>' , <EOL> credentials = data . get ( '<STR_LIT>' ) , <EOL> enabled = data . get ( '<STR_LIT>' ) , <EOL> revision = revision , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) . save ( id__null = True ) <EOL> except PutError as e : <EOL> logging . error ( e ) <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> try : <EOL> service = Service ( <EOL> id = id , <EOL> data_type = '<STR_LIT>' , <EOL> credentials = data [ '<STR_LIT>' ] , <EOL> enabled = data . get ( '<STR_LIT>' ) , <EOL> revision = revision , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) <EOL> service . save ( ) <EOL> except PutError as e : <EOL> logging . error ( e ) <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> added = list ( set ( service . credentials ) - set ( _service_credential_ids ) ) <EOL> removed = list ( set ( _service_credential_ids ) - set ( service . credentials ) ) <EOL> msg = '<STR_LIT>' <EOL> msg = msg . format ( added , removed , service . revision ) <EOL> graphite . send_event ( [ id ] , msg ) <EOL> try : <EOL> credentials = _get_credentials ( service . credentials ) <EOL> except KeyError : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : service . id , <EOL> '<STR_LIT>' : credentials , <EOL> '<STR_LIT>' : service . revision , <EOL> '<STR_LIT>' : service . enabled , <EOL> '<STR_LIT>' : service . modified_date , <EOL> '<STR_LIT>' : service . modified_by <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_credential_list ( ) : <EOL> credentials = [ ] <EOL> for cred in Credential . data_type_date_index . query ( '<STR_LIT>' ) : <EOL> credentials . append ( { <EOL> '<STR_LIT:id>' : cred . id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . modified_date , <EOL> '<STR_LIT>' : cred . modified_by <EOL> } ) <EOL> return jsonify ( { '<STR_LIT>' : credentials } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_credential ( id ) : <EOL> try : <EOL> cred = Credential . get ( id ) <EOL> except Credential . DoesNotExist : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> if ( cred . data_type != '<STR_LIT>' and <EOL> cred . data_type != '<STR_LIT>' ) : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> services = [ ] <EOL> for service in Service . data_type_date_index . query ( '<STR_LIT>' ) : <EOL> services . append ( service . id ) <EOL> if cred . data_type == '<STR_LIT>' : <EOL> context = id <EOL> else : <EOL> context = id . split ( '<STR_LIT:->' ) [ <NUM_LIT:0> ] <EOL> data_key = keymanager . decrypt_key ( <EOL> cred . data_key , <EOL> encryption_context = { '<STR_LIT:id>' : context } <EOL> ) <EOL> cipher_version = cred . cipher_version <EOL> cipher = CipherManager ( data_key , cipher_version ) <EOL> _credential_pairs = cipher . decrypt ( cred . credential_pairs ) <EOL> _credential_pairs = json . loads ( _credential_pairs ) <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : _credential_pairs , <EOL> '<STR_LIT>' : services , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . modified_date , <EOL> '<STR_LIT>' : cred . modified_by <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_archive_credential_revisions ( id ) : <EOL> try : <EOL> cred = Credential . get ( id ) <EOL> except Credential . DoesNotExist : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> if ( cred . data_type != '<STR_LIT>' and <EOL> cred . data_type != '<STR_LIT>' ) : <EOL> return jsonify ( { } ) , <NUM_LIT> <EOL> revisions = [ ] <EOL> _range = range ( <NUM_LIT:1> , cred . revision + <NUM_LIT:1> ) <EOL> ids = [ ] <EOL> for i in _range : <EOL> ids . append ( "<STR_LIT>" . format ( id , i ) ) <EOL> for revision in Credential . batch_get ( ids ) : <EOL> revisions . append ( { <EOL> '<STR_LIT:id>' : revision . id , <EOL> '<STR_LIT:name>' : revision . name , <EOL> '<STR_LIT>' : revision . revision , <EOL> '<STR_LIT>' : revision . enabled , <EOL> '<STR_LIT>' : revision . modified_date , <EOL> '<STR_LIT>' : revision . modified_by <EOL> } ) <EOL> return jsonify ( { <EOL> '<STR_LIT>' : sorted ( <EOL> revisions , <EOL> key = lambda k : k [ '<STR_LIT>' ] , <EOL> reverse = True <EOL> ) <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_archive_credential_list ( ) : <EOL> credentials = [ ] <EOL> for cred in Credential . data_type_date_index . query ( <EOL> '<STR_LIT>' , scan_index_forward = False ) : <EOL> credentials . append ( { <EOL> '<STR_LIT:id>' : cred . id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . modified_date , <EOL> '<STR_LIT>' : cred . modified_by <EOL> } ) <EOL> return jsonify ( { '<STR_LIT>' : credentials } ) <EOL> def _get_credentials ( credential_ids ) : <EOL> credentials = [ ] <EOL> with stats . timer ( '<STR_LIT>' ) : <EOL> for cred in Credential . batch_get ( credential_ids ) : <EOL> data_key = keymanager . decrypt_key ( <EOL> cred . data_key , <EOL> encryption_context = { '<STR_LIT:id>' : cred . id } <EOL> ) <EOL> cipher_version = cred . cipher_version <EOL> cipher = CipherManager ( data_key , cipher_version ) <EOL> _credential_pairs = cipher . decrypt ( cred . credential_pairs ) <EOL> _credential_pairs = json . loads ( _credential_pairs ) <EOL> credentials . append ( { <EOL> '<STR_LIT:id>' : cred . id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : _credential_pairs <EOL> } ) <EOL> return credentials <EOL> def _pair_key_conflicts_for_credentials ( credential_ids ) : <EOL> conflicts = { } <EOL> pair_keys = { } <EOL> credentials = _get_credentials ( credential_ids ) <EOL> for credential in credentials : <EOL> for key in credential [ '<STR_LIT>' ] : <EOL> if key in pair_keys : <EOL> pair_keys [ key ] . append ( credential [ '<STR_LIT:id>' ] ) <EOL> else : <EOL> pair_keys [ key ] = [ credential [ '<STR_LIT:id>' ] ] <EOL> for key , ids in pair_keys . iteritems ( ) : <EOL> if len ( ids ) > <NUM_LIT:1> : <EOL> conflicts [ key ] = { '<STR_LIT>' : ids } <EOL> return conflicts <EOL> def _get_services_for_credential ( _id ) : <EOL> services = [ ] <EOL> for service in Service . data_type_date_index . query ( '<STR_LIT>' ) : <EOL> if _id in service . credentials : <EOL> services . append ( service ) <EOL> return services <EOL> def _check_credential_pair_uniqueness ( <EOL> credential_pairs , _id = None , services = None <EOL> ) : <EOL> for key , val in credential_pairs . iteritems ( ) : <EOL> if isinstance ( val , dict ) or isinstance ( val , list ) : <EOL> ret = { '<STR_LIT:error>' : '<STR_LIT>' } <EOL> return ( False , ret ) <EOL> return ( True , { } ) <EOL> def _pair_key_conflicts_for_services ( _id , credential_pairs , services ) : <EOL> conflicts = { } <EOL> service_map = { } <EOL> for service in services : <EOL> for credential in service . credentials : <EOL> if credential in service_map : <EOL> service_map [ credential ] . append ( service . id ) <EOL> else : <EOL> service_map [ credential ] = [ service . id ] <EOL> credential_ids = service_map . keys ( ) <EOL> if _id in credential_ids : <EOL> credential_ids . remove ( _id ) <EOL> credentials = _get_credentials ( credential_ids ) <EOL> pair_keys = credential_pairs . keys ( ) <EOL> for credential in credentials : <EOL> services = service_map [ credential [ '<STR_LIT:id>' ] ] <EOL> for key in pair_keys : <EOL> if key in credential [ '<STR_LIT>' ] : <EOL> if key not in conflicts : <EOL> conflicts [ key ] = { <EOL> '<STR_LIT>' : [ credential [ '<STR_LIT:id>' ] ] , <EOL> '<STR_LIT>' : services <EOL> } <EOL> else : <EOL> conflicts [ key ] [ '<STR_LIT>' ] . extend ( services ) <EOL> conflicts [ key ] [ '<STR_LIT>' ] . append ( credential [ '<STR_LIT:id>' ] ) <EOL> conflicts [ key ] [ '<STR_LIT>' ] = list ( <EOL> set ( conflicts [ key ] [ '<STR_LIT>' ] ) <EOL> ) <EOL> conflicts [ key ] [ '<STR_LIT>' ] = list ( <EOL> set ( conflicts [ key ] [ '<STR_LIT>' ] ) <EOL> ) <EOL> return conflicts <EOL> def _lowercase_credential_pairs ( credential_pairs ) : <EOL> return { i . lower ( ) : j for i , j in credential_pairs . iteritems ( ) } <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:POST>' ] ) <EOL> @ authnz . require_auth <EOL> @ authnz . require_csrf_token <EOL> def create_credential ( ) : <EOL> data = request . get_json ( ) <EOL> if not data . get ( '<STR_LIT>' ) : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> credential_pairs = _lowercase_credential_pairs ( data [ '<STR_LIT>' ] ) <EOL> if not _check_credential_pair_uniqueness ( credential_pairs ) : <EOL> ret = { '<STR_LIT:error>' : '<STR_LIT>' } <EOL> return jsonify ( ret ) , <NUM_LIT> <EOL> for cred in Credential . data_type_date_index . query ( <EOL> '<STR_LIT>' , name__eq = data [ '<STR_LIT:name>' ] ) : <EOL> msg = '<STR_LIT>' . format ( cred . id ) <EOL> return jsonify ( { '<STR_LIT:error>' : msg , '<STR_LIT>' : cred . id } ) , <NUM_LIT> <EOL> id = str ( uuid . uuid4 ( ) ) . replace ( '<STR_LIT:->' , '<STR_LIT>' ) <EOL> revision = <NUM_LIT:1> <EOL> credential_pairs = json . dumps ( credential_pairs ) <EOL> data_key = keymanager . create_datakey ( encryption_context = { '<STR_LIT:id>' : id } ) <EOL> cipher = CipherManager ( data_key [ '<STR_LIT>' ] , version = <NUM_LIT:2> ) <EOL> credential_pairs = cipher . encrypt ( credential_pairs ) <EOL> cred = Credential ( <EOL> id = '<STR_LIT>' . format ( id , revision ) , <EOL> data_type = '<STR_LIT>' , <EOL> name = data [ '<STR_LIT:name>' ] , <EOL> credential_pairs = credential_pairs , <EOL> revision = revision , <EOL> enabled = data . get ( '<STR_LIT>' ) , <EOL> data_key = data_key [ '<STR_LIT>' ] , <EOL> cipher_version = <NUM_LIT:2> , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) . save ( id__null = True ) <EOL> cred = Credential ( <EOL> id = id , <EOL> data_type = '<STR_LIT>' , <EOL> name = data [ '<STR_LIT:name>' ] , <EOL> credential_pairs = credential_pairs , <EOL> revision = revision , <EOL> enabled = data . get ( '<STR_LIT>' ) , <EOL> data_key = data_key [ '<STR_LIT>' ] , <EOL> cipher_version = <NUM_LIT:2> , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) <EOL> cred . save ( ) <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : cred . id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : json . loads ( cipher . decrypt ( cred . credential_pairs ) ) , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . modified_date , <EOL> '<STR_LIT>' : cred . modified_by <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ authnz . require_auth <EOL> def get_credential_dependencies ( id ) : <EOL> services = _get_services_for_credential ( id ) <EOL> _services = [ { '<STR_LIT:id>' : x . id , '<STR_LIT>' : x . enabled } for x in services ] <EOL> return jsonify ( { <EOL> '<STR_LIT>' : _services <EOL> } ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT>' ] ) <EOL> @ authnz . require_auth <EOL> @ authnz . require_csrf_token <EOL> def update_credential ( id ) : <EOL> try : <EOL> _cred = Credential . get ( id ) <EOL> except Credential . DoesNotExist : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> if _cred . data_type != '<STR_LIT>' : <EOL> msg = '<STR_LIT>' <EOL> return jsonify ( { '<STR_LIT:error>' : msg } ) , <NUM_LIT> <EOL> data = request . get_json ( ) <EOL> update = { } <EOL> revision = _cred . revision + <NUM_LIT:1> <EOL> update [ '<STR_LIT:name>' ] = data . get ( '<STR_LIT:name>' , _cred . name ) <EOL> if '<STR_LIT>' in data : <EOL> if not isinstance ( data [ '<STR_LIT>' ] , bool ) : <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> update [ '<STR_LIT>' ] = data [ '<STR_LIT>' ] <EOL> else : <EOL> update [ '<STR_LIT>' ] = _cred . enabled <EOL> services = _get_services_for_credential ( id ) <EOL> if '<STR_LIT>' in data : <EOL> credential_pairs = _lowercase_credential_pairs ( <EOL> data [ '<STR_LIT>' ] <EOL> ) <EOL> if not _check_credential_pair_uniqueness ( credential_pairs ) : <EOL> ret = { '<STR_LIT:error>' : '<STR_LIT>' } <EOL> return jsonify ( ret ) , <NUM_LIT> <EOL> conflicts = _pair_key_conflicts_for_services ( <EOL> id , <EOL> credential_pairs , <EOL> services <EOL> ) <EOL> if conflicts : <EOL> ret = { <EOL> '<STR_LIT:error>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : conflicts <EOL> } <EOL> return jsonify ( ret ) , <NUM_LIT> <EOL> update [ '<STR_LIT>' ] = json . dumps ( credential_pairs ) <EOL> else : <EOL> data_key = keymanager . decrypt_key ( <EOL> _cred . data_key , <EOL> encryption_context = { '<STR_LIT:id>' : id } <EOL> ) <EOL> cipher_version = _cred . cipher_version <EOL> cipher = CipherManager ( data_key , cipher_version ) <EOL> update [ '<STR_LIT>' ] = cipher . decrypt ( _cred . credential_pairs ) <EOL> data_key = keymanager . create_datakey ( encryption_context = { '<STR_LIT:id>' : id } ) <EOL> cipher = CipherManager ( data_key [ '<STR_LIT>' ] , version = <NUM_LIT:2> ) <EOL> credential_pairs = cipher . encrypt ( update [ '<STR_LIT>' ] ) <EOL> try : <EOL> Credential ( <EOL> id = '<STR_LIT>' . format ( id , revision ) , <EOL> name = update [ '<STR_LIT:name>' ] , <EOL> data_type = '<STR_LIT>' , <EOL> credential_pairs = credential_pairs , <EOL> enabled = update [ '<STR_LIT>' ] , <EOL> revision = revision , <EOL> data_key = data_key [ '<STR_LIT>' ] , <EOL> cipher_version = <NUM_LIT:2> , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) . save ( id__null = True ) <EOL> except PutError as e : <EOL> logging . error ( e ) <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> try : <EOL> cred = Credential ( <EOL> id = id , <EOL> name = update [ '<STR_LIT:name>' ] , <EOL> data_type = '<STR_LIT>' , <EOL> credential_pairs = credential_pairs , <EOL> enabled = update [ '<STR_LIT>' ] , <EOL> revision = revision , <EOL> data_key = data_key [ '<STR_LIT>' ] , <EOL> cipher_version = <NUM_LIT:2> , <EOL> modified_by = authnz . get_logged_in_user_email ( ) <EOL> ) <EOL> cred . save ( ) <EOL> except PutError as e : <EOL> logging . error ( e ) <EOL> return jsonify ( { '<STR_LIT:error>' : '<STR_LIT>' } ) , <NUM_LIT> <EOL> if services : <EOL> service_names = [ x . id for x in services ] <EOL> msg = '<STR_LIT>' <EOL> msg = msg . format ( cred . name , cred . id , cred . revision ) <EOL> graphite . send_event ( service_names , msg ) <EOL> return jsonify ( { <EOL> '<STR_LIT:id>' : cred . id , <EOL> '<STR_LIT:name>' : cred . name , <EOL> '<STR_LIT>' : json . loads ( cipher . decrypt ( cred . credential_pairs ) ) , <EOL> '<STR_LIT>' : cred . revision , <EOL> '<STR_LIT>' : cred . enabled , <EOL> '<STR_LIT>' : cred . modified_date , <EOL> '<STR_LIT>' : cred . modified_by <EOL> } ) </s>
