Skip to content

Commit dec371a

Browse files
committed
- Updated github actions
- Removed 'request' due to vulnerabilities and replaced with node-fetch - Added build tests to ensure changes were not breaking - Resolves some long standing issues with some of the capabilities - Added Software AG cloud options
1 parent 59f1925 commit dec371a

21 files changed

+1997
-562
lines changed

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "monthly"

.github/workflows/ci.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3+
4+
name: Node.js CI
5+
6+
on:
7+
push:
8+
branches: [ "main" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
strategy:
18+
matrix:
19+
node-version: [20.12.2]
20+
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
- name: Use Node.js ${{ matrix.node-version }}
25+
uses: actions/setup-node@v3
26+
with:
27+
node-version: ${{ matrix.node-version }}
28+
cache: 'npm'
29+
- run: npm install
30+
31+
# run the tests
32+
- name: Test Build
33+
shell: bash
34+
run: |
35+
npm test ${{ secrets.TENANT_USER_ID }} '${{ secrets.TENANT_USER_PW }}'
36+

EndtoEndTests.sh

Lines changed: 477 additions & 0 deletions
Large diffs are not rendered by default.

accounts.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Apache-2.0
55
*/
66

7-
const request = require('./rest.js');
7+
const request = require('./rest-fetch.js');
88

99

1010
var domainName, username, password, timeout;
@@ -60,7 +60,8 @@ function init(inDomainName, inUsername, inPassword, inTimeout, inPrettyprint) {
6060
* @param {return data from REST request} data
6161
* @param {status} status
6262
*/
63-
function processResponse(data, status) {
63+
function processResponse(restEndPointUrl, err, data, response) {
64+
let status = response.status;
6465
if (prettyprint == true) {
6566
console.log(JSON.stringify(data, null, 4));
6667
}

experimental.js

Lines changed: 114 additions & 80 deletions
Large diffs are not rendered by default.

flowservice.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Apache-2.0
55
*/
66

7-
const rest = require('./rest.js');
7+
const rest = require('./rest-fetch.js');
88
const dbg = require('./debug.js');
99

1010

@@ -69,7 +69,8 @@ function init(inDomainName, inUsername, inPassword,inTimeout,inPrettyPrint,proje
6969
* @param {return data from REST request} data
7070
* @param {status} status
7171
*/
72-
function processResponse(data,status){
72+
function processResponse(restEndPointUrl, err, data, response) {
73+
let status = response.status;
7374
if(prettyprint==true){
7475
console.log(JSON.stringify(data,null,4));
7576
}
@@ -82,14 +83,15 @@ function init(inDomainName, inUsername, inPassword,inTimeout,inPrettyPrint,proje
8283
}
8384
}
8485

85-
function downloadExport(data,status,filename){
86+
function downloadExport(restEndPointUrl, err, data, response,filename){
87+
let status = response.status
8688
debug("Downloading Export");
87-
if(status!=0){
89+
if(status!=200){
8890
console.log(JSON.stringify(data));
8991
process.exit(status);
9092
}
9193
else{
92-
rest.downloadFile(data,filename,downloadCompleted);
94+
rest.downloadFile(data, filename, downloadCompleted);
9395
}
9496
}
9597

@@ -117,7 +119,7 @@ function exportFlowService(flowId, filename){
117119
function importFlowService(filename){
118120
debug("Importing FlowService");
119121
url+="/flow-import";
120-
rest.postUploadFile(url,username,password,timeout,undefined,filename,processResponse);
122+
rest.postUploadFile(url,username,password,timeout,undefined,filename,"recipe",processResponse);
121123
}
122124

123125
function runFlowService(flowId,data){

idm.js

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/*
2+
* webMethods.io CLI
3+
* Copyright 2022 Software AG
4+
* Apache-2.0
5+
*/
6+
7+
const { user } = require('./experimental.js');
8+
const rest = require('./rest-fetch.js');
9+
const sync_rest = require('./sync-rest-fetch.js');
10+
11+
var domainName, username, password, timeout, prettyprint;
12+
var url;
13+
var bearerToken;
14+
15+
function debug(message) {
16+
dbg.message("<IDM> " + message,4);
17+
}
18+
function help() {
19+
return `
20+
\x1b[4mwebMethods Cloud IDM\x1b[0m
21+
22+
\x1b[32mProvides an IDM authtoken for subsequent calls\x1b[0m
23+
$ node wmiocli.js
24+
-d tenant.int-aws-us.webmethods.io
25+
-u user
26+
-p password
27+
idm-authtoken
28+
29+
\x1b[32mGets an IDM users details\x1b[0m
30+
$ node wmiocli.js
31+
-d tenant.int-aws-us.webmethods.io
32+
-u user
33+
-p password
34+
idm-user <username>
35+
36+
\x1b[32mFinds users that match the search criteria\x1b[0m
37+
$ node wmiocli.js
38+
-d tenant.int-aws-us.webmethods.io
39+
-u user
40+
-p password
41+
idm-user-search <query> <include roles - true|false> <product>
42+
where product is one of: apigateway, apiportal, webmethodsioint, b2b,
43+
cumulocity, cloudcontainer, devportal, mft, metering, wmapps
44+
e.g.
45+
idm-user-search Dave true webmethodsioint
46+
47+
\x1b[32mCounts users that match the search criteria\x1b[0m
48+
$ node wmiocli.js
49+
-d tenant.int-aws-us.webmethods.io
50+
-u user
51+
-p password
52+
idm-user-count <query>
53+
where query can be a partial username, e.g.
54+
idm-user-count dave
55+
56+
\x1b[32mLists environment available roles\x1b[0m
57+
$ node wmiocli.js
58+
-d tenant.int-aws-us.webmethods.io
59+
-u user
60+
-p password
61+
idm-roles
62+
63+
\x1b[32mGets user role mappings for the given userid\x1b[0m
64+
$ node wmiocli.js
65+
-d tenant.int-aws-us.webmethods.io
66+
-u user
67+
-p password
68+
idm-user-role-mappings <userid>
69+
where userid is the unique ID returned from the idm-user call
70+
71+
\x1b[32mCreates a user\x1b[0m
72+
$ node wmiocli.js
73+
-d tenant.int-aws-us.webmethods.io
74+
-u user
75+
-p password
76+
idm-user-create <first-name> <last-name> <email> <username>
77+
78+
\x1b[32mDeletes a user\x1b[0m
79+
$ node wmiocli.js
80+
-d tenant.int-aws-us.webmethods.io
81+
-u user
82+
-p password
83+
idm-user-delete <userid>
84+
where userid is the unique ID returned from the idm-user call
85+
86+
\x1b[32mUnlocks a user\x1b[0m
87+
$ node wmiocli.js
88+
-d tenant.int-aws-us.webmethods.io
89+
-u user
90+
-p password
91+
idm-user-unlock <userid>
92+
where userid is the unique ID returned from the idm-user call
93+
`;
94+
}
95+
96+
async function init(inDomainName, inUsername, inPassword, inTimeout, inPrettyPrint) {
97+
domainName = inDomainName;
98+
username = inUsername;
99+
password = inPassword;
100+
timeout = inTimeout;
101+
prettyprint = inPrettyPrint;
102+
debug("Started Init");
103+
url = getApiUrl() + "/authtoken";
104+
debug("Username [" + username + "]");
105+
debug("URL [" + url + "]");
106+
debug("Timeout [" + timeout + "]");
107+
108+
try {
109+
debug("Going to call the sync_rest/get call");
110+
const result = await sync_rest.get(url, inUsername, inPassword, inTimeout, "text/plain");
111+
//debug("Setting bearer Token: " + result.data.substr(0, 10));
112+
bearerToken = result;
113+
if (result.error) {
114+
console.error("Error:", result.error);
115+
}
116+
} catch (error) {
117+
console.error("Unhandled error:", error);
118+
}
119+
120+
debug("done");
121+
}
122+
123+
function getApiUrl()
124+
{
125+
var idmBaseUrl;
126+
if(domainName.indexOf('int-aws-de')>0)idmBaseUrl="https://idmas-eu-central-1.softwareag.cloud";
127+
if(domainName.indexOf('int-aws-us')>0)idmBaseUrl="https://idmas-us-west-2.softwareag.cloud";
128+
if(domainName.indexOf('int-aw-au')>0)idmBaseUrl="https://idmas-aw-au.softwareag.cloud";
129+
if(domainName.indexOf('int-az-au')>0)idmBaseUrl="https://idmas-az-au.softwareag.cloud";
130+
if(domainName.indexOf('int-az-us')>0)idmBaseUrl="https://idmas-az-us.softwareag.cloud";
131+
if(domainName.indexOf('int-az-eu')>0)idmBaseUrl="https://idmas-az-eu.softwareag.cloud";
132+
idmBaseUrl+="/idm/environments/";
133+
"https://idmas-eu-central-1.softwareag.cloud/idm/environments/"
134+
135+
var env = domainName.split(".")[0];
136+
return idmBaseUrl + env;
137+
}
138+
139+
function setHeaders()
140+
{
141+
var headers = [
142+
{"name":"Authorization","value":"Bearer " + bearerToken},
143+
];
144+
return headers;
145+
}
146+
147+
async function authToken(){
148+
debug("Getting authtoken");
149+
url=getApiUrl() + "/authtoken";
150+
await sync_rest.get(url, username, password, timeout, "text/plain");
151+
}
152+
153+
154+
function searchUserInfo(query,includeRoles,products)
155+
{
156+
headers = setHeaders();
157+
158+
url=getApiUrl()+"/users/search?query=" + query + "&includeRoles=" + includeRoles + "&products=" + products;
159+
rest.get(url, username, password, timeout, processResponse);
160+
}
161+
162+
function getUserInfo(inUsername)
163+
{
164+
url=getApiUrl()+"/users?username=" + inUsername;
165+
rest.get(url, username, password, timeout, processResponse);
166+
}
167+
168+
function countUsers(query)
169+
{
170+
var params="";
171+
if(query!==undefined)params="?query=" + query;
172+
url=getApiUrl()+"/users/count" + params;
173+
rest.get(url, username, password, timeout, processTextResponse,"text/plain");
174+
}
175+
176+
function roleMappings(userId)
177+
{
178+
url=getApiUrl()+"/users/" + userId + "/role-mappings";
179+
rest.get(url, username, password, timeout, processResponse);
180+
}
181+
182+
function allRoles()
183+
{
184+
url=getApiUrl()+"/roles/all";
185+
rest.get(url, username, password, timeout, processResponse);
186+
}
187+
188+
async function resetPassword(userId,newPassword)
189+
{
190+
url=getApiUrl()+"/users/" + userId + "/resetPassword";
191+
const base64Pw = Buffer.from(`${newPassword}`).toString('base64');
192+
var data={};
193+
data.password = base64Pw;
194+
headers = setHeaders();
195+
response = await sync_rest.custom(url, undefined, undefined, timeout,data,undefined,"PUT", headers,true,false,undefined,undefined);
196+
console.log(JSON.stringify({"response":response}));
197+
}
198+
199+
async function createUser(firstName,lastName,email,username)
200+
{
201+
debug("Started Create User");
202+
url=getApiUrl()+"/users";
203+
var data={};
204+
data.firstName = firstName;
205+
data.lastName = lastName;
206+
data.email = email;
207+
data.username = username;
208+
headers = setHeaders();
209+
response = await sync_rest.custom(url, undefined, undefined, timeout,data,undefined,"POST", headers,true,false,undefined,undefined);
210+
//console.log(response);
211+
console.log(JSON.stringify({"response":response}));
212+
}
213+
214+
async function deleteUser(userId)
215+
{
216+
url=getApiUrl()+"/users/" + userId;
217+
headers = setHeaders();
218+
response = await sync_rest.custom(url, undefined, undefined, timeout,undefined,undefined,"DELETE", headers,true,false,undefined,undefined);
219+
console.log(JSON.stringify({"response":"deleted"}));
220+
}
221+
222+
async function unlockUser(userId)
223+
{
224+
url=getApiUrl()+"/users/" + userId + "/unlock-user";
225+
headers = setHeaders();
226+
response = await sync_rest.custom(url, undefined, undefined, timeout,undefined,undefined,"DELETE", headers,true,false,undefined,undefined);
227+
console.log(JSON.stringify({"response":"unlocked"}));
228+
}
229+
230+
231+
/**
232+
* Call back function to process REST response
233+
* @param {return data from REST request} data
234+
* @param {status} status
235+
*/
236+
function processTextResponse(restEndPointUrl, err, data, response) {
237+
let status = response.status;
238+
//console.log(status);
239+
//console.log(response.text);
240+
console.log(JSON.stringify({"response":data}));
241+
242+
if (status != 200) {
243+
console.log("Error: " + status);
244+
process.exit(status);
245+
}
246+
}
247+
248+
/**
249+
* Call back function to process REST response
250+
* @param {return data from REST request} data
251+
* @param {status} status
252+
*/
253+
function processResponse(restEndPointUrl, err, data, response) {
254+
let status = response.status;
255+
if (prettyprint == true) {
256+
console.log(JSON.stringify(data, null, 4));
257+
}
258+
else {
259+
console.log(JSON.stringify(data));
260+
}
261+
262+
if (status != 200) {
263+
process.exit(status);
264+
}
265+
}
266+
267+
268+
269+
module.exports = { help, init, authToken, getUserInfo, deleteUser, unlockUser, resetPassword, searchUserInfo,countUsers,roleMappings,allRoles,createUser };

0 commit comments

Comments
 (0)