Retrieving current user's UserId object - exchangewebservices

I'm writing some code that does administrative tasks on an Exchange server, and I need to set a public folder's permissions, giving myself (that is, the mailbox/user that is connected to Exchange) permissions on a given folder.
The code for this is along these lines:
UserId userId = ???;
myFolder.Permissions.Add(userId, FolderPermissionLevel.Owner);
myFolder.Update();
This code would work fine (and there's no problem with me having permissions to grant myself permissions, since I'm in the Public Folder Management AD group), but the problem is that I don't have UserId object that represents the current user. I don't even have a primarySmtpAddress, which is another way to get a UserId. All I know is that I'm in the context of a user that has permissions to a mailbox - it might be the current Windows user, it might just be a NetworkCredential that was passed to my library.
Is there a way in EWS to get the current user, or at least the current user's SMTP address? I looked in the ExchangeService class but couldn't find anything to that effect.

If you have the NetworkCredential you can bind to AD and use the GetObject to get the IADsUser. From there you can get the email address. Then you can use:
UserIdType user = new UserIdType();
user.PrimarySmtpAddress = "user3#example.com.com";
to set your permissionset userid:
http://msdn.microsoft.com/en-us/library/bb856574(v=exchg.80).aspx

Related

Is endpoint unique for device in AWS Pinpoint?

I am new to Pinpoint and trying to understand how endpoint/endpointId works in Pinpoint semantics. From the aws doc:
When a user starts a session (for example, by launching your mobile app), your mobile or web application can automatically register (or update) an endpoint with Amazon Pinpoint.
Does that mean each time of the app launching, there is a new endpoint/endpointId? Will it register a new endpoint if the current session ends or the user kill and relaunch the app?
Is there a way I can get the endpoint/endpointId in the app programmatically?
Yes, the endpoint is the same for each unique device, email, etc. It needs to be the same so that Amazon knows where to send push notifications, for example, if you run a targeted campaign. If the user kills and relaunches the app, then the same endpoint is used. This goes for both authenticated and unauthenticated users. Thus, I would have reason to believe that if the current session ends (i.e. the user has to re-authenticate), then they have the same endpoint. This makes sense because every device (the device itself) needs a unique identifier. In order to better answer your question, I have personally tested the below and confirmed:
If one user logs out, and another logs in [on the same device], the endpoint ID remains the same. The purpose of the code below registers a user ID with a specific endpoint. You can also modify the code below to print the endpoint ID, as you requested.
At the top of your AppDelegate, put this, assuming you're using Swift and AWS Cognito for user authentication:
var pinpoint: AWSPinpoint?
... in didFinishLaunching, put this:
self.pinpoint = AWSPinpoint(configuration:AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: launchOptions))
if let targetingClient = pinpoint?.targetingClient {
if let username = AppDelegate.defaultUserPool().currentUser()?.username {
let endpoint = targetingClient.currentEndpointProfile()
// Create a user and set its userId property
let user = AWSPinpointEndpointProfileUser()
user.userId = username
// Assign the user to the endpoint
endpoint.user = user
// Update the endpoint with the targeting client
targetingClient.update(endpoint)
print("Assigned user ID \(user.userId ?? "nil") to endpoint \(endpoint.endpointId).\n")
}
}

Spring Security Authenticates User with old credentials until Web App Restart

Hi there I am developing a web app and I am using Spring Security. In the app the user can change his/her details (username, password and some other fields). I am using a custom User Details Class for this and my Spring Security configuration is the default (keep in mind no cache method is declared, so I suppose NullUserCache is used). All the user records come from DataBase using JDBC Connector (MySQL).
Now when a user changes his/her info or/and username-password those changes update the corresponding columns in DataBase. So now the DB is updated. Because I have not implemented setters in my Custom User Details Class, I force the user to logout log out automatically. But now he/she can login using both the new username and the old one.
Suppose now that the user changed something on the other fields (for example if the age was changed from 20 to 21). When user logins using the new username I can see 21. If user logins using the old username I can see 20!.
I guess Spring Security now creates a new User (during login) which didn't exist and the old one is never removed!
So after reading many posts in the web and trying the corresponding solutions I 'm still unable to fix that.
What I have used (in the controller that is responsible for account editing):
if (authenticate != null){
new SecurityContextLogoutHandler().logout(request, response, authenticate);
}
SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.clearContext();
What I understand and believe is that Spring Security holds somewhere (I thought User Cache) the username, maybe along with the password and now it sees the old username as a different User. The only way to prevent this from happening is to restart the app. After restarting the user only logins using the new username.
Is there any way I can remove that "user"-username? Any suggestion would be usefull, I am really confused and the only case close to mine was this but his problem was with the oracle connector using connection cache..
UPDATE problem tracked down to a problem inside loadbyusername method..read more on the 14th comment below :)
Happy coding!
I finally found the source of that problem..black hole closed. Credits #Jebil and #Robin Winch for their help!
Well everything worked as it should except the fact that the HashMap on the rensposible for the login DAO, was never cleared..so after every successful login attempt the HashMap returned was appended and so after every username update, it contained both old and new values..solution was simple..before accessing the DB HashMap should be cleared!
Happy dividing by 0 :P

Google Drive/OAuth - Can't figure out how to get re-usable GoogleCredentials

I've successfully installed and run the Google Drive Quick Start application called DriveCommandLine. I've also adapted it a little to GET file info for one of the files in my Drive account.
What I would like to do now is save the credentials somehow and re-use them without the user having to visit a web page each time to get an authorization code. I have checked out this page with instructions to Retrieve and Use OAuth 2.0 credentials. In order to use the example class (MyClass), I have modified the line in DriveCommandLine where the Credential object is instantiated:
Credential credential = MyClass.getCredentials(code, "");
This results in the following exception being thrown:
java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187)
at com.google.api.client.json.jackson.JacksonFactory.createJsonParser(JacksonFactory.java:84)
at com.google.api.client.json.JsonFactory.fromInputStream(JsonFactory.java:247)
at com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.load(GoogleClientSecrets.java:168)
at googledrive.MyClass.getFlow(MyClass.java:145)
at googledrive.MyClass.exchangeCode(MyClass.java:166)
at googledrive.MyClass.getCredentials(MyClass.java:239)
at googledrive.DriveCommandLine.<init>(DriveCommandLine.java:56)
at googledrive.DriveCommandLine.main(DriveCommandLine.java:115)
I've been looking at these APIs (Google Drive and OAuth) for 2 days now and have made very little progress. I'd really appreciate some help with the above error and the problem of getting persistent credentials in general.
This whole structure seems unnecessarily complicated to me. Anybody care to explain why I can't just create a simple Credential object by passing in my Google username and password?
Thanks,
Brian O Carroll, Dublin, Ireland
* Update *
Ok, I've just gotten around the above error and now I have a new one.
The way I got around the first problem was by modifying MyClass.getFlow(). Instead of creating a GoogleClientServices object from a json file, I have used a different version of GoogleAuthorizationCodeFlow.Builder that allows you to enter the client ID and client secret directly as Strings:
flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, jsonFactory, "<MY CLIENT ID>", "<MY CLIENT SECRET>", SCOPES).setAccessType("offline").setApprovalPrompt("force").build();
The problem I have now is that I get the following error when I try to use flow (GoogleAuthorizationCodeFlow object) to exchange the authorization code for the Credentials object:
An error occurred: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_scope"
}
googledrive.MyClass$CodeExchangeException
at googledrive.MyClass.exchangeCode(MyClass.java:185)
at googledrive.MyClass.getCredentials(MyClass.java:262)
at googledrive.DriveCommandLine.<init>(DriveCommandLine.java:56)
at googledrive.DriveCommandLine.main(DriveCommandLine.java:115)
Is there some other scope I should be using for this? I am currently using the array of scopes provided with MyClass:
private static final List<String> SCOPES = Arrays.asList(
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile");
Thanks!
I feel your pain. I'm two months in and still getting surprised.
Some of my learnings...
When you request user permissions, specify "offline=true". This will ("sometimes" sic) return a refreshtoken, which is as good as a password with restricted permissions. You can store this and reuse it at any time (until the user revokes it) to fetch an access token.
My feeling is that the Google SDKs are more of a hinderence than a help. One by one, I've stopped using them and now call the REST API directly.
On your last point, you can (just) use the Google clientlogin protocol to access the previous generation of APIs. However this is totally deprecated and will shortly be turned off. OAuth is designed to give fine grained control of authorisation which is intrinsically complex. So although I agree it's complicated, I don't think it's unnecessarily so. We live in a complicated world :-)
Your and mine experiences show that the development community is still in need of a consolidated document and recipes to get this stuff into our rear-view mirrors so we can focus on the task at hand.
Oath2Scopes is imported as follows:
import com.google.api.services.oauth2.Oauth2Scopes;
You need to have the jar file 'google-api-services-oauth2-v2-rev15-1.8.0-beta.jar' in your class path to access that package. It can be downloaded here.
No, I don't know how to get Credentials without having to visit the authorization URL at least once and copy the code. I've modified MyClass to store and retrieve credentials from a database (in my case, it's a simple table that contains userid, accesstoken and refreshtoken). This way I only have to get the authorization code once and once I get the access/refresh tokens, I can reuse them to make a GoogleCredential object. Here's how Imake the GoogleCredential object:
GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(jsonFactory)
.setTransport(httpTransport).setClientSecrets(clientid, clientsecret).build();
credential.setAccessToken(accessToken);
credential.setRefreshToken(refreshToken);
Just enter your clientid, clientsecret, accessToken and refreshToken above.
I don't really have a whole lot of time to separate and tidy up my entire code to post it up here but if you're still having problems, let me know and I'll see what I can do. Although, you are effectively asking a blind man for directions. My understanding of this whole system is very sketchy!
Cheers,
Brian
Ok, I've finally solved the second problem above and I'm finally getting a working GoogleCredential object with an access token and a refresh token.
I kept trying to solve the scopes problem by modifying the list of scopes in MyClass (the one that manages credentials). In the end I needed to adjust the scopes in my modified version of DriveCommandLine (the one that's originally used to get an authorization code). I added 2 scopes from Oauth2Scopes:
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET,
Arrays.asList(DriveScopes.DRIVE, Oauth2Scopes.USERINFO_EMAIL, Oauth2Scopes.USERINFO_PROFILE))
.setAccessType("offline").setApprovalPrompt("force").build();
Adding the scopes for user information allowed me to get the userid later in MyClass. I can now use the userid to store the credentials in a database for re-use (without having to get the user to go to a URL each time). I also set the access type to "offline" as suggested by pinoyyid.

Login via email + set_own_login_name + pas.plugins.sqlalchemy = change address fail

I'm using pas.plugins.sqlalchemy on a fresh new Plone 4.1 installation.
I set Plone to have the email address as login name.
It's all ok, but If I want to change the email address via personal-information panel I obtain an error:
You are not a Plone member. You are probably registered on the root user folder. Please notify an administrator if this is unexpected.
In case I would change another personal data field I don't obtain errors.
The problem seems to be the set_own_login_name function of Products.CMFPlone (utils.py).
Details here http://pastie.org/3780218
Thank's
Vito
Are you logged in as an admin user defined in the Zope root?
If that is the case, then see if you can change the login name by going to the acl_users in the Zope root and changing it there.
Otherwise, temporarily switch off emaillogin, change your email, and switch emaillogin back on.
Note that there is a comment (by me) in the utils.py code right before this KeyError is raised, which points to a possible solution that I don't really like:
# PLIP9214: For a user in the zope root we could do something like this:
# userfolder = member.getUser().__parent__.users
# userfolder.updateUser(member.id, loginname)
# But it is probably best not to touch root zope users.

Changing Active Directory user password

How can I change an Active Directory user password using Directory Services without knowing old password?
You are probably searching the SetPassword method, which you should invoke on a DirectoryEntry object.
Check the "Reset a User's Password" example here: Howto: (Almost) Everything In Active Directory via C#.
EDIT:
If you are having problems with the directory entry being null, you are probably passing a wrong path. The path should be something like this:
DirectoryEntry entry = new DirectoryEntry("LDAP://CN=johndoe,CN=Users,DC=acme,DC=com");
There is a new library introduced in .net 3.5 called System.DirectoryServices.AccountManagement. It simplifies user management stuff.
public void ChangePassword(string dn, string newPassword)
{
using (var context = new PrincipalContext(ContextType.Domain))
{
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.DistinguishedName, dn))
{
user.SetPassword(newPassword);
}
}
}
As an MCSE, I do password resets many times a day so I can tell you something about this.
There are basically two operations you can perform with an Active Directory password - a change, and a reset. Changing a password requires that you know the current password on an account, but resetting a password does not require you to know the current password on an account, so in a way, in order to change a user's password without knowing the password, you really need to perform a password reset operation on the account.
By the way, i believe there are two seperate Active Directory extended rights that control each of these permissions, but I am not intimately familiar with them, as I am a delegated admin who is delegated thos abillity.
So, please keep in mind that any attempts to reset a user's password will fail if you don't have the reset password right granted to you on the target user account.