Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
reg-app
Regapp
Commits
ea3e7fa2
Commit
ea3e7fa2
authored
Sep 19, 2019
by
michael.simon
Browse files
Update OpenStackRegisterWorkflow.java from Freiburg
parent
1ee8ec3d
Changes
1
Hide whitespace changes
Inline
Side-by-side
bwreg-service/src/main/java/edu/kit/scc/cloud/reg/OpenStackRegisterWorkflow.java
View file @
ea3e7fa2
package
edu.kit.scc.cloud.reg
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
ch.ethz.ssh2.Connection
;
import
ch.ethz.ssh2.Session
;
import
ch.ethz.ssh2.StreamGobbler
;
import
edu.kit.scc.webreg.audit.Auditor
;
import
edu.kit.scc.webreg.entity.RegistryEntity
;
import
edu.kit.scc.webreg.entity.ServiceEntity
;
import
edu.kit.scc.webreg.entity.UserEntity
;
import
edu.kit.scc.webreg.exc.RegisterException
;
import
edu.kit.scc.webreg.service.reg.Infotainment
;
import
edu.kit.scc.webreg.service.reg.InfotainmentCapable
;
import
edu.kit.scc.webreg.service.reg.InfotainmentTreeNode
;
import
edu.kit.scc.webreg.service.reg.RegisterUserWorkflow
;
import
edu.kit.scc.webreg.service.reg.SetPasswordCapable
;
import
edu.kit.scc.webreg.service.reg.ldap.PropertyReader
;
/**
* Workflow Class to register bwCloud OpenStack user
*
* @author Oleg Dulov
*/
public
class
OpenStackRegisterWorkflow
implements
RegisterUserWorkflow
,
InfotainmentCapable
,
SetPasswordCapable
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
OpenStackRegisterWorkflow
.
class
);
// OpenStack Connection variables
String
openstack_host
=
"os-all-one.bwcloud.scc.kit.edu"
;
String
openstack_user
=
"osweb"
;
String
openstack_pass
=
"test123"
;
String
openstack_path
=
"~/ManageOS.py"
;
String
defaultPass
=
"secretword"
;
String
openstack_port
=
"22"
;
@Override
public
void
registerUser
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
//logger.info("User: {}",user.getId());
logger
.
info
(
"User-EPPN {}"
,
user
.
getEppn
());
logger
.
debug
(
"try create new user"
);
// Create User
String
osUserId
=
this
.
execute
(
"add"
,
user
.
getEppn
(),
user
.
getEmail
(),
this
.
defaultPass
);
if
(
osUserId
!=
null
&&
!
osUserId
.
isEmpty
()){
// Put User to Registry
registry
.
getRegistryValues
().
put
(
"osId"
,
osUserId
);
logger
.
debug
(
"created user {}"
,
osUserId
);
}
else
{
logger
.
info
(
"Problem with user {}"
,
osUserId
);
throw
new
RegisterException
(
"Cannot register user under bwCloud"
);
}
}
@Override
public
void
deregisterUser
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
//logger.info("User: {}",user.getId());
logger
.
info
(
"User-EPPN {}"
,
user
.
getEppn
());
logger
.
debug
(
"try delete user: "
+
user
.
getEppn
());
// Delete User
String
osUserId
=
this
.
execute
(
"del"
,
user
.
getEppn
(),
"noemail"
,
this
.
defaultPass
);
logger
.
debug
(
"deleted user {}"
,
osUserId
);
}
@Override
public
void
reconciliation
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
}
@Override
public
Boolean
updateRegistry
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
return
false
;
}
@Override
public
Infotainment
getInfo
(
RegistryEntity
registry
,
UserEntity
user
,
ServiceEntity
service
)
throws
RegisterException
{
PropertyReader
prop
=
PropertyReader
.
newRegisterPropReader
(
service
);
if
(!
registry
.
getRegistryValues
().
containsKey
(
"osId"
))
throw
new
RegisterException
(
"Registration is incomplete (missing osId)"
);
String
userId
=
registry
.
getRegistryValues
().
get
(
"osId"
);
Infotainment
info
=
new
Infotainment
();
InfotainmentTreeNode
root
=
new
InfotainmentTreeNode
(
"root"
,
null
);
return
info
;
}
/**
* SetPasswordCapable methods
*/
@Override
public
void
setPassword
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
,
String
password
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
//logger.info("User: {}",user.getId());
logger
.
info
(
"User-EPPN {}"
,
user
.
getEppn
());
logger
.
debug
(
"try set Dienstpassword: "
+
user
.
getEppn
());
// Delete User
String
osUserId
=
this
.
execute
(
"upd"
,
user
.
getEppn
(),
"noemail"
,
password
);
logger
.
debug
(
"Dienstpassword set {}"
,
osUserId
);
}
@Override
public
void
deletePassword
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
//logger.info("User: {}",user.getId());
logger
.
info
(
"User-EPPN {}"
,
user
.
getEppn
());
logger
.
debug
(
"try delete Password: "
+
user
.
getEppn
());
// Delete User
String
osUserId
=
this
.
execute
(
"pswd"
,
user
.
getEppn
(),
"noemail"
,
this
.
defaultPass
);
logger
.
debug
(
"Dienstpassword is deleted {}"
,
osUserId
);
}
private
void
initWrapper
(
ServiceEntity
service
)
throws
RegisterException
{
PropertyReader
prop
=
PropertyReader
.
newRegisterPropReader
(
service
);
// OpenStack Keystone URL, admin credentials
if
(
prop
.
hasProp
(
"openstack_host"
)
){
this
.
openstack_host
=
prop
.
readPropOrNull
(
"openstack_host"
);
}
else
throw
new
RegisterException
(
"not configured openstack_host"
);
if
(
prop
.
hasProp
(
"openstack_user"
)
){
this
.
openstack_user
=
prop
.
readPropOrNull
(
"openstack_user"
);
}
else
throw
new
RegisterException
(
"not configured openstack_user"
);
if
(
prop
.
hasProp
(
"openstack_pass"
)
){
this
.
openstack_pass
=
prop
.
readPropOrNull
(
"openstack_pass"
);
}
else
throw
new
RegisterException
(
"not configured openstack_pass"
);
if
(
prop
.
hasProp
(
"openstack_path"
)
){
this
.
openstack_path
=
prop
.
readPropOrNull
(
"openstack_path"
);
}
else
throw
new
RegisterException
(
"not configured openstack_path"
);
if
(
prop
.
hasProp
(
"openstack_port"
)
){
this
.
openstack_port
=
prop
.
readPropOrNull
(
"openstack_port"
);
}
else
throw
new
RegisterException
(
"not configured openstack_port"
);
logger
.
debug
(
"OpenStack Credentials are initialized {}"
);
}
private
String
execute
(
String
method
,
String
user
,
String
email
,
String
password
)
throws
RegisterException
{
String
command
=
openstack_path
+
" --method "
+
method
+
" --user "
+
user
+
" --passwd "
+
password
+
" --email "
+
email
+
"\n"
;
String
line
=
""
;
try
{
/* Create a connection instance */
Connection
conn
=
new
Connection
(
this
.
openstack_host
,
Integer
.
parseInt
(
this
.
openstack_port
));
/* Now connect */
conn
.
connect
();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean
isAuthenticated
=
conn
.
authenticateWithPassword
(
this
.
openstack_user
,
this
.
openstack_pass
);
if
(
isAuthenticated
==
false
){
// throw new IOException("Authentication failed.");
throw
new
RegisterException
(
"Authentication failed."
);
}
/* Create a session */
Session
sess
=
conn
.
openSession
();
sess
.
execCommand
(
command
);
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream
stdout
=
new
StreamGobbler
(
sess
.
getStdout
());
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
stdout
));
line
=
br
.
readLine
();
br
.
close
();
/* Close this session */
sess
.
close
();
/* Close the connection */
conn
.
close
();
}
catch
(
IOException
e
)
{
logger
.
error
(
"IOExcetion happened in SSH Session"
,
e
);
throw
new
RegisterException
(
e
);
}
return
line
;
}
}
package
edu.kit.scc.cloud.reg
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.util.Base64
;
import
java.security.SecureRandom
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
ch.ethz.ssh2.Connection
;
import
ch.ethz.ssh2.Session
;
import
ch.ethz.ssh2.StreamGobbler
;
import
edu.kit.scc.webreg.audit.Auditor
;
import
edu.kit.scc.webreg.entity.RegistryEntity
;
import
edu.kit.scc.webreg.entity.ServiceEntity
;
import
edu.kit.scc.webreg.entity.UserEntity
;
import
edu.kit.scc.webreg.exc.RegisterException
;
import
edu.kit.scc.webreg.service.reg.Infotainment
;
import
edu.kit.scc.webreg.service.reg.InfotainmentCapable
;
import
edu.kit.scc.webreg.service.reg.InfotainmentTreeNode
;
import
edu.kit.scc.webreg.service.reg.RegisterUserWorkflow
;
import
edu.kit.scc.webreg.service.reg.SetPasswordCapable
;
import
edu.kit.scc.webreg.service.reg.ldap.PropertyReader
;
/**
* Workflow Class to register OpenStack cloud users
*
* @author Oleg Dulov
*/
public
class
OpenStackRegisterWorkflow
implements
RegisterUserWorkflow
,
InfotainmentCapable
,
SetPasswordCapable
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
OpenStackRegisterWorkflow
.
class
);
// generate ramdom starting PW
private
static
SecureRandom
random
=
new
SecureRandom
();
// OpenStack Connection variables
String
openstack_host
=
"bw-cloud.org"
;
String
openstack_user
=
"osweb"
;
String
openstack_pass
=
"[REDACTED]"
;
String
openstack_path
=
"/var/lib/manageos/manageos.py"
;
String
openstack_port
=
"22"
;
String
openstack_sudo
=
""
;
// Dictionaries for password generator
private
static
final
String
ALPHA_CAPS
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
private
static
final
String
ALPHA
=
"abcdefghijklmnopqrstuvwxyz"
;
private
static
final
String
NUMERIC
=
"0123456789"
;
private
static
final
String
SPECIAL_CHARS
=
"!@#$%^&*_=+-/"
;
//Method will generate random string based on the parameters
public
static
String
generatePassword
(
int
len
,
String
dic
)
{
String
passwd
=
""
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
index
=
random
.
nextInt
(
dic
.
length
());
passwd
+=
dic
.
charAt
(
index
);
}
return
passwd
;
}
@Override
public
void
registerUser
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
// create random password
String
password
=
generatePassword
(
32
,
ALPHA
+
ALPHA_CAPS
+
NUMERIC
+
SPECIAL_CHARS
);
// encode PW
byte
[]
encodedPassword
=
Base64
.
getEncoder
().
encode
(
password
.
getBytes
());
password
=
new
String
(
encodedPassword
);
// read and encode entitlements
// ADD EOS to string != NULL
String
entitlementStr
=
user
.
getAttributeStore
().
get
(
"urn:oid:1.3.6.1.4.1.5923.1.1.1.7"
)
+
";EOS"
;
logger
.
debug
(
"User {} has following entitlements: {}"
,
user
.
getEppn
(),
entitlementStr
);
byte
[]
encodedEntitlements
=
Base64
.
getEncoder
().
encode
(
entitlementStr
.
getBytes
());
String
entitlement
=
new
String
(
encodedEntitlements
);
logger
.
debug
(
"Trying to create new user {}"
,
user
.
getEppn
());
// Create user
String
osUserId
=
this
.
execute
(
"add"
,
user
.
getEppn
(),
user
.
getEmail
(),
password
,
entitlement
);
if
(
osUserId
!=
null
&&
!
osUserId
.
isEmpty
()){
// Register user
registry
.
getRegistryValues
().
put
(
"osId"
,
osUserId
);
logger
.
debug
(
"created user {}"
,
osUserId
);
}
else
{
logger
.
info
(
"problem with user {} (EPPN {})"
,
osUserId
,
user
.
getEppn
());
throw
new
RegisterException
(
"Cannot register user"
+
user
.
getEppn
()
+
" with service "
+
service
.
getName
());
}
}
@Override
public
void
deregisterUser
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack Connection parameters
this
.
initWrapper
(
service
);
logger
.
debug
(
"Trying to delete user {}"
,
user
.
getEppn
());
// Delete User
String
osUserId
=
this
.
execute
(
"del"
,
user
.
getEppn
(),
null
,
null
,
null
);
logger
.
debug
(
"deleted user {}"
,
osUserId
);
}
@Override
public
void
reconciliation
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
}
@Override
public
Boolean
updateRegistry
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
return
false
;
}
@Override
public
Infotainment
getInfo
(
RegistryEntity
registry
,
UserEntity
user
,
ServiceEntity
service
)
throws
RegisterException
{
PropertyReader
prop
=
PropertyReader
.
newRegisterPropReader
(
service
);
if
(!
registry
.
getRegistryValues
().
containsKey
(
"osId"
))
throw
new
RegisterException
(
"Registration is incomplete (missing osId)"
);
String
userId
=
registry
.
getRegistryValues
().
get
(
"osId"
);
Infotainment
info
=
new
Infotainment
();
InfotainmentTreeNode
root
=
new
InfotainmentTreeNode
(
"root"
,
null
);
return
info
;
}
/**
* SetPasswordCapable methods
*/
@Override
public
void
setPassword
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
,
String
password
)
throws
RegisterException
{
PropertyReader
prop
=
PropertyReader
.
newRegisterPropReader
(
service
);
// Initialize OpenStack connection parameters
this
.
initWrapper
(
service
);
logger
.
debug
(
"Trying to set service password for user {}"
,
user
.
getEppn
());
String
passwordRegex
;
if
(
prop
.
hasProp
(
"password_regex"
))
passwordRegex
=
prop
.
readPropOrNull
(
"password_regex"
);
else
passwordRegex
=
".{6,}"
;
String
passwordRegexMessage
;
if
(
prop
.
hasProp
(
"password_regex_message"
))
passwordRegexMessage
=
prop
.
readPropOrNull
(
"password_regex_message"
);
else
passwordRegexMessage
=
"Das Passwort ist nicht komplex genug"
;
if
(!
password
.
matches
(
passwordRegex
))
throw
new
RegisterException
(
passwordRegexMessage
);
// encode PW
byte
[]
encodedPassword
=
Base64
.
getEncoder
().
encode
(
password
.
getBytes
());
password
=
new
String
(
encodedPassword
);
// Set password
String
osUserId
=
this
.
execute
(
"upd"
,
user
.
getEppn
(),
null
,
password
,
null
);
logger
.
debug
(
"Service password set {}"
,
osUserId
);
}
@Override
public
void
deletePassword
(
UserEntity
user
,
ServiceEntity
service
,
RegistryEntity
registry
,
Auditor
auditor
)
throws
RegisterException
{
// Initialize OpenStack connection parameters
this
.
initWrapper
(
service
);
logger
.
debug
(
"Trying to delete service password for user {}"
,
user
.
getEppn
());
// Delete password
String
osUserId
=
this
.
execute
(
"pswd"
,
user
.
getEppn
(),
null
,
null
,
null
);
logger
.
debug
(
"Service password is deleted {}"
,
osUserId
);
}
private
void
initWrapper
(
ServiceEntity
service
)
throws
RegisterException
{
PropertyReader
prop
=
PropertyReader
.
newRegisterPropReader
(
service
);
// OpenStack Keystone URL, admin credentials
if
(
prop
.
hasProp
(
"openstack_host"
)
){
this
.
openstack_host
=
prop
.
readPropOrNull
(
"openstack_host"
);
}
else
throw
new
RegisterException
(
"not configured openstack_host"
);
if
(
prop
.
hasProp
(
"openstack_user"
)
){
this
.
openstack_user
=
prop
.
readPropOrNull
(
"openstack_user"
);
}
else
throw
new
RegisterException
(
"not configured openstack_user"
);
if
(
prop
.
hasProp
(
"openstack_pass"
)
){
this
.
openstack_pass
=
prop
.
readPropOrNull
(
"openstack_pass"
);
}
else
throw
new
RegisterException
(
"not configured openstack_pass"
);
if
(
prop
.
hasProp
(
"openstack_path"
)
){
this
.
openstack_path
=
prop
.
readPropOrNull
(
"openstack_path"
);
}
else
throw
new
RegisterException
(
"not configured openstack_path"
);
if
(
prop
.
hasProp
(
"openstack_port"
)
){
this
.
openstack_port
=
prop
.
readPropOrNull
(
"openstack_port"
);
}
else
throw
new
RegisterException
(
"not configured openstack_port"
);
if
(
prop
.
hasProp
(
"openstack_sudo"
)
){
if
(
prop
.
readPropOrNull
(
"openstack_sudo"
).
equals
(
"true"
))
{
this
.
openstack_sudo
=
"sudo "
;
}
}
logger
.
debug
(
"OpenStack credentials are initialized {}"
);
}
private
String
fmt_arg
(
String
pref
,
String
val
)
{
return
val
==
null
?
""
:
" --"
+
pref
+
" "
+
val
;
}
private
String
execute
(
String
method
,
String
user
,
String
email
,
String
password
,
String
entitlement
)
throws
RegisterException
{
String
command
=
openstack_sudo
+
openstack_path
+
this
.
fmt_arg
(
"method"
,
method
)
+
this
.
fmt_arg
(
"user"
,
user
)
+
this
.
fmt_arg
(
"passwd"
,
password
)
+
this
.
fmt_arg
(
"email"
,
email
)
+
this
.
fmt_arg
(
"entitlement"
,
entitlement
)
+
"\n"
;
String
line
=
""
;
try
{
/* Create a connection instance */
Connection
conn
=
new
Connection
(
this
.
openstack_host
,
Integer
.
parseInt
(
this
.
openstack_port
));
/* Now connect */
conn
.
connect
();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean
isAuthenticated
=
conn
.
authenticateWithPassword
(
this
.
openstack_user
,
this
.
openstack_pass
);
if
(
isAuthenticated
==
false
){
//throw new IOException("Authentication failed.");
throw
new
RegisterException
(
"Authentication failed."
);
}
/* Create a session */
Session
sess
=
conn
.
openSession
();
sess
.
execCommand
(
command
);
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream
stdout
=
new
StreamGobbler
(
sess
.
getStdout
());
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
stdout
));
line
=
br
.
readLine
();
br
.
close
();
/* Close this session */
sess
.
close
();
/* Close the connection */
conn
.
close
();
}
catch
(
IOException
e
)
{
logger
.
error
(
"IOExcetion happened in SSH Session"
,
e
);
throw
new
RegisterException
(
e
);
}
return
line
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment