def delete_secret(user, team, channel, secret_name): try: SecretId1 = team + '.' + channel + '.' + secret_name oSecret = aws_secretsmanager_get_secret(SecretId1) if (len(oSecret) > 0) and (oSecret.get( 'secretType', '') == 's3file'): # if it's a file, delete the file s3Functions.delete(oSecret.get('secret', '')) client.tag_resource( SecretId=SecretId1, Tags=[{ 'Key': 'DeletedBy', 'Value': user }, { 'Key': 'DeletedDate', 'Value': datetime.datetime.now().strftime("%m-%d-%Y %H:%M:%S") }]) answer = client.delete_secret(SecretId=SecretId1) if 'Name' in answer: logFunctions.log('User ' + user + ' deleted the secret: "' + secret_name + '" at channel: ' + channel) return "I will no longer remember " + slackFunctions.escape( secret_name) else: return 'Sorry, there was a problem deleting your secret' except Exception as e: return 'Sorry, there was a big problem deleting your secret: ' + slackFunctions.escape( str(e))
def get_secret(user, team, channel, secret_name=''): SecretId1 = team + '.' + channel + '.' + secret_name oSecret = aws_secretsmanager_get_secret(SecretId1) if len(oSecret) > 0: # tag the secret client.tag_resource( SecretId=SecretId1, Tags=[{ 'Key': 'AccessedBy', 'Value': user }, { 'Key': 'AccessedDate', 'Value': datetime.datetime.now().strftime("%m-%d-%Y %H:%M:%S") }]) logFunctions.log('User ' + user + ' requested the secret: "' + secret_name + '" at channel: ' + channel) if oSecret.get('secretType', '') == 'string': return 'Your secret is: `' + slackFunctions.escape( oSecret.get('secret', '') + '`') elif oSecret.get('secretType', '') == 's3file': s3url = s3Functions.create_presigned_url_get( oSecret.get('secret', ''), oSecret.get('original-file-name', secret_name)) return '*Download your secret from here*:\r`' + slackFunctions.escape( s3url) + '`\rThe link expires in 30 minutes' else: return 'unknown secret type' else: return 'Secret not found'
def create_presigned_url_get( object_name, download_filename='', expiration=3600): # Generate a presigned URL to share an S3 object if download_filename == '': download_filename = object_name bucket_name = os.environ.get('BucketName') s3_client = boto3.client('s3') try: response = s3_client.generate_presigned_url( 'get_object', Params={ 'Bucket': bucket_name, 'Key': object_name, 'ResponseContentDisposition': 'attachment; filename ="' + download_filename + '"' }, ExpiresIn=expiration) return response except ClientError as e: logFunctions.log('create_presigned_url failed') logFunctions.log(e) return ''
def aws_secretsmanager_set_secret(SecretId1, SecretValue1, Tags1=[]): try: answer = client.create_secret(Name=SecretId1, Description='Created by ' + settings.botName, SecretString=SecretValue1, Tags=Tags1) return 'Name' in answer except Exception as e: logFunctions.log('Error when saving a secret: ' + str(e)) return False
def update_secret(user, team, channel, secret_name, secret_value, old_secret_value): if secret_name != '': try: SecretId1 = team + '.' + channel + '.' + secret_name if secret_value.strip() == '+': # it's a file-secret secret_data = prepare_s3file_secret(old_secret_value) if aws_secretsmanager_update_secret(SecretId1, json.dumps(secret_data)): presignedURL = s3Functions.create_presigned_url_put( secret_data["secret"]) logFunctions.log('User ' + user + ' updating the file secret: "' + secret_name + '" (file upload pending) at channel: ' + channel) return '*Please, use the link below to upload your new file*:\r`' + uploadURL( requestContext, presignedURL) + '`' else: return 'Something went wrong when preparing your filesecret for update' else: if aws_secretsmanager_update_secret( SecretId1, encode_text_secret(secret_value)): client.tag_resource(SecretId=SecretId1, Tags=[{ 'Key': 'ModifiedBy', 'Value': user }, { 'Key': 'ModifiedDate', 'Value': datetime.datetime.now().strftime( "%m-%d-%Y %H:%M:%S") }]) logFunctions.log('User ' + user + ' updated the secret: "' + secret_name + '" at channel: ' + channel) fret = 'I will remember the new "' + slackFunctions.escape( secret_name) + '" secret' if settings.check_private_channel: fret += slackFunctions.get_channel_info(channel) return fret else: return 'Something went wrong when updating your secret' except Exception as e: return 'Error. Secret not updated. ' + slackFunctions.escape( str(e)) else: return 'I need a name and a value to update it!'
def set_secret(user, team, channel, secret_name, secret_value): if secret_name != '': try: Tags1 = [{ 'Key': 'CreatedBy', 'Value': user }, { 'Key': 'CreatedDate', 'Value': datetime.datetime.now().strftime("%m-%d-%Y %H:%M:%S") }] if secret_value.strip() == '+': # it's a file-secret secret_data = prepare_s3file_secret() if aws_secretsmanager_set_secret( team + '.' + channel + '.' + secret_name, json.dumps(secret_data), Tags1): presignedURL = s3Functions.create_presigned_url_put( secret_data["secret"]) logFunctions.log('User ' + user + ' created the file secret: "' + secret_name + '" (file upload pending) at channel: ' + channel) return '*Please, use the link below to upload your file*:\r`' + uploadURL( requestContext, presignedURL) + '`' else: return 'Something went wrong when preparing your filesecret' else: if aws_secretsmanager_set_secret( team + '.' + channel + '.' + secret_name, encode_text_secret(secret_value), Tags1): logFunctions.log('User ' + user + ' created the secret: "' + secret_name + '" at channel: ' + channel) fret = 'I will remember it as ' + slackFunctions.escape( secret_name) + ' (only for this channel)' if settings.check_private_channel: fret += slackFunctions.get_channel_info(channel) return fret else: return 'Something went wrong when storing your secret' except Exception as e: return 'Error. Secret not stored. ' + slackFunctions.escape(str(e)) else: return 'I need a name and a value to remember it!'
def main(event, context): return_headers = {} output = '' slack_event = {"type": ""} try: # load the request context secretsManagement.requestContext = event.get('requestContext', {}) except: secretsManagement.requestContext = {} try: # load the GET parameters get_params = event.get('queryStringParameters', '{}') except: get_params = {} try: # load JSON post jsonbody = json.loads(event.get('body', {})) except Exception as e: jsonbody = {} try: # it's not JSON. lets try to decode it as URL with multiple query string if 'body' in event: bodyString = event['body'] else: bodyString = '' if ('isBase64Encoded' in event) and event['isBase64Encoded']: slack_event = base64.decodestring(bytes( bodyString, 'utf-8')).decode('utf-8') slack_event = urllib.parse.parse_qs(slack_event) else: slack_event = urllib.parse.parse_qs(bodyString) except Exception as e: logFunctions.log('Invalid data in body ' + str(e)) if (type(get_params) is dict) and (get_params.get('presigned', '') != '1'): # the user wants to upload a file return_headers = {'Content-Type': 'text/html'} output = secretsManagement.HTML_uploadForm(get_params['presigned']) elif ('type' in jsonbody) and (jsonbody['type'] == "url_verification"): output = jsonbody["challenge"] # log the request logFunctions.log('New challenge replied') elif not ('token' in slack_event) or not (verificationToken in slack_event['token']): output = '' logFunctions.log('invalid token') elif "bot_id" in slack_event: logFunctions.log('Ignoring event from bot') elif 'X-Slack-Retry-Num' in event['headers']: logFunctions.log('Ignoring a duplicated event') elif ("command" in slack_event) and ('/' + settings.botName in slack_event["command"]): output = "" text = '' from_user = '' from_team = '' from_channel = '' from_username = '' from_domain = '' try: if len(slack_event["text"]) > 0: text = slack_event["text"][0].strip() if len(slack_event["user_id"]) > 0: from_user = slack_event["user_id"][0] if len(slack_event["team_id"]) > 0: from_team = slack_event["team_id"][0] if len(slack_event["channel_id"]) > 0: from_channel = slack_event["channel_id"][0] #response_url = slack_event["response_url"][0] if len(slack_event["user_name"]) > 0: from_username = slack_event["user_name"][0] if len(slack_event["team_domain"]) > 0: from_domain = slack_event["team_domain"][0] from_user = from_username + '@' + from_domain # check for commands # get help if text.lower() == "help": output = settings.help_message # get the extended secrets list elif text == "??": output = secretsManagement.get_secret_list_extended( from_team, from_channel) # get the secrets list elif text == "?": output = secretsManagement.get_secret_list( from_team, from_channel) elif text.lower() == "info": output = 'id: ' + from_user + ' team domain: ' + from_domain + ' channel: ' + from_channel + ' ' + slackFunctions.get_channel_info( from_channel, True) elif text.lower().startswith("delete "): output = secretsManagement.delete_secret( from_user, from_team, from_channel, text[7:].lower().strip()) elif text.lower() == "delete": output = "missing name to delete" elif text.lower().startswith("file "): output = secretsManagement.set_secret(from_user, from_team, from_channel, text[5:].lower().strip(), '+') elif text.lower() == "file": output = "missing file name" # create a new secret elif '=' in text: newSecretName, newSecretValue = '', '' values = text.strip().split(sep='=', maxsplit=1) newSecretName = values[0] if len(values) > 1: newSecretValue = values[1].strip() if bool(newSecretName): # the name is not empty if newSecretName in settings.reservedWords: output = "Sorry, '" + newSecretName + "' is a reserverd word." else: if bool(newSecretValue.strip() ): # the secret is not empty old_secret_value = secretsManagement.aws_secretsmanager_get_secret( from_team + '.' + from_channel + '.' + newSecretName.strip()) if len(old_secret_value ) > 0: # if exists, update it output = secretsManagement.update_secret( from_user, from_team, from_channel, newSecretName.strip(), newSecretValue, old_secret_value) else: # create a new secret output = secretsManagement.set_secret( from_user, from_team, from_channel, newSecretName.strip(), newSecretValue) else: # if empty, just delete it output = secretsManagement.delete_secret( from_user, from_team, from_channel, newSecretName.strip()) else: output = "Your secret needs a name" # get a secret value else: SecretName = text.strip() output = secretsManagement.get_secret(from_user, from_team, from_channel, SecretName) except Exception as e: logFunctions.log("Error or missing paramter from slack. " + str(e)) logFunctions.log(slack_event) return { 'statusCode': 200, 'body': output, 'headers': return_headers, 'isBase64Encoded': isBase64Encoded }