Skip to content

Instantly share code, notes, and snippets.

@kevprice83
Last active October 26, 2022 03:41
Show Gist options
  • Save kevprice83/666f625f2c95c5f94baeb4f23f2f6bad to your computer and use it in GitHub Desktop.
Save kevprice83/666f625f2c95c5f94baeb4f23f2f6bad to your computer and use it in GitHub Desktop.
Developer portal solution for multiple services and scoped users

What is this?

  • This gist is a solution to build a developer portal in 3scale with a workflow that allows signup to services based on the scope of the user.
  • The template have been adapted from the default index.html page.
  • This solution is dependent on the correct settings being configured in the 3scale admin portal & the users being scoped by means of the Groups feature.
  • The Service Plan Features have been used in this solution instead of the Service system_name.
<header class="jumbotron page-header">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1> &nbsp; </h1>
</div>
</div>
</div>
</header>
<section class="sell">
<div class="container">
<div class="row">
<div class="col-md-4">
<h3>Register</h3>
<p>
<i class="fa fa-sign-in fa-3x pull-left"></i> Register to the developer portal to use the Echo API
</p>
</div>
<div class="col-md-4">
<h3>Get your API key</h3>
<p>
<i class="fa fa-key fa-3x pull-left"></i> Use your API key to authenticate and report the calls you make
</p>
</div>
<div class="col-md-4">
<h3>Create your app</h3>
<p>
<i class="fa fa-code fa-3x pull-left"></i> Start coding and create awesome applications with the Echo API
</p>
</div>
</div>
</div>
</section>
{% if current_user %}
<section class="plans" id="plans">
<div class="container">
<h1>Pick your group plan</h1>
<br/>
<div class="row">
{% assign sections = current_user.sections %}
{% for service in provider.services %}
{% for section in sections %}
{% assign cleanedsection = section | remove_first: "/" %}
{% for feature in service.features %}
{% if feature.system_name contains cleanedsection %}
{% for plan in service.application_plans %}
<div class="col-md-6">
<article class="panel panel-default">
<div class="panel-heading">
<strong>{{ plan.name }}</strong>
</div>
<div class="panel-body">
<div class="row">
{% if plan.features == present %}
<div class="col-md-6">
<h5>Features</h5>
<ul class="features list-unstyled">
{% for feature in plan.features %}
<li>
<i class="fa fa-check"></i> {{ feature.name }}
</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="col-md-6">
<h5>Limits{{ plan.trial_period_days.size }}</h5>
<ul class="limits list-unstyled">
{% if plan.usage_limits == present %} {% for limit in plan.usage_limits %}
<li>
<i class="fa fa-signal"></i> {{ limit.metric.name }} &ndash; {{ limit.value }} {{ limit.metric.unit }}s per {{ limit.period }}
</li>
{% endfor %} {% else %}
<li>
<i class="fa fa-signal"></i> No limits
</li>
{% endif %}
</ul>
</div>
</div>
</div>
<div class="panel-footer">
<div class="row">
<div class="col-md-12">
{% if service.subscription %}
<a href="{{urls.new_application}}?service_id={{service.system_name}}&application[plan_id]={{plan.id}}" type="button" class="btn btn-success pull-right">Signup to plan {{ plan.name }}</a>
{% else %}
<a href="{{urls.service_subscription}}?service_id={{service.id}}" class="btn btn-success pull-right">Subscribe to {{ service.name }} Service</a> {% endif %}
</div>
</div>
</div>
</article>
</div>
{% endfor %}
{% else %}
{% comment %}
Maybe render a signup or login button
{% endcomment %}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
</div>
</div>
</section>
{% else %}
{% comment %}
Maybe render a signup or login button
{% endcomment %}
{% endif %}
<section class="invert">
<div class="container">
<h1>Run your requests</h1>
<div class="row">
<div class="col-md-12">
<h3><code style="display:block">$ curl -v https://echo-api.3scale.net</code></h3>
<br/>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
Request
</div>
<div class="panel-body panel-footer">
<pre>
&gt; GET / HTTP/1.1
&gt; User-Agent: curl/7.27.0
&gt; Host: https://echo-api.3scale.net/echo
&gt; Accept: */*
&gt;
</pre>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
Response
</div>
<div class="panel-body panel-footer">
<pre>
&lt; HTTP/1.1 200 OK
&lt; Content-Type: text/plain; charset=utf-8
&lt; Connection: close
echo
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
@mayorova
Copy link

mayorova commented Dec 5, 2017

Two suggestions to improve this Gist:

  1. applications_form.html.liquid doesn't need to be customized, if we use application[plan_id] query parameter for the /admin/applications/new page.

  2. The following line:

<button type="button" class="btn btn-success pull-right" onclick="subscribe('{{plan.service.system_name}}', '{{plan.id}}')">Signup to plan {{ plan.name }}</button>

can be replaced with:

<a href="{{ urls.new_application }}?service_id={{ service.system_name }}&application[plan_id]={{ plan.id }}"class="btn btn-success pull-right">Sign up to plan {{ plan.name }}</a>

so this can be removed as well:

<script>
    function subscribe(serviceId, planId) {  
      window.location.href = '/admin/applications/new?service_id=' + serviceId + '&plan_id=' + planId; 
    }
</script>

@kevprice83
Copy link
Author

@mayorova thanks, I have updated the solution now. Much more streamlined. Tested it also and it works fine this way too. Thanks for the contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment