def test_get_login_url(self): c = Client("client_id" "client_secret") self.assertEqual( c.get_login_url("http://localhost", "login"), "https://hivesigner.com/oauth2/authorize?client_id" "=client_idclient_secret&redirect_uri=http%3A%2F%2Flocalh" "ost&scope=login")
def test_get_login_url_override_defaults(self): c = Client(oauth_base_url="http://foo.bar/oauth2/", client_id="client_id", client_secret="client_secret") self.assertEqual( c.get_login_url("http://localhost", "login"), "http://foo.bar/oauth2/authorize?client_id=client_id&" "redirect_uri=http%3A%2F%2Flocalhost&scope=login")
def test_me(self): def request_callback(request): self.assertEqual(request.url, "https://hivesigner.com/api/me/") return 200, {}, json.dumps({"access_token": "foo"}) c = Client(access_token="foo") responses.add_callback( responses.POST, 'https://hivesigner.com/api/me/', callback=request_callback, ) c.me()
def test_hot_sign(self): c = Client() sign_url = c.hot_sign("transfer", { "to": "turbot", "amount": "0.001 HBD", "memo": "selam", }, redirect_uri="http://localhost") self.assertEqual( sign_url, "https://hivesigner.com/sign/tra" "nsfer?to=turbot&amount=0.001+HBD&me" "mo=selam&redirect_uri=http%3A%2F%2F" "localhost")
def test_hot_sign_without_redirect_uri(self): c = Client() sign_url = c.hot_sign( "transfer", { "to": "turbot", "amount": "0.001 HBD", "memo": "selam", }, ) self.assertEqual( sign_url, "https://hivesigner.com/sign/tra" "nsfer?to=turbot&amount=0.001+HBD&me" "mo=selam")
def test_refresh_access_token(self): def request_callback(request): self.assertEqual(request.url, "https://hivesigner.com/api/oauth2/token/") self.assertEqual( request.body, 'refresh_token=refresh_token&client_id=client_id&' 'client_secret=client_secret&scope=login') return 200, {}, json.dumps({"access_token": "foo"}) c = Client(client_id="client_id", client_secret="client_secret") responses.add_callback( responses.POST, 'https://hivesigner.com/api/oauth2/token/', callback=request_callback, ) c.refresh_access_token("refresh_token", "login")
def test_get_access_token(self): def request_callback(request): self.assertEqual(request.url, "https://hivesigner.com/api/oauth2/token/") self.assertEqual( request.body, 'grant_type=authorization_code&code=code&client_id=' 'client_id&client_secret=client_secret') return 200, {}, json.dumps({"access_token": "foo"}) c = Client(client_id="client_id", client_secret="client_secret") responses.add_callback( responses.POST, 'https://hivesigner.com/api/oauth2/token/', callback=request_callback, ) c.get_access_token("code")
def get_sc_client(): global _sc_client if not _sc_client: _sc_client = Client( client_id=settings.SC_CLIENT_ID, client_secret=settings.SC_CLIENT_SECRET, oauth_base_url="https://hivesigner.com/oauth2/", sc2_api_base_url="https://hivesigner.com/api/", ) return _sc_client
def authenticate(self, request, **kwargs): if 'username' in kwargs: return None # validate the access token with /me endpoint and get user information client = Client(access_token=kwargs.get("access_token"), oauth_base_url="https://hivesigner.com/oauth2/", sc2_api_base_url="https://hivesigner.com/api/") user = client.me() if 'name' not in user: return None user_model = get_user_model() try: user_instance = user_model.objects.get(username=user["name"]) user_instance.save() except user_model.DoesNotExist: user_instance = user_model.objects.create_user( username=user["name"]) return user_instance
def vote(request, user, permlink): if request.method != "POST": raise Http404 # django admin users should not be able to vote. if not request.session.get("sc_token"): redirect('logout') try: poll = Question.objects.get(username=user, permlink=permlink) except Question.DoesNotExist: raise Http404 if not request.user.is_authenticated: return redirect('login') if poll.allow_multiple_choices: choice_ids = request.POST.getlist("choice-id") else: choice_ids = [ request.POST.get("choice-id"), ] # remove noise choice_ids = [x for x in choice_ids if x is not None] additional_thoughts = request.POST.get("vote-comment", "") if not len(choice_ids): messages.add_message(request, messages.ERROR, "You need to pick a choice to vote.") return redirect("detail", poll.username, poll.permlink) if Choice.objects.filter(voted_users__username=request.user, question=poll).exists(): messages.add_message(request, messages.ERROR, "You have already voted for this poll!") return redirect("detail", poll.username, poll.permlink) if not poll.is_votable(): messages.add_message(request, messages.ERROR, "This poll is expired!") return redirect("detail", poll.username, poll.permlink) for choice_id in choice_ids: try: choice = Choice.objects.get(pk=int(choice_id)) except Choice.DoesNotExist: raise Http404 choice_instances = [] for choice_id in choice_ids: choice = Choice.objects.get(pk=int(choice_id)) choice_instances.append(choice) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token"), oauth_base_url="https://hivesigner.com/oauth2/", sc2_api_base_url="https://hivesigner.com/api/") choice_text = "" for c in choice_instances: choice_text += f" - {c.text.strip()}\n" body = f"Voted for \n {choice_text}" if additional_thoughts: body += f"\n\n{additional_thoughts}" comment = Comment(author=request.user.username, permlink=str(uuid.uuid4()), body=body, parent_author=poll.username, parent_permlink=poll.permlink, json_metadata={ "tags": settings.DEFAULT_TAGS, "app": f"dpoll/{settings.DPOLL_APP_VERSION}", "content_type": "poll_vote", "votes": [c.text.strip() for c in choice_instances], }) comment_options = get_comment_options(comment) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) # Steemconnect sometimes returns 503. # https://github.com/steemscript/steemconnect/issues/356 if not isinstance(resp, dict): messages.add_message( request, messages.ERROR, "We got an unexpected error from Steemconnect. Please, try again.") return redirect("detail", poll.username, poll.permlink) # Expected way to receive errors on broadcasting if 'error' in resp: messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) return redirect("detail", poll.username, poll.permlink) # register the vote to the database for choice_instance in choice_instances: choice_instance.voted_users.add(request.user) block_id = resp.get("result", {}).get("block_num") trx_id = resp.get("result", {}).get("id") # add trx id and block id to the audit log vote_audit = VoteAudit(question=poll, voter=request.user, block_id=block_id, trx_id=trx_id) vote_audit.save() for choice_instance in choice_instances: vote_audit.choices.add(choice_instance) messages.add_message(request, messages.SUCCESS, "You have successfully voted!") return redirect("detail", poll.username, poll.permlink)
def edit_poll(request, author, permlink): if not request.user.is_authenticated: return redirect('login') try: poll = Question.objects.get( permlink=permlink, username=author, ) except Question.DoesNotExist: raise Http404 if author != request.user.username: raise Http404 if request.method == "GET": poll_data = fetch_poll_data(poll.username, poll.permlink) tags = poll_data.get("tags", []) tags = [tag for tag in tags if tag not in settings.DEFAULT_TAGS] form_data = { "question": poll.text, "description": poll.description, "answers": [c.text for c in Choice.objects.filter(question=poll)], "expire_at": poll.expire_at_humanized, "tags": ",".join(tags), "allow_multiple_choices": poll.allow_multiple_choices } if request.method == 'POST': form_data = copy.copy(request.POST) if 'sc_token' not in request.session: return redirect("/") error, question, choices, expire_at, _, days, tags, \ allow_multiple_choices = validate_input(request) if tags: tags = settings.DEFAULT_TAGS + tags else: tags = settings.DEFAULT_TAGS permlink = poll.permlink if error: form_data.update({ "answers": request.POST.getlist("answers[]"), "expire_at": request.POST.get("expire-at"), "allow_multiple_choices": request.POST.get("allow-multiple-choices"), }) return render(request, "edit.html", {"form_data": form_data}) # add question question = add_or_get_question(request, question, permlink, days, allow_multiple_choices) question.save() # add answers attached to it add_choices(question, choices, flush=True) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token"), oauth_base_url="https://hivesigner.com/oauth2/", sc2_api_base_url="https://hivesigner.com/api/") comment = get_comment(request, question, choices, permlink, tags=tags) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), ]) if 'error' in resp: if 'The token has invalid role' in resp.get("error_description"): # expired token auth_logout(request) return redirect('login') messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) question.delete() return redirect('edit', args=(author, permlink)) return redirect('detail', question.username, question.permlink) return render(request, "edit.html", { "form_data": form_data, })
def create_poll(request): if not request.user.is_authenticated: return redirect('login') if request.method == 'POST': form_data = copy.copy(request.POST) if 'sc_token' not in request.session: return redirect("/") error, question, choices, expire_at, permlink, days, tags, \ allow_multiple_choices = validate_input(request) if error: form_data.update({ "answers": request.POST.getlist("answers[]"), "expire_at": request.POST.get("expire-at"), "reward_option": request.POST.get("reward-option"), "allow_multiple_choices": request.POST.get("allow-multiple-choices"), }) return render(request, "add.html", {"form_data": form_data}) if (Question.objects.filter(permlink=permlink, username=request.user)).exists(): messages.add_message(request, messages.ERROR, "You have already a similar poll.") return redirect('create-poll') # add question question = add_or_get_question(request, question, permlink, days, allow_multiple_choices) question.save() # add answers attached to it add_choices(question, choices) # send it to the steem blockchain sc_client = Client(access_token=request.session.get("sc_token"), oauth_base_url="https://hivesigner.com/oauth2/", sc2_api_base_url="https://hivesigner.com/api/") comment = get_comment(request, question, choices, permlink, tags) comment_options = get_comment_options( comment, reward_option=request.POST.get("reward-option")) if not settings.BROADCAST_TO_BLOCKCHAIN: resp = {} else: resp = sc_client.broadcast([ comment.to_operation_structure(), comment_options.to_operation_structure(), ]) if 'error' in resp: if 'The token has invalid role' in resp.get("error_description"): # expired token auth_logout(request) return redirect('login') messages.add_message(request, messages.ERROR, resp.get("error_description", "error")) question.delete() return redirect('create-poll') return redirect('detail', question.username, question.permlink) return render(request, "add.html")
from flask import Flask, request from hivesigner.client import Client app = Flask(__name__) client_id = "your.app" client_secret = "your_secret" c = Client(client_id=client_id, client_secret=client_secret) @app.route('/') def index(): login_url = c.get_login_url( "http://*****:*****@app.route('/welcome') def welcome(): c.access_token = request.args.get("access_token") return "Welcome <strong>%s</strong>!" % c.me()["name"]