mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-20 13:28:20 +02:00
* Go to peer address page on connected peer item click * Added disconnect button to peer address page * Add get connected peer rpc method * Add disconnect button to peer address page * Add both connect and disconnect button to peer address page * Update frontend build
624 lines
18 KiB
Python
624 lines
18 KiB
Python
import logging
|
|
import os
|
|
import threading
|
|
|
|
from flask import flash
|
|
from flask import Flask
|
|
from flask import redirect
|
|
from flask import render_template
|
|
from flask import request
|
|
from flask import url_for
|
|
from flask_cors import CORS
|
|
from flask_login import current_user
|
|
from flask_login import login_required
|
|
from flask_login import login_user
|
|
from flask_login import LoginManager
|
|
from flask_login import logout_user
|
|
from werkzeug.serving import make_server
|
|
|
|
from proto import lnd_pb2
|
|
from proto import squeak_admin_pb2
|
|
from squeaknode.admin.webapp.forms import LoginForm
|
|
from squeaknode.admin.webapp.squeak_admin_web_user import User
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_app(handler, username, password):
|
|
# create and configure the app
|
|
logger.info("Starting flask app from directory: {}".format(os.getcwd()))
|
|
app = Flask(
|
|
__name__,
|
|
static_url_path="/",
|
|
static_folder="static/build",
|
|
)
|
|
app.config.from_mapping(
|
|
SECRET_KEY="dev",
|
|
)
|
|
login = LoginManager(app)
|
|
valid_user = User(
|
|
username,
|
|
password,
|
|
)
|
|
logger.info("Starting flask with app.root_path: {}".format(app.root_path))
|
|
logger.info("Files in root path: {}".format(os.listdir(app.root_path)))
|
|
|
|
@login.user_loader
|
|
def load_user(id):
|
|
return valid_user.get_user_by_username(id)
|
|
|
|
@login.unauthorized_handler
|
|
def unauthorized_callback():
|
|
return redirect("/login")
|
|
|
|
def handle_request(request_message, handle_rpc_request):
|
|
data = request.get_data()
|
|
request_message.ParseFromString(data)
|
|
try:
|
|
reply = handle_rpc_request(request_message)
|
|
return reply.SerializeToString()
|
|
except Exception as e:
|
|
logger.error("Error in handle admin web request.", exc_info=True)
|
|
return str(e), 500
|
|
|
|
@app.route("/login", methods=["GET", "POST"])
|
|
def login():
|
|
logger.info("Trying to login")
|
|
if current_user.is_authenticated:
|
|
return redirect(url_for("index"))
|
|
form = LoginForm()
|
|
if form.validate_on_submit():
|
|
user = valid_user.get_user_by_username(form.username.data)
|
|
if user is None or not user.check_password(form.password.data):
|
|
flash("Invalid username or password")
|
|
return redirect(url_for("login"))
|
|
login_user(user, remember=form.remember_me.data)
|
|
return redirect(url_for("index"))
|
|
return render_template("login.html", title="Sign In", form=form)
|
|
|
|
@app.route("/logout")
|
|
def logout():
|
|
logout_user()
|
|
return redirect(url_for("index"))
|
|
|
|
@app.route("/")
|
|
@login_required
|
|
def index():
|
|
logger.info("Getting index route.")
|
|
return app.send_static_file("index.html")
|
|
|
|
@app.route("/user")
|
|
@login_required
|
|
def user():
|
|
logger.info("Getting user.")
|
|
return current_user.username
|
|
|
|
@app.route("/hello")
|
|
@login_required
|
|
def hello_world():
|
|
logger.info("Getting hello route.")
|
|
return "Hello, World!"
|
|
|
|
@app.route("/lndgetinfo", methods=["POST"])
|
|
@login_required
|
|
def lndgetinfo():
|
|
return handle_request(
|
|
lnd_pb2.GetInfoRequest(),
|
|
handler.handle_lnd_get_info,
|
|
)
|
|
|
|
@app.route("/lndwalletbalance", methods=["POST"])
|
|
@login_required
|
|
def lndwalletbalance():
|
|
return handle_request(
|
|
lnd_pb2.WalletBalanceRequest(),
|
|
handler.handle_lnd_wallet_balance,
|
|
)
|
|
|
|
@app.route("/lndgettransactions", methods=["POST"])
|
|
@login_required
|
|
def lndgettransactions():
|
|
return handle_request(
|
|
lnd_pb2.GetTransactionsRequest(),
|
|
handler.handle_lnd_get_transactions,
|
|
)
|
|
|
|
@app.route("/lndlistpeers", methods=["POST"])
|
|
@login_required
|
|
def lndlistpeers():
|
|
return handle_request(
|
|
lnd_pb2.ListPeersRequest(),
|
|
handler.handle_lnd_list_peers,
|
|
)
|
|
|
|
@app.route("/lndlistchannels", methods=["POST"])
|
|
@login_required
|
|
def lndlistchannels():
|
|
return handle_request(
|
|
lnd_pb2.ListChannelsRequest(),
|
|
handler.handle_lnd_list_channels,
|
|
)
|
|
|
|
@app.route("/lndpendingchannels", methods=["POST"])
|
|
@login_required
|
|
def lndpendingchannels():
|
|
return handle_request(
|
|
lnd_pb2.PendingChannelsRequest(),
|
|
handler.handle_lnd_pending_channels,
|
|
)
|
|
|
|
@app.route("/lndconnectpeer", methods=["POST"])
|
|
@login_required
|
|
def lndconnectpeer():
|
|
return handle_request(
|
|
lnd_pb2.ConnectPeerRequest(),
|
|
handler.handle_lnd_connect_peer,
|
|
)
|
|
|
|
@app.route("/lnddisconnectpeer", methods=["POST"])
|
|
@login_required
|
|
def lnddisconnectpeer():
|
|
return handle_request(
|
|
lnd_pb2.DisconnectPeerRequest(),
|
|
handler.handle_lnd_disconnect_peer,
|
|
)
|
|
|
|
@app.route("/lndopenchannelsync", methods=["POST"])
|
|
@login_required
|
|
def lndopenchannelsync():
|
|
return handle_request(
|
|
lnd_pb2.OpenChannelRequest(),
|
|
handler.handle_lnd_open_channel_sync,
|
|
)
|
|
|
|
@app.route("/lndclosechannel", methods=["POST"])
|
|
@login_required
|
|
def lndclosechannel():
|
|
return handle_request(
|
|
lnd_pb2.CloseChannelRequest(),
|
|
handler.handle_lnd_close_channel,
|
|
)
|
|
|
|
@app.route("/lndnewaddress", methods=["POST"])
|
|
@login_required
|
|
def lndnewaddress():
|
|
return handle_request(
|
|
lnd_pb2.NewAddressRequest(),
|
|
handler.handle_lnd_new_address,
|
|
)
|
|
|
|
@app.route("/lndsendcoins", methods=["POST"])
|
|
@login_required
|
|
def lndsendcoins():
|
|
return handle_request(
|
|
lnd_pb2.SendCoinsRequest(),
|
|
handler.handle_lnd_send_coins,
|
|
)
|
|
|
|
@app.route("/gettimelinesqueakdisplays", methods=["POST"])
|
|
@login_required
|
|
def gettimelinesqueakdisplays():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetTimelineSqueakDisplaysRequest(),
|
|
handler.handle_get_timeline_squeak_display_entries,
|
|
)
|
|
|
|
@app.route("/getsqueakprofile", methods=["POST"])
|
|
@login_required
|
|
def getsqueakprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSqueakProfileRequest(),
|
|
handler.handle_get_squeak_profile,
|
|
)
|
|
|
|
@app.route("/setsqueakprofilefollowing", methods=["POST"])
|
|
@login_required
|
|
def setsqueakprofilefollowing():
|
|
return handle_request(
|
|
squeak_admin_pb2.SetSqueakProfileFollowingRequest(),
|
|
handler.handle_set_squeak_profile_following,
|
|
)
|
|
|
|
@app.route("/setsqueakprofilesharing", methods=["POST"])
|
|
@login_required
|
|
def setsqueakprofilesharing():
|
|
return handle_request(
|
|
squeak_admin_pb2.SetSqueakProfileSharingRequest(),
|
|
handler.handle_set_squeak_profile_sharing,
|
|
)
|
|
|
|
@app.route("/renamesqueakprofile", methods=["POST"])
|
|
@login_required
|
|
def renamesqueakprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.RenameSqueakProfileRequest(),
|
|
handler.handle_rename_squeak_profile,
|
|
)
|
|
|
|
@app.route("/setsqueakprofileimage", methods=["POST"])
|
|
@login_required
|
|
def setsqueakprofileimage():
|
|
return handle_request(
|
|
squeak_admin_pb2.SetSqueakProfileImageRequest(),
|
|
handler.handle_set_squeak_profile_image,
|
|
)
|
|
|
|
@app.route("/clearsqueakprofileimage", methods=["POST"])
|
|
@login_required
|
|
def clearsqueakprofileimage():
|
|
return handle_request(
|
|
squeak_admin_pb2.ClearSqueakProfileImageRequest(),
|
|
handler.handle_clear_squeak_profile_image,
|
|
)
|
|
|
|
@app.route("/getpeers", methods=["POST"])
|
|
@login_required
|
|
def getpeers():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetPeersRequest(),
|
|
handler.handle_get_squeak_peers,
|
|
)
|
|
|
|
@app.route("/payoffer", methods=["POST"])
|
|
@login_required
|
|
def payoffer():
|
|
return handle_request(
|
|
squeak_admin_pb2.PayOfferRequest(),
|
|
handler.handle_pay_offer,
|
|
)
|
|
|
|
@app.route("/getbuyoffers", methods=["POST"])
|
|
@login_required
|
|
def getbuyoffers():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetBuyOffersRequest(),
|
|
handler.handle_get_buy_offers,
|
|
)
|
|
|
|
@app.route("/getbuyoffer", methods=["POST"])
|
|
@login_required
|
|
def getbuyoffer():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetBuyOfferRequest(),
|
|
handler.handle_get_buy_offer,
|
|
)
|
|
|
|
@app.route("/getpeer", methods=["POST"])
|
|
@login_required
|
|
def getpeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetPeerRequest(),
|
|
handler.handle_get_squeak_peer,
|
|
)
|
|
|
|
@app.route("/setpeerdownloading", methods=["POST"])
|
|
@login_required
|
|
def setpeerdownloading():
|
|
return handle_request(
|
|
squeak_admin_pb2.SetPeerDownloadingRequest(),
|
|
handler.handle_set_squeak_peer_downloading,
|
|
)
|
|
|
|
@app.route("/setpeeruploading", methods=["POST"])
|
|
@login_required
|
|
def setpeeruploading():
|
|
return handle_request(
|
|
squeak_admin_pb2.SetPeerUploadingRequest(),
|
|
handler.handle_set_squeak_peer_uploading,
|
|
)
|
|
|
|
@app.route("/renamepeer", methods=["POST"])
|
|
@login_required
|
|
def renamepeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.RenamePeerRequest(),
|
|
handler.handle_rename_squeak_peer,
|
|
)
|
|
|
|
@app.route("/getsigningprofiles", methods=["POST"])
|
|
@login_required
|
|
def getsigningprofiles():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSigningProfilesRequest(),
|
|
handler.handle_get_signing_profiles,
|
|
)
|
|
|
|
@app.route("/getcontactprofiles", methods=["POST"])
|
|
@login_required
|
|
def getcontactprofiles():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetContactProfilesRequest(),
|
|
handler.handle_get_contact_profiles,
|
|
)
|
|
|
|
@app.route("/makesqueakrequest", methods=["POST"])
|
|
@login_required
|
|
def makesqueakrequest():
|
|
return handle_request(
|
|
squeak_admin_pb2.MakeSqueakRequest(),
|
|
handler.handle_make_squeak,
|
|
)
|
|
|
|
@app.route("/getsqueakdisplay", methods=["POST"])
|
|
@login_required
|
|
def getsqueakdisplay():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSqueakDisplayRequest(),
|
|
handler.handle_get_squeak_display_entry,
|
|
)
|
|
|
|
@app.route("/getancestorsqueakdisplays", methods=["POST"])
|
|
@login_required
|
|
def getancestorsqueakdisplays():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetAncestorSqueakDisplaysRequest(),
|
|
handler.handle_get_ancestor_squeak_display_entries,
|
|
)
|
|
|
|
@app.route("/getreplysqueakdisplays", methods=["POST"])
|
|
@login_required
|
|
def getreplysqueakdisplays():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetReplySqueakDisplaysRequest(),
|
|
handler.handle_get_reply_squeak_display_entries,
|
|
)
|
|
|
|
@app.route("/getsqueakprofilebyaddress", methods=["POST"])
|
|
@login_required
|
|
def getsqueakprofilebyaddress():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSqueakProfileByAddressRequest(),
|
|
handler.handle_get_squeak_profile_by_address,
|
|
)
|
|
|
|
@app.route("/getaddresssqueakdisplays", methods=["POST"])
|
|
@login_required
|
|
def getaddresssqueakdisplays():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetAddressSqueakDisplaysRequest(),
|
|
handler.handle_get_squeak_display_entries_for_address,
|
|
)
|
|
|
|
@app.route("/createcontactprofile", methods=["POST"])
|
|
@login_required
|
|
def createcontactprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.CreateContactProfileRequest(),
|
|
handler.handle_create_contact_profile,
|
|
)
|
|
|
|
@app.route("/createsigningprofile", methods=["POST"])
|
|
@login_required
|
|
def createsigningprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.CreateSigningProfileRequest(),
|
|
handler.handle_create_signing_profile,
|
|
)
|
|
|
|
@app.route("/importsigningprofile", methods=["POST"])
|
|
@login_required
|
|
def importsigningprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.ImportSigningProfileRequest(),
|
|
handler.handle_import_signing_profile,
|
|
)
|
|
|
|
@app.route("/createpeer", methods=["POST"])
|
|
@login_required
|
|
def createpeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.CreatePeerRequest(),
|
|
handler.handle_create_peer,
|
|
)
|
|
|
|
@app.route("/deletepeer", methods=["POST"])
|
|
@login_required
|
|
def deletepeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.DeletePeerRequest(),
|
|
handler.handle_delete_squeak_peer,
|
|
)
|
|
|
|
@app.route("/deleteprofile", methods=["POST"])
|
|
@login_required
|
|
def deleteprofile():
|
|
return handle_request(
|
|
squeak_admin_pb2.DeleteSqueakProfileRequest(),
|
|
handler.handle_delete_squeak_profile,
|
|
)
|
|
|
|
@app.route("/deletesqueak", methods=["POST"])
|
|
@login_required
|
|
def deletesqueak():
|
|
return handle_request(
|
|
squeak_admin_pb2.DeleteSqueakRequest(),
|
|
handler.handle_delete_squeak,
|
|
)
|
|
|
|
@app.route("/syncsqueak", methods=["POST"])
|
|
@login_required
|
|
def syncsqueak():
|
|
return handle_request(
|
|
squeak_admin_pb2.SyncSqueakRequest(),
|
|
handler.handle_sync_squeak,
|
|
)
|
|
|
|
@app.route("/getsqueakdetails", methods=["POST"])
|
|
@login_required
|
|
def getsqueakdetails():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSqueakDetailsRequest(),
|
|
handler.handle_get_squeak_details,
|
|
)
|
|
|
|
@app.route("/getsentpayments", methods=["POST"])
|
|
@login_required
|
|
def getsentpayments():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSentPaymentsRequest(),
|
|
handler.handle_get_sent_payments,
|
|
)
|
|
|
|
@app.route("/getsentoffers", methods=["POST"])
|
|
@login_required
|
|
def getsentoffers():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSentOffersRequest(),
|
|
handler.handle_get_sent_offers,
|
|
)
|
|
|
|
@app.route("/getreceivedpayments", methods=["POST"])
|
|
@login_required
|
|
def getreceivedpayments():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetReceivedPaymentsRequest(),
|
|
handler.handle_get_received_payments,
|
|
)
|
|
|
|
@app.route("/getnetwork", methods=["POST"])
|
|
@login_required
|
|
def getnetwork():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetNetworkRequest(),
|
|
handler.handle_get_network,
|
|
)
|
|
|
|
@app.route("/getsqueakprofileprivatekey", methods=["POST"])
|
|
@login_required
|
|
def getsqueakprofileprivatekey():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetSqueakProfilePrivateKeyRequest(),
|
|
handler.handle_get_squeak_profile_private_key,
|
|
)
|
|
|
|
@app.route("/getpaymentsummary", methods=["POST"])
|
|
@login_required
|
|
def getpaymentsummary():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetPaymentSummaryRequest(),
|
|
handler.handle_get_payment_summary,
|
|
)
|
|
|
|
@app.route("/reprocessreceivedpayments", methods=["POST"])
|
|
@login_required
|
|
def reprocessreceivedpayments():
|
|
return handle_request(
|
|
squeak_admin_pb2.ReprocessReceivedPaymentsRequest(),
|
|
handler.handle_reprocess_received_payments,
|
|
)
|
|
|
|
@app.route("/likesqueak", methods=["POST"])
|
|
@login_required
|
|
def likesqueak():
|
|
return handle_request(
|
|
squeak_admin_pb2.LikeSqueakRequest(),
|
|
handler.handle_like_squeak,
|
|
)
|
|
|
|
@app.route("/unlikesqueak", methods=["POST"])
|
|
@login_required
|
|
def unlikesqueak():
|
|
return handle_request(
|
|
squeak_admin_pb2.UnlikeSqueakRequest(),
|
|
handler.handle_unlike_squeak,
|
|
)
|
|
|
|
@app.route("/getlikedsqueakdisplays", methods=["POST"])
|
|
@login_required
|
|
def getlikedsqueakdisplays():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetLikedSqueakDisplaysRequest(),
|
|
handler.handle_get_liked_squeak_display_entries,
|
|
)
|
|
|
|
@app.route("/getconnectedpeers", methods=["POST"])
|
|
@login_required
|
|
def getconnectedpeers():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetConnectedPeersRequest(),
|
|
handler.handle_get_connected_peers,
|
|
)
|
|
|
|
@app.route("/getconnectedpeer", methods=["POST"])
|
|
@login_required
|
|
def getconnectedpeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.GetConnectedPeerRequest(),
|
|
handler.handle_get_connected_peer,
|
|
)
|
|
|
|
@app.route("/connectpeer", methods=["POST"])
|
|
@login_required
|
|
def connectpeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.ConnectPeerRequest(),
|
|
handler.handle_connect_peer,
|
|
)
|
|
|
|
@app.route("/disconnectpeer", methods=["POST"])
|
|
@login_required
|
|
def disconnectpeer():
|
|
return handle_request(
|
|
squeak_admin_pb2.DisconnectPeerRequest(),
|
|
handler.handle_disconnect_peer,
|
|
)
|
|
|
|
return app
|
|
|
|
|
|
class SqueakAdminWebServer:
|
|
def __init__(
|
|
self,
|
|
host,
|
|
port,
|
|
username,
|
|
password,
|
|
use_ssl,
|
|
login_disabled,
|
|
allow_cors,
|
|
handler,
|
|
stopped,
|
|
):
|
|
self.host = host
|
|
self.port = port
|
|
self.use_ssl = use_ssl
|
|
self.login_disabled = login_disabled
|
|
self.allow_cors = allow_cors
|
|
self.app = create_app(handler, username, password)
|
|
self.stopped = stopped
|
|
|
|
def get_app(self):
|
|
|
|
# Set LOGIN_DISABLED and allow CORS if login not required.
|
|
if self.login_disabled:
|
|
self.app.config["LOGIN_DISABLED"] = True
|
|
|
|
# Allow CORS
|
|
if self.allow_cors:
|
|
CORS(self.app)
|
|
|
|
# self.app.run(
|
|
# self.host,
|
|
# self.port,
|
|
# debug=False,
|
|
# ssl_context="adhoc" if self.use_ssl else None,
|
|
# )
|
|
|
|
return self.app
|
|
|
|
def serve(self):
|
|
server = make_server(
|
|
self.host,
|
|
self.port,
|
|
self.get_app(),
|
|
ssl_context="adhoc" if self.use_ssl else None,
|
|
)
|
|
|
|
logger.info("Starting SqueakAdminWebServer...")
|
|
threading.Thread(
|
|
target=server.serve_forever,
|
|
).start()
|
|
self.stopped.wait()
|
|
logger.info("Stopping SqueakAdminWebServer....")
|
|
server.shutdown()
|
|
logger.info("Stopped SqueakAdminWebServer.")
|