Skip to content

Commit 32d4564

Browse files
author
Christoph Jahn
committed
Initial working version
1 parent eff3368 commit 32d4564

File tree

14 files changed

+569
-4
lines changed

14 files changed

+569
-4
lines changed

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
# BlueJ files
88
*.ctxt
99

10-
# Mobile Tools for Java (J2ME)
11-
.mtj.tmp/
1210

1311
# Package Files #
1412
*.jar
@@ -21,3 +19,6 @@
2119

2220
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2321
hs_err_pid*
22+
23+
*.bak
24+
java.frag

README.md

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,87 @@
1-
# webmethods-integrationserver-wxpassword
2-
Ensure non-default passwords
1+
# WxPassword
2+
3+
Initial functionality is to change the passwords of the built-in users
4+
(Administrator, Replicator, Developer). The primary use-case is deployment
5+
in a container.
6+
7+
## Usage
8+
9+
Installing the package is all that needs to be done. The service
10+
`wx.password.pub:nonDefaultPasswordsForStandardAccounts` is defined
11+
as a start-up service and therefore gets executed automatically.
12+
13+
### Specific passwords
14+
15+
In a typical production deployment, the desired passwords need to
16+
be provide as environment variables. The naming convention is
17+
`SAG_WXPASSWORD_SET_<USERNAME>`. So for the `Administrator` account
18+
the variable `SAG_WXPASSWORD_SET_Administrator` must be defined.
19+
20+
### Random passwords
21+
22+
If no password is defined a random one will be generated and saved in
23+
clear text in the working directory. For each user a separate file will
24+
be created and its name matches the user name.
25+
26+
**Intended only for
27+
non-production environments!**
28+
29+
### Working directory
30+
31+
The working directory needs to be provided as an environment variable
32+
(`SAG_WXPASSWORD_DIR`). If nothing is specified, the fall-back value
33+
is `$IS_HOME/config/WxPassword`. In both cases, the directory will
34+
be created, if it does not exist. If the creation fails, a
35+
`ServiceException` is thrown and now further activities performed.
36+
37+
### Disable execution
38+
39+
To disable the execution from the outside you need to create a semaphore
40+
file (name: `disable_WxPassword`) in the working directory. If this is
41+
found, WxPassword will effectively be completely disabled.
42+
43+
## Getting Started
44+
45+
You can use this package in multiple ways.
46+
47+
1. Simply make use of the existing functionality
48+
1. Use it as a source of inspiration for your own development
49+
1. Contribute to WxPassword by adding new functionality and/or fixing bugs
50+
51+
### Installing a Release
52+
53+
This is the suitable approach, if you either just want to use WxPassword or use it as a starting point for
54+
your own development.
55+
56+
* Download `WxPassword.zip` from the [latest release](https://github.com/SoftwareAG/webmethods-integrationserver-wxpassword/releases), place it into `$IS_HOME/replicate/inbound/`, and install via "Packages / Management / Install Inbound Releases"
57+
58+
### Installation from Source
59+
60+
- Prerequisite: You need "Local Service Development" installed (located in Designer preferences at "Software AG / Service Development / Local Service Development")
61+
- Get sources
62+
- Via Software AG Designer (no separate Git installation needed)
63+
- Open "Java" perspective
64+
- Click "Import projects"
65+
- Select "Git / Projects from Git"
66+
- Select "Clone URI"
67+
- Paste Git URI from green "Clone or download" button above
68+
- Adjust target directory to `<WORKSPACE>/WxPassword`
69+
- Confirm defaults on all further dialogues and finish the import
70+
- Via command line (requires local Git installation)
71+
- Go into Designer workspace (e.g. `/home/john/workspace105`)
72+
- Clone Git repository into new directory `git clone https://github.com/SoftwareAG/webmethods-integrationserver-wxpassword.git WxPassword`
73+
- Import as existing project into workspace
74+
- Activate package in Integration Server
75+
- If the "Service Development" perspective has not been active before you openend the "Java" perspective, you must quickly switch there and then directly back to "Java". This is needed to initialize the Local Service Development feature.
76+
- In the "Java" perspective right-click the project name and select "Move Project to IS Package"
77+
- Switch to the "Service Development" perspective and the WxPassword package should show up
78+
- Compile and frag package (required because for Java services neither the class files nor the frag files are versioned)
79+
- Open Command Promopt (`cmd.exe`) and go into `$IS_HOME/bin` directory
80+
- Execute the following commands
81+
```
82+
jcode makeall WxPassword
83+
jcode fragall WxPassword
84+
```
385
486
587
------------------------------

WxPassword/.classpath

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="code/source"/>
4+
<classpathentry kind="lib" path="code/jars"/>
5+
<classpathentry kind="lib" path="lib"/>
6+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
7+
<classpathentry kind="var" path="IS_CLIENT"/>
8+
<classpathentry kind="var" path="IS_SERVER"/>
9+
<classpathentry kind="var" path="IS_ENTTK"/>
10+
<classpathentry kind="var" path="IS_MAIL"/>
11+
<classpathentry kind="var" path="IS_G11N"/>
12+
<classpathentry kind="var" path="IS_ICU4J"/>
13+
<classpathentry kind="var" path="IS_WSDL4J"/>
14+
<classpathentry kind="var" path="IS_CORE"/>
15+
<classpathentry kind="var" path="IS_EDITOR"/>
16+
<classpathentry kind="var" path="IS_UIUTILS"/>
17+
<classpathentry kind="var" path="ECLIPSE_OSGI"/>
18+
<classpathentry kind="var" path="ECLIPSE_EQUINOX"/>
19+
<classpathentry kind="var" path="ECLIPSE_DRAW2D"/>
20+
<classpathentry kind="var" path="ECLIPSE_JFACE"/>
21+
<classpathentry kind="var" path="ECLIPSE_SWT"/>
22+
<classpathentry kind="var" path="ECLIPSE_CORECMD"/>
23+
<classpathentry kind="var" path="ECLIPSE_CORERUN"/>
24+
<classpathentry kind="var" path="ECLIPSE_UIWB"/>
25+
<classpathentry kind="var" path="ECLIPSE_PREF"/>
26+
<classpathentry kind="var" path="ECLIPSE_JOBS"/>
27+
<classpathentry kind="var" path="ECLIPSE_EQREG"/>
28+
<classpathentry kind="var" path="ECLIPSE_E4_UIWB"/>
29+
<classpathentry kind="var" path="ECLIPSE_E4_UIWB3"/>
30+
<classpathentry kind="var" path="ECLIPSE_E4_MWB"/>
31+
<classpathentry kind="var" path="ECLIPSE_OSGI_SVC"/>
32+
<classpathentry kind="var" path="ECLIPSE_E4_CORE"/>
33+
<classpathentry kind="output" path="code/classes"/>
34+
</classpath>

WxPassword/.project

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>WxPassword</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
<buildCommand>
14+
<name>com.softwareag.is.vcsintegration.ISPackageBuilder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
18+
</buildSpec>
19+
<natures>
20+
<nature>org.eclipse.jdt.core.javanature</nature>
21+
<nature>com.softwareag.is.vcsintegration.nature</nature>
22+
</natures>
23+
<filteredResources>
24+
<filter>
25+
<id>1623779121942</id>
26+
<name></name>
27+
<type>30</type>
28+
<matcher>
29+
<id>org.eclipse.core.resources.regexFilterMatcher</id>
30+
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
31+
</matcher>
32+
</filter>
33+
</filteredResources>
34+
</projectDescription>

WxPassword/code/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
classes
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.softwareag.wx.is.password;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.security.SecureRandom;
6+
7+
import com.wm.app.b2b.server.User;
8+
import com.wm.app.b2b.server.UserManager;
9+
import com.wm.util.Files;
10+
11+
/**
12+
* Set password for given user (executed only once)
13+
*/
14+
public class PasswordSetter {
15+
16+
/**
17+
* Prefix of environment variables for setting a specific password
18+
*/
19+
public static final String ENVVAR_PASSWORD_PREFIX = "SAG_WXPASSWORD_SET_";
20+
21+
/**
22+
* Name of semaphore file to indicate that password should not be updated. The
23+
* existence of this file disables any changes, regardless of whether the
24+
* passwords are specified as environment variables or should be created
25+
* randomly.
26+
*/
27+
public static final String SEMAPHOR_DISABLE = "disable_WxPassword";
28+
29+
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
30+
static SecureRandom rnd = new SecureRandom();
31+
32+
File workDir = null;
33+
String userName = null;
34+
String password = null;
35+
boolean isPasswordDefinedByEnvVar = true;
36+
37+
/**
38+
* Initialize password setter
39+
*
40+
* @param workDir Work directory
41+
* @param userName User name
42+
*/
43+
public PasswordSetter(File workDir, String userName) {
44+
this.workDir = workDir;
45+
this.userName = userName;
46+
password = getPassword();
47+
}
48+
49+
/**
50+
* Perform the password update, if needed
51+
*
52+
* @throws IOException
53+
*/
54+
public void execute() throws IOException {
55+
if (isActionNeeded()) {
56+
User user = UserManager.getUser(userName);
57+
String password = getPassword();
58+
59+
// New random password is written before it gets applied to avoid loosing it by
60+
// an IO issue
61+
if (!isPasswordDefinedByEnvVar) {
62+
Files.write(fileWithPlainTextPassword(), password.getBytes());
63+
}
64+
user.setPassword(password);
65+
// user.setPasswordUpdatedOn();
66+
}
67+
}
68+
69+
/**
70+
* Indicate whether the password needs to be updated. This is done by checking
71+
* the existence of a file with the name of the user in the workDir location
72+
*
73+
* @param userName Name of user
74+
* @return true
75+
*/
76+
private boolean isActionNeeded() {
77+
78+
// Password not defined by envVar and no file with plain-text password exists
79+
if (!fileWithPlainTextPassword().exists() && !isPasswordDefinedByEnvVar) {
80+
return true;
81+
82+
// Password defined by envVar
83+
} else if (isPasswordDefinedByEnvVar) {
84+
return true;
85+
}
86+
return false;
87+
}
88+
89+
/**
90+
* Attempt to retrieve password for user
91+
*
92+
* @param userName
93+
* @return
94+
* @throws IOException
95+
*/
96+
private String getPassword() {
97+
String password = System.getenv(ENVVAR_PASSWORD_PREFIX + userName);
98+
if (password == null) {
99+
isPasswordDefinedByEnvVar = false;
100+
password = randomString(30);
101+
}
102+
return password;
103+
}
104+
105+
/**
106+
* File for holding the randomly generated new password in clear text
107+
*
108+
* @return
109+
*/
110+
private File fileWithPlainTextPassword() {
111+
return new File(workDir, userName);
112+
}
113+
114+
/**
115+
* Generate random string (taken from
116+
* https://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string)
117+
*
118+
* @param len
119+
* @return
120+
*/
121+
private static String randomString(int len) {
122+
StringBuilder sb = new StringBuilder(len);
123+
for (int i = 0; i < len; i++)
124+
sb.append(AB.charAt(rnd.nextInt(AB.length())));
125+
return sb.toString();
126+
}
127+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.softwareag.wx.is.password;
2+
3+
import java.io.File;
4+
5+
import com.wm.app.b2b.server.ServerAPI;
6+
import com.wm.app.b2b.server.ServiceException;
7+
8+
/**
9+
* Represents the working directory of the WxPassword package
10+
* <p>
11+
* If the environment variable {@value #ENVVAR_DIR} is defined, its value will
12+
* be used. Otherwise a sub-directory called {@value #NAME} underneath the
13+
* server's configuration directory will be used. Either directory will be
14+
* created, if it does not exist.
15+
*/
16+
public class WorkDir {
17+
18+
/**
19+
* Environment variable to define custom directory for holding WxPassword files
20+
*/
21+
private static final String ENVVAR_DIR = "SAG_WXPASSWORD_DIR";
22+
23+
/**
24+
* Sub-directory underneath server's configuration directory that will be used,
25+
* if no environment variable {@value #ENVVAR_DIR }is defined
26+
*/
27+
private static final String NAME = "WxPassword";
28+
29+
private File file = null;
30+
31+
/**
32+
* Determine directory and create it, if needed
33+
*
34+
* @throws ServiceException if directory creation fails
35+
*/
36+
public WorkDir() throws ServiceException {
37+
determineDir();
38+
createIfNeeded();
39+
}
40+
41+
/**
42+
* Determine directory
43+
*/
44+
private void determineDir() {
45+
String dirFromEnvVar = System.getenv(ENVVAR_DIR);
46+
if (dirFromEnvVar != null) {
47+
file = new File(dirFromEnvVar);
48+
} else {
49+
file = new File(ServerAPI.getServerConfigDir(), NAME);
50+
}
51+
}
52+
53+
/**
54+
* If the working directory does not exist, it will be created
55+
*
56+
* @throws ServiceException if directory cannot be created
57+
*/
58+
private void createIfNeeded() throws ServiceException {
59+
System.out.println("Checking if directory '" + file.getAbsolutePath() + "' exists");
60+
if (!file.exists()) {
61+
System.out.println("Directory '" + file.getAbsolutePath() + "' not found, will be created");
62+
boolean successLogDirCreate = file.mkdir();
63+
if (!successLogDirCreate) {
64+
throw new ServiceException("Unable to create directory '" + file.getAbsolutePath() + "'");
65+
}
66+
}
67+
}
68+
69+
/**
70+
* Get effective working directory
71+
*
72+
* @return
73+
*/
74+
public File get() {
75+
return file;
76+
}
77+
}

0 commit comments

Comments
 (0)