How to create user of elastic using flask

Issue

I want to create a user | role | privilege of elastic using API in flask
Documentation for creating user provided an example

it’s working fine in elastic Dev Tools
Creating new user using in console
but how can I convert it into a python POST request?

My Code

from flask import Flask, request, jsonify, render_template
from elasticsearch import Elasticsearch

CLOUD_ID = "myfirstdeployment:XXX"
ELASTIC_PASS = 'XXX'
ELASTIC_USER = 'XXX'

client = Elasticsearch(cloud_id=CLOUD_ID, basic_auth=(ELASTIC_USER, ELASTIC_PASS))

app = Flask(__name__)
import requests
from requests.structures import CaseInsensitiveDict

@app.route('/get')
def getting():
    data = client.search(index="kibana_sample_data_ecommerce", body={"query" :{"match_all":{}}})
    return f'{[x["_source"]["category"] for x in data["hits"]["hits"]]}'

es = Elasticsearch(hosts="https://localhost:9200", basic_auth=('elastic', 'zoU_Ec8JjbPnQNG4b8kY'), verify_certs=False)
@app.route('/local')
def local():
    return f'{es.info()}'

@app.route('/users')
def getAllUser():
    uri = 'https://localhost:9200/_security/user/'
    es = Elasticsearch(hosts=uri, basic_auth=('elastic', 'zoU_Ec8JjbPnQNG4b8kY'), ca_certs="872ee6c0879fc0cfe73054c3ba7afb5902dbb171a2c215af35a5faab1206b924", verify_certs=False)
    return f'{es.info()}'


@app.route('/users/<name>')
def getSingleUser(name):
    try:
        uri = f'https://localhost:9200/_security/user/{name}'
        es = Elasticsearch(hosts=uri, basic_auth=('elastic', 'zoU_Ec8JjbPnQNG4b8kY'), ca_certs="872ee6c0879fc0cfe73054c3ba7afb5902dbb171a2c215af35a5faab1206b924", verify_certs=False)
        return f'{es.info()}'
    except:
        content = {'error':'User Not Found'}
        return content, 404

@app.route('/create-new-user', methods=['GET','POST'])
def createUser():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        email = request.form.get('email')
        fullname = request.form.get('fullname')
        role = request.form.getlist('role')
        body ={"password":password, "username":username, "email":email, "fullname":fullname, "role":role}
        try:
            uri = f'https://localhost:9200/_security/user/{username}'
            es = Elasticsearch(hosts=uri, basic_auth=('elastic', 'zoU_Ec8JjbPnQNG4b8kY'), ca_certs="872ee6c0879fc0cfe73054c3ba7afb5902dbb171a2c215af35a5faab1206b924", verify_certs=False)
            return f'{es.info()}'
        except:
            content = {'error':'something went wrong'}
            return content, 501
    return render_template('add_user.html')

if __name__ == "__main__":
    app.run(debug=True)

when I create a user from Stack Management > Security > User > Create
POST request send to security/user/new_user_username
post data = {password=password, username=username, email=email, role=[], fullname=fullname

Solution

first Thanks to Paulo
Using put_user() method we can easily create user

Image For Creating a user in elastic

username, password & email fields are mandatory when creating a user using API

@app.route('/create-new-user', methods=['GET','POST'])
def createUser():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        email = request.form.get('email')
        fullname = request.form.get('fullname')
        roles = request.form.getlist('role')
        body ={"password":password, "username":username, "email":email, "fullname":fullname, "roles":roles}
        try:
            client = Elasticsearch(hosts=https://localhost:9200/, basic_auth=(ELASTIC_USERNAME, ELASTIC_PASSWORD), ca_certs=CERTIFICATE, verify_certs=False)
            es = SecurityClient(client)
            es.put_user(**body)
            return {'message':'User created'}, 201
        except:
            return {'message':'something went wrong'}, 501
    return render_template('add_user.html')

Remember to pass keyword args of roles in put_user

Edited if someone experimenting can also try perform_request

Edited 2 Simple and better solution

body ={"password":password, "username":username, "email":email, "full_name":fullname, 'enabled':True, 'roles':role}
uri = f'https://localhost:9200/'
client = Elasticsearch(hosts=uri, basic_auth=(ELASTIC_USER, ELASTIC_PASS), ca_certs=CERTIFICATE, verify_certs=False)
client.perform_request(body=body, method='POST', path=f'/_security/user/{username}', headers={'content-type':'application/json', 'accept':'application/json'})

Answered By – Azhar Uddin Sheikh

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published