WSO25.3 Custom User store manager - wso2-identity-server
I am on WSO2 5.3
My usecase is to invoke the api to authenticate the user and return isAuthenticated as true/false based on credentials provided.
I have written a custom user store ( as MyAPIUserStoreManager which extends JDBCUserStoreManager) and placed into the droppins folder, and i can see this in drop down as well after restarting the server,
Then I also configured the travelocity app as a service provider as i want to login to this app by using credentials which will be validated using api(custom user store i.e MyAPIUserStoreManager).
This works fine in wso25.2 version :
but on WSO25.3 my problem is that clicking on login button after providing the username/pwd, in log it says the following :
TID: [-1234] [] [2017-01-23 16:05:10,673] ERROR {org.wso2.carbon.user.core.common.AbstractUserStoreManager} - java.lang.ClassCastException: org.wso2.carbon.utils.Secret cannot be cast to java.lang.String
TID: [-1234] [] [2017-01-23 16:05:10,676] DEBUG {org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator} - User authentication failed due to invalid credentials
It is not going through my custom user store i.e MyAPIUserStoreManager somehow.
Am I missing any config ? I have followed the followed link :
https://docs.wso2.com/display/ADMIN44x/Writing+a+Custom+User+Store+Manager#WritingaCustomUserStoreManager-AbstractUserStoreManagerandimplementations
Here is the code for custom user store manager:
public class MyAPIUserStoreManager extends JDBCUserStoreManager{
private static Log log = LogFactory.getLog(MyAPIUserStoreManager.class);
Map<String,String> userProperties;
public MyAPIUserStoreManager() {
}
public MyAPIUserStoreManager(RealmConfiguration realmConfig, Map<String, Object> properties,
ClaimManager claimManager, ProfileConfigurationManager profileManager, UserRealm realm,
Integer tenantId) throws UserStoreException {
super(realmConfig, properties, claimManager, profileManager, realm, tenantId);
}
#Override
public boolean doAuthenticate(String userName, Object credential) throws UserStoreException {
boolean isAuthenticated = false;
if (userName == null || credential == null) {
return false;
}
userName = userName.trim();
String password = (String) credential;
password = password.trim();
if (userName.equals("") || password.equals("")) {
return false;
}
Map<String, String> properties = initUserProperties(userName, password);
if (userName.equals(properties.get("loginName"))) {
isAuthenticated = true;
}
return isAuthenticated;
}
#Override
public Map<String, String> getUserPropertyValues(String username, String[] propertyNames,
String profileName) throws UserStoreException {
Map<String,String> map = new HashMap<>();
if (userProperties == null) {
log.warn("User property values not initialized for " + username + ", returning null");
return null;
}
for (String propertyName : propertyNames) {
if ("accountId".equals(propertyName)) {
map.put(propertyName, userProperties.get("accountId"));
} else if ("userStatusID".equals(propertyName)) {
map.put(propertyName, userProperties.get("userStatusID"));
} else if ("loginName".equals(propertyName)) {
map.put(propertyName, userProperties.get("loginName"));
} else if ("firstName".equals(propertyName)) {
map.put(propertyName, userProperties.get("firstName"));
} else if ("lastName".equals(propertyName)) {
map.put(propertyName, userProperties.get("lastName"));
} else if ("email".equals(propertyName)) {
map.put(propertyName, userProperties.get("email"));
} else if ("phoneNumber".equals(propertyName)) {
map.put(propertyName, userProperties.get("phoneNumber"));
} else if ("role".equals(propertyName)) {
map.put(propertyName, userProperties.get("role"));
} else if ("roleId".equals(propertyName)) {
map.put(propertyName, userProperties.get("roleId"));
} else if ("secretQuestionId".equals(propertyName)) {
map.put(propertyName, userProperties.get("secretQuestionId"));
} else if ("secretAnswer".equals(propertyName)) {
map.put(propertyName, userProperties.get("secretAnswer"));
} else if ("dateLastUpdated".equals(propertyName)) {
map.put(propertyName, userProperties.get("dateLastUpdated"));
} else if ("lastUpdatedByUserId".equals(propertyName)) {
map.put(propertyName, userProperties.get("lastUpdatedByUserId"));
} else if ("password".equals(propertyName)) {
map.put(propertyName, userProperties.get("password"));
} else if ("existingsuperuser".equals(propertyName)) {
map.put(propertyName, userProperties.get("existingsuperuser"));
} else if ("updateMeWithAnnouncements".equals(propertyName)) {
map.put(propertyName, userProperties.get("updateMeWithAnnouncements"));
} else if ("blockAccess".equals(propertyName)) {
map.put(propertyName, userProperties.get("blockAccess"));
} else if ("allowEndUserOutboundCallerId".equals(propertyName)) {
map.put(propertyName, userProperties.get("allowEndUserOutboundCallerId"));
} else if ("allowCallBlocking".equals(propertyName)) {
map.put(propertyName, userProperties.get("allowCallBlocking"));
} else if ("passExpiry".equals(propertyName)) {
map.put(propertyName, userProperties.get("passExpiry"));
} else if ("passhash".equals(propertyName)) {
map.put(propertyName, userProperties.get("passhash"));
} else if ("salt".equals(propertyName)) {
map.put(propertyName, userProperties.get("salt"));
} else if ("passHistory".equals(propertyName)) {
map.put(propertyName, userProperties.get("passHistory"));
} else if ("passAlgo".equals(propertyName)) {
map.put(propertyName, userProperties.get("passAlgo"));
} else if ("sendEmail".equals(propertyName)) {
map.put(propertyName, userProperties.get("sendEmail"));
} else if ("contactnumbers".equals(propertyName)) {
map.put(propertyName, userProperties.get("contactnumbers"));
}
}
return map;
}
#Override
public org.wso2.carbon.user.api.Properties getDefaultUserStoreProperties() {
return MyAPIUserConstants.getDefaultUserStoreProperties();
}
#Override
public String[] getAllProfileNames() throws UserStoreException {
return new String[]{"default"};
}
#Override
public String[] getProfileNames(String userName) throws UserStoreException {
return new String[]{"default"};
}
public boolean isMultipleProfilesAllowed() {
return false;
}
public boolean isReadOnly() throws UserStoreException {
return true;
}
private Map<String,String> initUserProperties(String userName, String password) throws UserStoreException {
userProperties = new HashMap<>();
String url = realmConfig.getUserStoreProperty(MyAPIUserConstants.LOGIN_API);
if (url == null) {
throw new UserStoreException("Authentication API not defined");
}
String params = URLEncoder.encode(userName + "," + password);
url = String.format(url, params);
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
log.debug("Lets see headers");
request.addHeader("Authorization", "Basic ffgggggddddd"); //hard coding as of now
HttpResponse response;
String xmlResponse = null;
try {
log.debug("Authorization header is "+request.getFirstHeader("Authorization"));
response = client.execute(request);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity resEntity = response.getEntity();
xmlResponse = EntityUtils.toString(resEntity);
xmlResponse = MyApiUserStoreUtils.trim(xmlResponse);
}
} catch (IOException e) {
e.printStackTrace();
}
if (StringUtils.isNotEmpty(xmlResponse)) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
InputSource is;
try {
builder = factory.newDocumentBuilder();
is = new InputSource(new StringReader(xmlResponse));
Document doc = builder.parse(is);
userProperties.put("accountId", doc.getElementsByTagName("accountId").item(0).getTextContent());
userProperties.put("userStatusID", doc.getElementsByTagName("userStatusID").item(0).getTextContent());
userProperties.put("loginName", doc.getElementsByTagName("loginName").item(0).getTextContent());
userProperties.put("firstName", doc.getElementsByTagName("firstName").item(0).getTextContent());
userProperties.put("lastName", doc.getElementsByTagName("lastName").item(0).getTextContent());
userProperties.put("email", doc.getElementsByTagName("email").item(0).getTextContent());
userProperties.put("phoneNumber", doc.getElementsByTagName("phoneNumber").item(0).getTextContent());
userProperties.put("role", doc.getElementsByTagName("role").item(0).getTextContent());
userProperties.put("roleId", doc.getElementsByTagName("roleId").item(0).getTextContent());
userProperties.put("secretQuestionId", doc.getElementsByTagName("secretQuestionId").item(0).getTextContent());
userProperties.put("secretAnswer", doc.getElementsByTagName("secretAnswer").item(0).getTextContent());
userProperties.put("dateLastUpdated", doc.getElementsByTagName("dateLastUpdated").item(0).getTextContent());
userProperties.put("lastUpdatedByUserId", doc.getElementsByTagName("lastUpdatedByUserId").item(0).getTextContent());
userProperties.put("password", doc.getElementsByTagName("password").item(0).getTextContent());
userProperties.put("existingsuperuser", doc.getElementsByTagName("existingsuperuser").item(0).getTextContent());
userProperties.put("updateMeWithAnnouncements", doc.getElementsByTagName("updateMeWithAnnouncements").item(0).getTextContent());
userProperties.put("blockAccess", doc.getElementsByTagName("blockAccess").item(0).getTextContent());
userProperties.put("allowEndUserOutboundCallerId", doc.getElementsByTagName("allowEndUserOutboundCallerId").item(0).getTextContent());
userProperties.put("allowCallBlocking", doc.getElementsByTagName("allowCallBlocking").item(0).getTextContent());
userProperties.put("passExpiry", doc.getElementsByTagName("passExpiry").item(0).getTextContent());
userProperties.put("passhash", doc.getElementsByTagName("passhash").item(0).getTextContent());
userProperties.put("salt", doc.getElementsByTagName("salt").item(0).getTextContent());
userProperties.put("passHistory", doc.getElementsByTagName("passHistory").item(0).getTextContent());
userProperties.put("passAlgo", doc.getElementsByTagName("passAlgo").item(0).getTextContent());
userProperties.put("sendEmail", doc.getElementsByTagName("sendEmail").item(0).getTextContent());
String contactNumbers = "";
for (int i = 0 ; i < doc.getElementsByTagName("contactnumbers").getLength(); i++) {
if (StringUtils.isNotEmpty(contactNumbers)) {
contactNumbers += ",";
}
contactNumbers += doc.getElementsByTagName("contactnumbers").item(i).getTextContent();
}
userProperties.put("contactnumbers", contactNumbers);
} catch (ParserConfigurationException e) {
throw new UserStoreException("Error while initializing document builder", e);
} catch (IOException e) {
throw new UserStoreException("Error while parsing Input source", e);
} catch (org.xml.sax.SAXException e) {
throw new UserStoreException("Error while parsing Input source", e);
}
}
return userProperties;
}
protected Connection getDBConnection() throws SQLException, UserStoreException {
return null;
}
protected boolean isExistingJDBCRole(RoleContext context) throws UserStoreException {
return false;
}
public boolean doCheckExistingUser(String userName) throws UserStoreException {
if (userProperties != null) {
return true;
} else {
return false;
}
}
public String[] getUserListOfJDBCRole(RoleContext ctx, String filter) throws UserStoreException {
String [] user = null;
if (userProperties != null) {
user = new String[]{userProperties.get("loginName")};
}
return user;
}
public RoleDTO[] getRoleNamesWithDomain(boolean noHybridRoles) throws UserStoreException {
return null;
}
public String[] doGetExternalRoleListOfUser(String userName, String filter) throws UserStoreException {
return null;
}
#Override
protected String[] doGetSharedRoleListOfUser(String userName,
String tenantDomain, String filter) throws UserStoreException {
return null;
}
public String[] getRoleListOfUser(String userName) throws UserStoreException {
return new String[]{"Internal/everyone"};
}
public boolean isRecurssive() {
return false;
}
}
Please suggest.
Here is the log after i click on login button:
TID: [-1234] [] [2017-01-24 16:35:30,315] DEBUG {org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils} - Authentication Context is null
TID: [-1234] [] [2017-01-24 16:35:30,318] DEBUG {org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler} - In authentication flow
TID: [-1234] [] [2017-01-24 16:35:30,318] DEBUG {org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler} - Executing the Step Based Authentication...
TID: [-1234] [] [2017-01-24 16:35:30,318] DEBUG {org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.DefaultStepBasedSequenceHandler} - Starting Step: 1
TID: [-1234] [] [2017-01-24 16:35:30,319] DEBUG {org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils} - Finding already authenticated IdPs of the Step
TID: [-1234] [] [2017-01-24 16:35:30,320] DEBUG {org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler} - Receive a response from the external party
TID: [-1234] [] [2017-01-24 16:35:30,320] DEBUG {org.wso2.carbon.identity.application.authentication.framework.handler.step.impl.DefaultStepHandler} - BasicAuthenticator can handle the request.
TID: [-1234] [] [2017-01-24 16:35:30,325] ERROR {org.wso2.carbon.user.core.common.AbstractUserStoreManager} - java.lang.ClassCastException: org.wso2.carbon.utils.Secret cannot be cast to java.lang.String
TID: [-1234] [] [2017-01-24 16:35:30,327] DEBUG {org.wso2.carbon.user.core.common.AbstractUserStoreManager} - Authentication failure. Wrong username or password is provided.
TID: [-1234] [] [2017-01-24 16:35:30,328] DEBUG {org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator} - User authentication failed due to invalid credentials
You can add debug logs as follows in /repository/conf/log4j.properties file
log4j.logger.org.wso2.carbon.user.core=DEBUG
log4j.logger.org.wso2.carbon.identity.application.authenticator.basicauth.BasicAuthenticator=DEBUG
Attach the wso2carbon.log file.
Better if you can attach your custom as well.
I think you can write a custom authenticator for your use-case.
Thanks
Isura
Related
unable to login as secondary custom user manager in wso2 IS 5.9
in WSO2 IS 5.9, a)i created a CustomeruserStoreManager and placed in drop-ins and along with mysql driver i lib lib folder, b)I cud see the users from my custom usertable, created a internal and gave all permissions and assigned the 2 users test.com/dinuka and test.com.malinda to new role created. c)In the login page i can login as admin/admin but unable to login as test.com/dinuka-dinuka, I get the error as [2020-02-18 11:03:36,781] [cf46aae7-eb2b-4eeb-9683-e7adbbba5c1f] ERROR {org.wso2.carbon.core.services.authentication.AuthenticationAdmin} - System error while Authenticating/Authorizing User : Error when handling event : PRE_AUTHENTICATION I have disabled the claims as well,, public class CustomUserStoreConstants { //Properties for Read Active Directory User Store Manager public static final ArrayList<Property> CUSTOM_UM_MANDATORY_PROPERTIES = new ArrayList<Property>(); public static final ArrayList<Property> CUSTOM_UM_OPTIONAL_PROPERTIES = new ArrayList<Property>(); public static final ArrayList<Property> CUSTOM_UM_ADVANCED_PROPERTIES = new ArrayList<Property>(); static { setMandatoryProperty(JDBCRealmConstants.DRIVER_NAME, "Driver Name", "", "Full qualified driver name"); setMandatoryProperty(JDBCRealmConstants.URL,"Connection URL", "", "URL of the user store database"); setMandatoryProperty(JDBCRealmConstants.USER_NAME, "User Name","", "Username for the database"); setMandatoryProperty(JDBCRealmConstants.PASSWORD, "Password","", "Password for the database"); setProperty(UserStoreConfigConstants.disabled,"Disabled", "false", UserStoreConfigConstants.disabledDescription); setProperty("ReadOnly","Read Only", "true", "Indicates whether the user store of this realm operates in the user read only mode or not"); setProperty(UserStoreConfigConstants.SCIMEnabled,"SCIM Enabled", "false", UserStoreConfigConstants.SCIMEnabledDescription); //Advanced Properties (No descriptions added for each property) setAdvancedProperty("SelectUserSQL","Select User SQL", "SELECT * FROM CUSTOMER_DATA WHERE CUSTOMER_NAME=?", ""); setAdvancedProperty("UserFilterSQL","User Filter SQL", "SELECT CUSTOMER_NAME FROM CUSTOMER_DATA WHERE CUSTOMER_NAME LIKE ? ORDER BY CUSTOMER_ID", ""); setAdvancedProperty("ClaimOperationsSupported","Claim Operations Supported","false",""); } private static void setProperty(String name, String displayName, String value, String description) { Property property = new Property(name, value, displayName + "#" +description, null); CUSTOM_UM_OPTIONAL_PROPERTIES.add(property); } private static void setMandatoryProperty(String name, String displayName, String value, String description) { Property property = new Property(name, value, displayName + "#" +description, null); CUSTOM_UM_MANDATORY_PROPERTIES.add(property); } private static void setAdvancedProperty(String name, String displayName, String value, String description) { Property property = new Property(name, value, displayName + "#" +description, null); CUSTOM_UM_ADVANCED_PROPERTIES.add(property); } } public class CustomUserStoreManager extends JDBCUserStoreManager { private static Log log = LogFactory.getLog(CustomUserStoreManager.class); public CustomUserStoreManager() { } public CustomUserStoreManager(org.wso2.carbon.user.api.RealmConfiguration realmConfig, Map<String, Object> properties, ClaimManager claimManager, ProfileConfigurationManager profileManager, UserRealm realm, Integer tenantId) throws UserStoreException { super(realmConfig, properties, claimManager, profileManager, realm, tenantId, false); } #Override public boolean doAuthenticate(String userName, Object credential) throws UserStoreException { System.out.println("TRYING TO LOGIN HERE "); if (CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME.equals(userName)) { log.error("Anonymous user trying to login"); return false; } Connection dbConnection = null; ResultSet rs = null; PreparedStatement prepStmt = null; String sqlstmt = null; String password = (String) credential; boolean isAuthed = false; try { dbConnection = getDBConnection(); dbConnection.setAutoCommit(false); //paring the SELECT_USER_SQL from user_mgt.xml sqlstmt = realmConfig.getUserStoreProperty(JDBCRealmConstants.SELECT_USER); if (log.isDebugEnabled()) { log.debug(sqlstmt); } prepStmt = dbConnection.prepareStatement(sqlstmt); prepStmt.setString(1, userName); rs = prepStmt.executeQuery(); if (rs.next()) { String storedPassword = rs.getString(2); if ((storedPassword != null) && (storedPassword.trim().equals(password))) { isAuthed = true; } } } catch (SQLException e) { throw new UserStoreException("Authentication Failure. Using sql :" + sqlstmt); } finally { DatabaseUtil.closeAllConnections(dbConnection, rs, prepStmt); } if (log.isDebugEnabled()) { log.debug("User " + userName + " login attempt. Login success :: " + isAuthed); } return isAuthed; } #Override public Date getPasswordExpirationTime(String userName) throws UserStoreException { return null; } protected boolean isValueExisting(String sqlStmt, Connection dbConnection, Object... params) throws UserStoreException { PreparedStatement prepStmt = null; ResultSet rs = null; boolean isExisting = false; boolean doClose = false; try { if (dbConnection == null) { dbConnection = getDBConnection(); doClose = true; //because we created it } if (DatabaseUtil.getStringValuesFromDatabase(dbConnection, sqlStmt, params).length > 0) { isExisting = true; } return isExisting; } catch (SQLException e) { log.error(e.getMessage(), e); log.error("Using sql : " + sqlStmt); throw new UserStoreException(e.getMessage(), e); } finally { if (doClose) { DatabaseUtil.closeAllConnections(dbConnection, rs, prepStmt); } } } public String[] getUserListFromProperties(String property, String value, String profileName) throws UserStoreException { return new String[0]; } /*#Override public Map<String, String> doGetUserClaimValues(String userName, String[] claims, String domainName) throws UserStoreException { return new HashMap<String, String>(); }*/ /*#Override public String doGetUserClaimValue(String userName, String claim, String profileName) throws UserStoreException { return null; }*/ #Override public boolean isReadOnly() throws UserStoreException { return true; } #Override public void doAddUser(String userName, Object credential, String[] roleList, Map<String, String> claims, String profileName, boolean requirePasswordChange) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } public void doAddRole(String roleName, String[] userList, org.wso2.carbon.user.api.Permission[] permissions) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doDeleteRole(String roleName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doDeleteUser(String userName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public boolean isBulkImportSupported() { return false; } #Override public void doUpdateRoleName(String roleName, String newRoleName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doUpdateUserListOfRole(String roleName, String[] deletedUsers, String[] newUsers) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doUpdateRoleListOfUser(String userName, String[] deletedRoles, String[] newRoles) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doSetUserClaimValue(String userName, String claimURI, String claimValue, String profileName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doSetUserClaimValues(String userName, Map<String, String> claims, String profileName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doDeleteUserClaimValue(String userName, String claimURI, String profileName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doDeleteUserClaimValues(String userName, String[] claims, String profileName) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doUpdateCredential(String userName, Object newCredential, Object oldCredential) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } #Override public void doUpdateCredentialByAdmin(String userName, Object newCredential) throws UserStoreException { throw new UserStoreException( "User store is operating in read only mode. Cannot write into the user store."); } public String[] getExternalRoleListOfUser(String userName) throws UserStoreException { /*informix user store manager is supposed to be read only and users in the custom user store users in the custom user store are only assigned to internal roles. Therefore this method returns an empty string. */ return new String[0]; } #Override public String[] doGetRoleNames(String filter, int maxItemLimit) throws UserStoreException { return new String[0]; } #Override public boolean doCheckExistingRole(String roleName) throws UserStoreException { return false; } #Override public boolean doCheckExistingUser(String userName) throws UserStoreException { return true; } #Override public org.wso2.carbon.user.api.Properties getDefaultUserStoreProperties(){ Properties properties = new Properties(); properties.setMandatoryProperties(CustomUserStoreConstants.CUSTOM_UM_MANDATORY_PROPERTIES.toArray (new Property[CustomUserStoreConstants.CUSTOM_UM_MANDATORY_PROPERTIES.size()])); properties.setOptionalProperties(CustomUserStoreConstants.CUSTOM_UM_OPTIONAL_PROPERTIES.toArray (new Property[CustomUserStoreConstants.CUSTOM_UM_OPTIONAL_PROPERTIES.size()])); properties.setAdvancedProperties(CustomUserStoreConstants.CUSTOM_UM_ADVANCED_PROPERTIES.toArray (new Property[CustomUserStoreConstants.CUSTOM_UM_ADVANCED_PROPERTIES.size()])); return properties; } } #Component( name = "com.wso2.carbon.custom.user.store.manager", immediate = true ) public class CustomUserStoreMgtDSComponent { private static Log log = LogFactory.getLog(CustomUserStoreMgtDSComponent.class); private static RealmService realmService; #Activate protected void activate(ComponentContext ctxt) { try { CustomUserStoreManager customUserStoreManager = new CustomUserStoreManager(); ctxt.getBundleContext().registerService(UserStoreManager.class.getName(), customUserStoreManager, null); log.info("CustomUserStoreManager bundle activated successfully.."); } catch (Throwable storeError) { log.error("ERROR when activating Custom User Store", storeError); } } #Deactivate protected void deactivate(ComponentContext ctxt) { System.out.println(" !!! DEACTIVATE COMP !!!"); if (log.isDebugEnabled()) { log.debug("Custom User Store Manager is deactivated "); } } #Reference( name = "RealmService", service = org.wso2.carbon.user.core.service.RealmService.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, unbind = "unsetRealmService") protected void setRealmService(RealmService realmService) { realmService = realmService; } protected void unsetRealmService(RealmService realmService) { realmService = null; } }
Parse-Server Facebook login
I am running into an issue with signing up a user into Parse-Server while using Facebook. When the user clicks on the Sign up with facebook icon this code will run.. ParseFacebookUtils.logInWithReadPermissionsInBackground(LoginRegister.this, permissions, new LogInCallback() { #Override public void done(ParseUser user, ParseException err) { if (user == null) { MethodContants.showLog(TAG, "Uh oh. The user cancelled the Facebook login.", true); } else if (user.isNew()) { MethodContants.showLog(TAG, "User logged in through Facebook", false); getUserDetailsFromFacebook(); } else { MethodContants.showLog(TAG, "User logged in through Facebook", false); Intent intent = new Intent(LoginRegister.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(intent); } } }); My getUserDetailsFromFacebook() method looks like this private void getUserDetailsFromFacebook() { GraphRequest graphRequest = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() { #Override public void onCompleted(JSONObject jsonObject, GraphResponse response) { try { facebookUser = jsonObject.getString("name"); MethodContants.showLog(TAG, "json name object: " + jsonObject.getString("name"), false); } catch (JSONException e) { MethodContants.showLog(TAG, "Error when getting facebook name: " + e.getMessage(), true); showToast("Error saving Facebook user."); } try { facebookEmail = jsonObject.getString("email"); MethodContants.showLog(TAG, "json email object: " + jsonObject.getString("email"), false); } catch (JSONException e) { MethodContants.showLog(TAG, "Error when getting facebook email: " + e.getMessage(), true); showToast("Error saving Facebook email."); } saveNewFacebookUser(); } }); Bundle parameters = new Bundle(); parameters.putString("fields", "name,email"); graphRequest.setParameters(parameters); graphRequest.executeAsync(); } my saveNewFacebookUser() looks like this... private void saveNewFacebookUser() { final ParseUser newFacebookUser = new ParseUser(); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.profile_picture); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] image = stream.toByteArray(); ParseFile file = new ParseFile(AppConstants.PARSEUSER_IMAGE_FILE_NAME, image); newFacebookUser.setUsername(facebookUser); newFacebookUser.setEmail(facebookEmail); newFacebookUser.put(AppConstants.PARSEUSER_FULLNAME, facebookUser); newFacebookUser.put(AppConstants.PARSEUSER_FIRST_TIME_LOGGED_IN, "true"); newFacebookUser.put(AppConstants.PARSEUSER_PROFILE_IMAGE, file); file.saveInBackground(new SaveCallback() { #Override public void done(ParseException e) { if (e == null) { newFacebookUser.saveInBackground(new SaveCallback() { #Override public void done(ParseException e) { if (e == null) { // USER CREATED! // TODO SEND AN EMAIL TO THE USER WITH USERNAME AND PASSWORD Intent intent = new Intent(LoginRegister.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); startActivity(intent); } else { MethodContants.showLog(TAG, "Facebook Error:" + e.getMessage(), true); showToast("Facebook Error: " + e.getMessage()); } } }); } else { MethodContants.showLog(TAG, "Facebook Error:" + e.getMessage(), true); showToast("Facebook Error: " + e.getMessage()); } } }); } The error is telling me that I have to use signUpInBackground and not saveInBackground. However, when I do that, I get another error that says I need to save a password for the user -> which defeats the whole purpose of the facebook login. Any help would be much appreciated!
I found the issue. in the saveNewFacebookUser() method, I was setting it as a brand new user. ParseUser new = new ParseUser(); This should have been ParseUser new = ParseUser.getCurrentUser(); I will leave this up in case anyone has issues.
Getting API name from Synapse handler
I am trying to implement a custom logger with Synapse handler, I can differentiate API and service but how can I get the API name from synapse handler code? Service name is __SynapseService for all APIs. public static boolean isProxyService(MessageContext messageContext, AxisService axisService) { if (axisService != null) { Parameter val = axisService.getParameter("serviceType"); if (val != null && val.getValue().toString().equalsIgnoreCase("Proxy")) { if (logger.isDebugEnabled()) { logger.debug("Parameter Value Service Type: " + val.getValue().toString()); } return true; } } return false; } public static boolean isAPI(MessageContext messageContext, AxisService axisService) { if(!isProxyService(messageContext, axisService) && axisService.getAxisServiceGroup().getServiceGroupName().equals(SynapseConstants.SYNAPSE_SERVICE_NAME)){ return true; } return false; } public static String getServiceName(MessageContext messageContext, AxisService axisService) { org.apache.axis2.context.MessageContext msgContext = ((Axis2MessageContext) messageContext).getAxis2MessageContext(); return msgContext.getServiceContext().getName(); }
Try this. String apiName = (String) messageContext.getProperty("SYNAPSE_REST_API");
Programe Not Executing in Correct Order in Android Studio
I want to check whether the email id entered by user is unique or not so for that initially I have my variable Boolean valid = false;. On clicking a button i am taking the email id entered and checking it for valid email id expression using regular expression and then i am using an asyntask to check its uniqueness. Code in my onclicklistner is if (emailid.matches(regexp) && emailid.length() > 0) { new Validate().execute(); Toast.makeText(getApplicationContext(), valid.toString(), Toast.LENGTH_LONG).show(); if (valid) { data.putString("eid", eid); data.putString("firstname", firstname); data.putString("lastname", lastname); data.putString("emailid", emailid); Intent i = new Intent(getApplicationContext(), GamesFragment.class); startActivity(i); } else { Toast.makeText(getApplicationContext(), "Email Address Already Exist", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(getApplicationContext(), "Check Your Email Address", Toast.LENGTH_LONG).show(); } Here what problem i am facing is, for first time when i am entering an email which is unique and clicks the button, the Validate() asynctask checks and sets the valid variable to true, but it doesn't goes to next activity GamesFragment because i have declared valid = false initially. Now when i again click the button, then it goes to next activity as the valid variable is set to true because of previous click. Now My Validate() asynctask is private class Validate extends AsyncTask<Void, Void, Void> { #Override protected Boolean doInBackground(Void... params) { ArrayList<NameValuePair> emailId = new ArrayList<NameValuePair>(); emailId.add(new BasicNameValuePair("email", emailid)); try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("url/validate.php"); httppost.setEntity(new UrlEncodedFormEntity(emailId)); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); iss = entity.getContent(); } catch(Exception e) { Log.e("pass 1", "Connection Error"); e.printStackTrace(); } try { BufferedReader reader = new BufferedReader (new InputStreamReader(iss,"iso-8859-1"),8); StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) sb.append(line + "\n"); iss.close(); result = sb.toString(); } catch(Exception e) { e.printStackTrace(); } try { JSONObject json_data = new JSONObject(result); code=(json_data.getInt("code")); if(code == 1) valid = true; else valid = false; Log.e("pass 3", "valid "+valid); } catch(Exception e) { e.printStackTrace(); } return null; } } Please help i am not getting why this is happening.
Create function to check validation. private boolean function validate(String emailid){ if (emailid.matches(regexp) && emailid.length() > 0) { return true; } return false; } use that function to decide event if(validate(emailid)){ // if function return true then email is valid and good to go. new Validate().execute(); } For second condition you have to check it in your async task onPostExecute() that is Validate(); #Override protected void onPostExecute(Object o) { super.onPostExecute(o); if(code == 1){ // check if response is valid than Intent i = new Intent(getApplicationContext(), GamesFragment.class); startActivity(i); } }
Interceptors doesn't work in Unit tests
I am get Interceptors working on the application server. I have annotated EJB: #Stateless #Named("accountsEJB") public class AccountsEJB { #PersistenceContext(unitName = "weducationPU") private EntityManager em; // . . . other methods #WithLog #Restricted(allowedRoles = {}) // Allowed only for admin public Account save(Account item) { if (item.getId() == 0) { em.persist(item); return item; } else { return em.merge(item); } } #WithLog #Restricted(allowedRoles = {}) // Allowed only for admin public void delete(final Account item) { Account a = em.find(Account.class, item.getId()); if (null != a) { em.remove(a); } } } Empty list of roles means, that It's allowed only for role admin. Here the unit test file for this EJB public class AccountsEJBTest { private static EJBContainer container; private static AccountsEJB ejb; #BeforeClass public static void setUpClass() { try { Map<String, Object> properties = new HashMap<>(); properties.put(EJBContainer.MODULES, new File("target/classes")); properties.put("org.glassfish.ejb.embedded.glassfish.installation.root", "glassfish"); properties.put(EJBContainer.APP_NAME, "weducation"); container = EJBContainer.createEJBContainer(properties); ejb = (AccountsEJB) container.getContext().lookup("java:global/weducation/classes/AccountsEJB"); System.out.println("AccountsEJBTest running..."); } catch (NamingException e) { fail("Container init error: " + e.getMessage()); } } #AfterClass public static void tearDownClass() { if (null != container) { container.close(); } System.out.println("AccountsEJBTest finished"); } private boolean equals(Account source, Account result) { if (!source.getFullName().contentEquals(result.getFullName())) return false; if (!source.getLogin().contentEquals(result.getLogin())) return false; return source.getRole() == result.getRole(); } #Test public void testOperations() { try { System.out.println("-->testOperations()"); Account testAccount = new Account(); testAccount.setFullName("Test Account"); testAccount.setLogin("test"); testAccount.setPassword("test"); testAccount.setConfirm("test"); testAccount.updatePassword(); testAccount.setRole(AccountRole.DEPOT); Account savedAccount = ejb.save(testAccount); assertTrue(equals(testAccount, savedAccount)); savedAccount.setFullName("Still Test Account"); savedAccount.setLogin("test1"); testAccount = ejb.save(savedAccount); assertTrue(equals(testAccount, savedAccount)); testAccount.setPassword("testpwd"); testAccount.setConfirm("testpwd"); testAccount.updatePassword(); savedAccount = ejb.save(testAccount); assertTrue(equals(testAccount, savedAccount)); ejb.delete(savedAccount); } catch (Exception e) { fail("Exception class " + e.getClass().getName() + " with message " + e.getMessage()); } } } And this test working. I think, that is not correct, because there is no user with admin role logged in. But why this behavior happing? UPDATED. #Restricted interface: #Inherited #InterceptorBinding #Target({METHOD, TYPE}) #Retention(RUNTIME) public #interface Restricted { #Nonbinding AccountRole[] allowedRoles(); } SecurityInterceptor class #Interceptor #Restricted(allowedRoles = {}) public class SecurityInterceptor implements Serializable { #Inject private transient SessionMB session; #AroundInvoke public Object checkSecurity(InvocationContext context) throws Exception { //System.out.println("Security checker started."); if ((session == null) || (session.getUser() == null)) { throw new SecurityException("Can't get user info"); } // Allow all to admin if (session.isAdmin()) { //System.out.println("It's admin."); return context.proceed(); } // walk non administrator roles for (AccountRole r : getAllowedRoles(context.getMethod())) { // if match - accept method invocation if (session.getUser().getRole() == r) { //System.out.println("It's " + r.getDescription()); return context.proceed(); } } throw new SecurityException(session.getUser().getFullName() + " has no souch privilegies "); } private AccountRole[] getAllowedRoles(Method m) { if (null == m) { throw new IllegalArgumentException("Method is null!"); } // Walk all method annotations for (Annotation a : m.getAnnotations()) { if (a instanceof Restricted) { return ((Restricted) a).allowedRoles(); } } // Now - walk all class annotations if (null != m.getDeclaringClass()) { for (Annotation a : m.getDeclaringClass().getAnnotations()) { if (a instanceof Restricted) { return ((Restricted) a).allowedRoles(); } } } // if no annotaion found throw new RuntimeException("Annotation #Restricted not found at method " + m.getName() + " or it's class."); } } The beans.xml is placed in WEB-INF folder and looks like <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated"> <interceptors> <class>ru.edu.pgtk.weducation.interceptors.LogInterceptor</class> <class>ru.edu.pgtk.weducation.interceptors.SecurityInterceptor</class> </interceptors> </beans> Can someone help me to know: How to get Interceptors working in Unit tests? How to start authorized session in Unit tests (log in as admin, for example)? How to test such operations as creation and deleting account with the different tests (one test for creating, one for deleting)? Is it correct - to test all operations in one test? Thank you for your time and your questions.