Skip to content

Commit fb99d0d

Browse files
author
Huan Li
committed
Implement Simple Admin Flow for Spigit
1 parent 22da025 commit fb99d0d

File tree

14 files changed

+623
-32
lines changed

14 files changed

+623
-32
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ The following configuration parameters are available:
3434
| ACCOUNTS_CONNECTOR_URL | Url to TC account connector |
3535
| JWT_V3_NAME | jwt V3 cookie name |
3636
| JWT_V2_NAME | jwt V2 cookie name |
37+
| OAUTH2_TOKEN_NAME | OAuth2 token name |
38+
| OAUTH2_TOKEN_EXPIRETIME_TAGNAME | OAuth2 token expire time tag name |
39+
| OAUTH2_CLIENT_SECRET | OAuth2 client secret |
40+
| SPIGIT_API_URL | SPIGIT api base url |
41+
|SPIGIT_API_VERSION_PATH | SPIGIT api version path |
3742

3843
## Start the Application
3944

config.json

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
"AUTH_URL": "https://accounts.topcoder-dev.com/member",
88
"ACCOUNTS_CONNECTOR_URL": "https://accounts.topcoder-dev.com/connector.html",
99
"JWT_V3_NAME": "v3jwt",
10-
"JWT_V2_NAME": "tcjwt"
10+
"JWT_V2_NAME": "tcjwt",
11+
"OAUTH2_TOKEN_NAME": "oa2spigit",
12+
"OAUTH2_TOKEN_EXPIRETIME_TAGNAME": "oa2expire",
13+
"OAUTH2_CLIENT_SECRET": "qTyeKfuKB7h3CG6tVFJf3QIoMpmp4gnliRupMAM2jEqGjqYR",
14+
"SPIGIT_API_URL": "spigit.com",
15+
"SPIGIT_API_VERSION_PATH" : "/api/v1"
1116
},
1217
"dev": {
1318
"API_URL" : "https://api.topcoder-dev.com",
@@ -17,7 +22,12 @@
1722
"AUTH_URL": "https://accounts.topcoder-dev.com/member",
1823
"ACCOUNTS_CONNECTOR_URL": "https://accounts.topcoder-dev.com/connector.html",
1924
"JWT_V3_NAME": "v3jwt",
20-
"JWT_V2_NAME": "tcjwt"
25+
"JWT_V2_NAME": "tcjwt",
26+
"OAUTH2_TOKEN_NAME": "oa2spigit",
27+
"OAUTH2_TOKEN_EXPIRETIME_TAGNAME": "oa2expire",
28+
"OAUTH2_CLIENT_SECRET": "qTyeKfuKB7h3CG6tVFJf3QIoMpmp4gnliRupMAM2jEqGjqYR",
29+
"SPIGIT_API_URL": "spigit.com",
30+
"SPIGIT_API_VERSION_PATH" : "/api/v1"
2131
},
2232
"qa": {
2333
"API_URL" : "https://api.topcoder-qa.com",
@@ -27,7 +37,12 @@
2737
"AUTH_URL": "https://accounts.topcoder-qa.com/member",
2838
"ACCOUNTS_CONNECTOR_URL": "https://accounts.topcoder-qa.com/connector.html",
2939
"JWT_V3_NAME": "v3jwt",
30-
"JWT_V2_NAME": "tcjwt"
40+
"JWT_V2_NAME": "tcjwt",
41+
"OAUTH2_TOKEN_NAME": "oa2spigit",
42+
"OAUTH2_TOKEN_EXPIRETIME_TAGNAME": "oa2expire",
43+
"OAUTH2_CLIENT_SECRET": "qTyeKfuKB7h3CG6tVFJf3QIoMpmp4gnliRupMAM2jEqGjqYR",
44+
"SPIGIT_API_URL": "spigit.com",
45+
"SPIGIT_API_VERSION_PATH" : "/api/v1"
3146
},
3247
"prod": {
3348
"API_URL" : "https://api.topcoder.com",
@@ -37,6 +52,11 @@
3752
"AUTH_URL": "https://accounts.topcoder.com/member",
3853
"ACCOUNTS_CONNECTOR_URL": "https://accounts.topcoder.com/connector.html",
3954
"JWT_V3_NAME": "v3jwt",
40-
"JWT_V2_NAME": "tcjwt"
55+
"JWT_V2_NAME": "tcjwt",
56+
"OAUTH2_TOKEN_NAME": "oa2spigit",
57+
"OAUTH2_TOKEN_EXPIRETIME_TAGNAME": "oa2expire",
58+
"OAUTH2_CLIENT_SECRET": "qTyeKfuKB7h3CG6tVFJf3QIoMpmp4gnliRupMAM2jEqGjqYR",
59+
"SPIGIT_API_URL": "spigit.com",
60+
"SPIGIT_API_VERSION_PATH" : "/api/v1"
4161
}
4262
}

src/app/app.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,20 @@ angular.module('supportAdminApp', [
389389
templateUrl: 'app/challenges/challenges.html',
390390
data: { pageTitle: 'Challenge Management'},
391391
resolve: { auth: authenticate }
392+
})
393+
.state('index.ideas', {
394+
abstract: true,
395+
url: '/ideas',
396+
templateUrl: 'app/ideas/ideas.html',
397+
data: { pageTitle: 'Spigit' },
398+
controller: 'IdeasController'
399+
})
400+
.state('index.ideas.list', {
401+
url: '/list',
402+
templateUrl: 'app/ideas/ideas.list.html',
403+
data: { pageTitle: 'Spigit - Idea List' },
404+
controller: 'IdeaListController',
405+
resolve: { auth: authenticate }
392406
});
393407

394408
$urlRouterProvider.otherwise('/index/main');

src/app/auth/auth.config.js

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ angular.module('supportAdminApp')
1212
var refreshingToken = null;
1313

1414
jwtInterceptorProvider.tokenGetter = [
15-
'AuthService', '$http', 'API_URL', 'ADMIN_TOOL_URL', 'config',
16-
function($authService, $http, API_URL, ADMIN_TOOL_URL, config) {
15+
'AuthService', '$http', 'API_URL', 'ADMIN_TOOL_URL', 'config', 'SPIGIT_API_URL',
16+
function($authService, $http, API_URL, ADMIN_TOOL_URL, config, SPIGIT_API_URL) {
1717
// token V2 for API V2
1818
if (config.url.indexOf(ADMIN_TOOL_URL) > -1) {
1919
if ($authService.getTokenV2()) {
@@ -24,39 +24,42 @@ angular.module('supportAdminApp')
2424

2525
// token V3 for API V3
2626
} else {
27-
var currentToken = $authService.getTokenV3();
27+
if (config.url.indexOf(SPIGIT_API_URL) === -1) {
2828

29-
function handleRefreshResponse(res) {
30-
var newToken, ref, ref1, ref2;
29+
var currentToken = $authService.getTokenV3();
3130

32-
newToken = (ref = res.data) != null ? (ref1 = ref.result) != null ? (ref2 = ref1.content) != null ? ref2.token : void 0 : void 0 : void 0;
31+
function handleRefreshResponse(res) {
32+
var newToken, ref, ref1, ref2;
3333

34-
$authService.setTokenV3(newToken);
34+
newToken = (ref = res.data) != null ? (ref1 = ref.result) != null ? (ref2 = ref1.content) != null ? ref2.token : void 0 : void 0 : void 0;
3535

36-
return newToken;
37-
};
36+
$authService.setTokenV3(newToken);
3837

39-
function refreshingTokenComplete() {
40-
return refreshingToken = null;
41-
};
38+
return newToken;
39+
};
4240

43-
if ($authService.getTokenV3() && $authService.isTokenV3Expired()) {
44-
if (refreshingToken === null) {
45-
refreshingToken = $http({
46-
method: 'GET',
47-
url: API_URL + "/v3/authorizations/1",
48-
headers: {
49-
'Authorization': "Bearer " + currentToken
50-
}
51-
})
52-
.then(handleRefreshResponse)["finally"](refreshingTokenComplete)
53-
.catch(function() {
54-
$authService.login();
55-
});
41+
function refreshingTokenComplete() {
42+
return refreshingToken = null;
43+
};
44+
45+
if ($authService.getTokenV3() && $authService.isTokenV3Expired()) {
46+
if (refreshingToken === null) {
47+
refreshingToken = $http({
48+
method: 'GET',
49+
url: API_URL + "/v3/authorizations/1",
50+
headers: {
51+
'Authorization': "Bearer " + currentToken
52+
}
53+
})
54+
.then(handleRefreshResponse)["finally"](refreshingTokenComplete)
55+
.catch(function () {
56+
$authService.login();
57+
});
58+
}
59+
return refreshingToken;
60+
} else {
61+
return currentToken;
5662
}
57-
return refreshingToken;
58-
} else {
59-
return currentToken;
6063
}
6164
}
6265
}];
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<div class="inmodal">
2+
<div class="modal-header" style="padding:14px"></div>
3+
<div class="modal-body">
4+
<div class="row">
5+
<div class="text-center" ng-show="isLoading">
6+
<img src="assets/images/loading.gif" />
7+
</div>
8+
<form role="form" name="detaillForm">
9+
<div class="col-md-12" ng-include src="'components/alert/alert.html'"></div>
10+
<div class="form-group">
11+
<h2>Idea Information</h2>
12+
<label>Ttitle</label>
13+
<input ng-model="form.title" type="text" class="form-control" readonly="readonly">
14+
</div>
15+
<div class="form-group">
16+
<label>Content</label>
17+
<div ng-bind-html="form.content" class="content"></div>
18+
<!--<div><textarea readonly="readonly">{{form.content}}</textarea></div>-->
19+
</div>
20+
<hr>
21+
<h2>Creator Information</h2>
22+
<div class="form-group">
23+
<label>First Name</label>
24+
<input ng-model="form.firstName" type="text" class="form-control" readonly="readonly">
25+
</div>
26+
<div class="form-group">
27+
<label>Last Name</label>
28+
<input ng-model="form.lastName" type="text" class="form-control" readonly="readonly">
29+
</div>
30+
<div class="form-group">
31+
<label>Email</label>
32+
<input ng-model="form.email" type="text" class="form-control" readonly="readonly">
33+
</div>
34+
</form>
35+
</div>
36+
</div>
37+
<div class="modal-footer">
38+
<button type="button" class="btn btn-white" ng-click="cancel()" ng-disabed="form.isLoading">
39+
Close
40+
</button>
41+
</div>
42+
<div style="text-align:center;position:absolute;top:65px;left:0;width:100%;height:100%;zIndex:1;"
43+
ng-show="form.isLoading">
44+
<img src="assets/images/loading.gif"/>
45+
</div>
46+
</div>

src/app/ideas/ideas.controller.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
var module = angular.module('supportAdminApp');
4+
5+
/**
6+
* The parent controller for the clients states
7+
*/
8+
module.controller('IdeasController', ['$scope', 'AuthService', '$state',
9+
function ($scope, $authService, $state) {
10+
$scope.$state = $state;
11+
12+
/**
13+
* Validate the user authentication
14+
*/
15+
$scope.authorized = function() {
16+
return $authService.isLoggedIn();
17+
};
18+
}
19+
]);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
var module = angular.module('supportAdminApp');
4+
5+
module.controller('IdeasDetailController', ['$scope', '$log','IdeaService', 'Alert', '$timeout', 'OAuth2Service','$uibModalInstance', 'ideaId', 'domain', 'username', 'password', 'clientId', '$sce', 'SPIGIT_API_URL',
6+
function ($scope, $log, IdeaService, $alert, $timeout, OAuth2Service, $modalInstance, ideaId, domain, username, password, clientId, $sce, SPIGIT_API_URL) {
7+
8+
$scope.ideaId = ideaId;
9+
$scope.domain = domain;
10+
$scope.username = username;
11+
$scope.password = password;
12+
$scope.clientId = clientId;
13+
14+
$scope.form = {};
15+
$scope.isLoading = false;
16+
17+
$scope.load = function() {
18+
19+
$scope.isLoading = true;
20+
21+
// If token expired should get new token first
22+
if (OAuth2Service.checkTokenExpireTime()) {
23+
OAuth2Service.refreshToken($scope.username, $scope.password, $scope.domain, $scope.clientId).then(function (data) {
24+
$scope.loadDetail();
25+
}).catch(function (error) {
26+
$alert.error(error.message, $scope);
27+
$scope.isLoading = false;
28+
});
29+
} else {
30+
$scope.loadDetail();
31+
}
32+
}
33+
34+
// get idea detail
35+
$scope.loadDetail = function() {
36+
IdeaService.getIdeaDetail(domain, $scope.ideaId).then(function (data) {
37+
$scope.form.title = data.title;
38+
$scope.form.content = $sce.trustAsHtml($scope.convertContent(data.content));
39+
// get creator detail
40+
IdeaService.getUserDetail(domain, data.creator_id).then(function(user) {
41+
$scope.form.firstName = user.first_name;
42+
$scope.form.lastName = user.last_name;
43+
$scope.form.email = user.primary_email;
44+
$scope.isLoading = false;
45+
});
46+
}).catch(function (error) {
47+
$alert.error(error.error, $scope);
48+
$scope.isLoading = false;
49+
});
50+
}
51+
52+
/**
53+
* Convert detail content without html tags
54+
* @param content
55+
* @returns {string}
56+
*/
57+
$scope.convertContent = function(content) {
58+
var newContent= content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi,function(match,capture){
59+
var newStr='<img src="http://' + domain + "." + SPIGIT_API_URL +capture+'" />';
60+
return newStr;
61+
});
62+
return newContent;
63+
}
64+
65+
$scope.cancel = function() {
66+
$modalInstance.close();
67+
};
68+
69+
70+
$scope.load();
71+
}
72+
]);

src/app/ideas/ideas.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div class="row wrapper border-bottom white-bg page-heading">
2+
<div class="col-lg-10">
3+
<h2>{{$state.current.data.pageTitle}}</h2>
4+
</div>
5+
<div class="col-md-10 col-lg-12" ng-include src="'components/alert/alert.html'"></div>
6+
</div>
7+
<div ui-view=""></div>

0 commit comments

Comments
 (0)