Commits

Andreas Knecht committed aa9cbc6

Make the this a generic example.

Comments (0)

Files changed (15)

-# NPS Score app
+# Issue Example App
 
-Provides a standalone Node JS app that can be integrated with JIRA using plugins 3.
+Provides a standalone Node JS app that can be integrated with JIRA using plugins 3. It provides OAuth validation so that
+Atlassian apps can make authenticated requests to the node app. Admins can approve OAuth consumers (via /oauth/approve)
+ to be allowed to make requests.  After this the validator sets a certified cookie that will be used for future requests.
 
 To run this app get the source. Then:
 
 
 You can then access the app on http://localhost:3000/. There are a number of environment variables that should be set for this app to function correctly:
 
-*   NPS_DB_USER - the user to connect to the greenzone db
-*   NPS_DB_PASSWORD - the password to connect to the greenzone db
-*   NPS_COOKIE_SECRET - secret used to encrypt cookies
-*   NPS_ADMIN_USER - admin user name to log in to the admin section of this app
-*   NPS_ADMIN_PASSWORD - admin password to log in to the admin section of this app
+*   ATL_COOKIE_SECRET - secret used to encrypt cookies
+*   ATL_ADMIN_USER - admin user name to log in to the admin section of this app
+*   ATL_ADMIN_PASSWORD - admin password to log in to the admin section of this app
 
 var express = require('express')
     , routes = require('./routes')
-    , user = require('./routes/user')
     , oauth = require('./routes/oauth')
-    , nps = require('./routes/npsscore')
+    , issue = require('./routes/issue')
     , plugin = require('./routes/plugin')
     , http = require('http')
     , path = require('path')
     app.use(express.logger('dev'));
     app.use(express.bodyParser());
     app.use(express.methodOverride());
-    app.use(express.cookieParser(process.env.NPS_COOKIE_SECRET));
+    app.use(express.cookieParser(process.env.ATL_COOKIE_SECRET || "ssssh!"));
     app.use(express.session());
     app.use(express.static(path.join(__dirname, 'public')));
-    app.use("/nps", oauthValidator(consumerStore));
+    app.use("/issue", oauthValidator(consumerStore));
     app.use(app.router);
     app.use(express.errorHandler());
 });
 app.get('/', routes.index);
 app.post('/plugin/installed', plugin.pluginInstalled);
 
-var adminAuth = express.basicAuth(process.env.NPS_ADMIN_USER || 'admin', process.env.NPS_ADMIN_PASSWORD || 'admin');
+var adminAuth = express.basicAuth(process.env.ATL_ADMIN_USER || 'admin', process.env.ATL_ADMIN_PASSWORD || 'admin');
 
 app.get('/oauth/approve', adminAuth, oauth.list);
 app.put('/oauth/approve/:consumerkey', adminAuth, oauth.approve);
 app.delete('/oauth/approve/:consumerkey', adminAuth, oauth.remove);
 
-app.get('/nps/issue', nps.issueScore);
-app.get('/nps/rest/issue', nps.restIssueScore);
-app.get('/nps/reporter/:reporter', nps.reporterScore);
+app.get('/issue', issue.panel);
+app.get('/issue/details', issue.details);
 
 express.errorHandler.title = "Oops. Something went wrong...";
 

oauthValidator.js

 var _ = require('underscore'),
-    fs = require('fs'),
     crypto = require('crypto');
 
 module.exports = function (consumerStore) {
             oauthSignature = req.param("oauth_signature");
 
         //looks like we did the oauth dance earlier.
-        if (req.signedCookies.remoteUser === "sac") {
+        if (req.signedCookies.remoteUser === "atlassian") {
             return next();
         }
 
         var valid = verifier.verify(consumerInfo.publicKey, oauthSignature, 'base64');
 
         if (valid) {
-            res.cookie('remoteUser', 'sac', { httpOnly:true, signed:true });
+            res.cookie('remoteUser', 'atlassian', { httpOnly:true, signed:true });
             res.cookie('consumerKey', oauthConsumerKey, { httpOnly:true, signed:true });
             next();
         } else {
 {
-    "name":"NPS-Score",
+    "name":"Issue-Example",
     "version":"0.0.1",
     "private":true,
     "scripts":{
         "start":"node app"
     },
     "dependencies":{
-        "pg":"0.8.7",
         "underscore":"1.4.2",
         "express":"3.0.3",
         "hjs":"*",

public/atlassian-plugin.xml

-<atlassian-plugin key="nps-score-app" name="NPS Score" plugins-version="2"
+<atlassian-plugin key="issue-example-app" name="Issue Example App" plugins-version="2"
                   xmlns="https://remoteapps.jira.com/rest/remotable-plugins/1/installer/schema/atlassian-plugin">
     <plugin-info>
         <description>Displays NPS Score on the view issue page.</description>
         </permissions>
     </plugin-info>
 
-    <remote-plugin-container key="nps-score-container" display-url="http://localhost:3000/" />
+    <remote-plugin-container key="remote-issue-app" display-url="http://localhost:3000/"/>
 
-    <issue-panel-page key="nps-score" name="NPS Score" url="/nps/issue">
+    <issue-panel-page key="issue-example" name="Remote Issue Example" url="/issue">
         <conditions>
             <condition name="has_issue_permission">
-                <param name="permission">move</param>
+                <param name="permission">edit</param>
             </condition>
         </conditions>
     </issue-panel-page>

public/javascripts/issue.js

+(function () {
+    jQuery(function () {
+        var issueId = jQuery("#issueId").text();
+        RA.request("/rest/api/2/issue/" + issueId, {
+            success:function (resp) {
+                var issue = JSON.parse(resp);
+                jQuery.get("http://localhost:3000/issue/details?issueId=" + jQuery("#issueId").text() + "&reporterEmail=" + issue.fields.reporter.emailAddress,
+                    function (remoteResp) {
+                        jQuery("body").html(remoteResp);
+                        RA.resize();
+                    });
+            }
+        });
+    });
+})();

public/javascripts/npsscore.js

-(function () {
-    jQuery(function () {
-        var issueId = jQuery("#issueId").text();
-        RA.request("/rest/api/2/issue/" + issueId, {
-            success:function (resp) {
-                var issue = JSON.parse(resp);
-                jQuery.get("http://localhost:3000/nps/rest/issue?issueId=" + jQuery("#issueId").text() +
-                    "&reporterEmail=" + issue.fields.reporter.emailAddress,
-                    function (remoteResp) {
-                        jQuery("body").html(remoteResp);
-                    });
-            }
-        });
-    });
-})();
  */
 
 exports.index = function(req, res){
-  res.render('index', { title: 'NPS Score' });
+  res.render('index', { title: 'Plugins 3 example.' });
 };
+/*
+ * GET NPS scores for an issue
+ */
+
+
+exports.panel = function (req, res, next) {
+    var issue_id = req.query.issue_id;
+    if (issue_id === undefined) {
+        res.send(404, "Please provide a valid issue key");
+    }
+
+    res.render('issuepanel', { issueId:issue_id });
+};
+
+exports.details = function (req, res, next) {
+    var issueId = req.query.issueId;
+    if (issueId === undefined) {
+        res.send(404, "Please provide a valid issue key");
+    }
+
+    // do some expensive processing!
+
+    res.send("<p>Do some cool node js shit for reporter '" + req.query.reporterEmail + "'!</p>")
+};

routes/npsscore.js

-/*
- * GET NPS scores for an issue
- */
-var pg = require('pg');
-
-var conString = "tcp://" + process.env.NPS_DB_USER + ":" + process.env.NPS_DB_PASSWORD + "@atlassian66/greenzone";
-
-exports.reporterScore = function (req, res, next) {
-    return next(new Error("Not implemented yet!"));
-};
-
-exports.issueScore = function (req, res, next) {
-    var issue_id = req.query.issue_id;
-    if (issue_id === undefined) {
-        res.send(404, "Please provide a valid issue key");
-    }
-
-    res.render('npsscore', { issueId:issue_id });
-};
-
-exports.restIssueScore = function (req, res, next) {
-    var issueId = req.query.issueId;
-    if (issueId === undefined) {
-        res.send(404, "Please provide a valid issue key");
-    }
-    pg.connect(conString, function (err, client) {
-        if (err) {
-            return next(err);
-        }
-
-        client.query("select * from support_csat sc, support s where s.issue_id = $1 and sc.issue = s.issue", [issueId], function (err, result) {
-            if (err) {
-                return next(err);
-            }
-
-            if (result.rows.length == 1) {
-                var firstRow = result.rows[0];
-                res.send("<p>NPS Score: " + firstRow["q2_support_nps"] + "</p>");
-            } else {
-                res.send("<p>No NPS scores are associated with this issue.</p>");
-            }
-        });
-    });
-};

routes/user.js

-
-/*
- * GET users listing.
- */
-
-exports.list = function(req, res){
-  res.send("respond with a resource");
-};
 <!DOCTYPE html>
-<html>
-  <head>
-    <title>{{ title }}</title>
-    <link rel='stylesheet' href='/stylesheets/style.css' />
-  </head>
-  <body>
-    <h1>{{ title }}</h1>
-    <p>Welcome to {{ title }}</p>
-  </body>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=EDGE">
+    <title>{{title}}</title>
+
+    <link rel="stylesheet" href="/aui-5.0-m18/css/aui-all.css" media="all">
+    <!--[if IE]><link rel="stylesheet" href="/aui-5.0-m18/css/aui-ie.css" media="all"><![endif]-->
+    <!--[if IE 9]><link rel="stylesheet" href="/aui-5.0-m18/css/aui-ie9.css" media="all"><![endif]-->
+    <script src="/aui-5.0-m18/js/aui-all.js"></script>
+</head>
+<body class="aui-layout aui-theme-default">
+<div id="page">
+    <header id="header" role="banner">
+        <nav class="aui-header" role="navigation">
+            <div class="aui-header-primary">
+                <h1 id="logo" class="aui-header-logo aui-header-logo-aui"><a href="https://localhost:3000/"></a></h1>
+                <ul class="aui-nav">
+                    <li class="selected"><a href="/">Home</a></li>
+                    <li><a href="/oauth/approve">OAuth</a></li>
+                </ul>
+            </div>
+        </nav>
+    </header>
+    <section id="content" role="main">
+
+        <header class="aui-page-header">
+            <h1>{{title}}</h1>
+        </header>
+
+        <div class="aui-page-panel">
+            <div class="aui-page-panel-inner">
+                <section class="aui-page-panel-content">
+                    <p>Welcome!</p>
+                </section>
+            </div>
+        </div>
+        <!-- .aui-panel -->
+
+    </section>
+    <!-- #content -->
+
+    <footer id="footer" role="contentinfo">
+        <section class="footer-body">
+            <ul>
+                <li>NPS Score</li>
+            </ul>
+        </section>
+    </footer>
+</div>
+<!-- #page -->
+
+</body>
 </html>

views/issuepanel.hjs

+<!DOCTYPE html>
+<html>
+<head>
+    <title>{{ title }}</title>
+
+    <link rel='stylesheet' href='/stylesheets/style.css'/>
+    <link rel="stylesheet" href="http://localhost:2990/jira/remotable-plugins/all-debug.css">
+
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
+    <script src="/javascripts/issue.js" type="text/javascript"></script>
+
+    <script src="http://localhost:2990/jira/remotable-plugins/all.js" type="text/javascript"></script>
+    <script type="text/javascript">
+        RA.init();
+    </script>
+</head>
+<body>
+<div id="issueId" class="hidden">{{issueId}}</div>
+<p class="result">Loading...</p>
+</body>
+</html>

views/npsscore.hjs

-<!DOCTYPE html>
-<html>
-<head>
-    <title>{{ title }}</title>
-    <link rel='stylesheet' href='/stylesheets/style.css'/>
-    <link rel="stylesheet" href="http://localhost:2990/jira/remotable-plugins/all-debug.css">
-    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
-    <script src="/javascripts/npsscore.js" type="text/javascript"></script>
-    <script src="http://localhost:2990/jira/remotable-plugins/all.js" type="text/javascript"></script>
-    <script type="text/javascript">
-        RA.init();
-    </script>
-</head>
-<body>
-<div id="issueId" class="hidden">{{issueId}}</div>
-<p class="result">Loading...</p>
-</body>
-</html>

views/oauthconsumers.hjs

             <div class="aui-header-primary">
                 <h1 id="logo" class="aui-header-logo aui-header-logo-aui"><a href="https://localhost:3000/"></a></h1>
                 <ul class="aui-nav">
+                    <li><a href="/">Home</a></li>
                     <li class="selected"><a href="/oauth/approve">OAuth</a></li>
                 </ul>
             </div>