I wanted to create cloud firestore database programmatically using c#, but I am getting error when I run the code. How would I fix permission related issue I am facing? Below is the code and error
private static AppengineService _appEngineService;
public static void IntializeAppEngine() {
GoogleCredential credential = GoogleCredential.GetApplicationDefault();
if (CloudManager.Credential.IsCreateScopedRequired)
{
credential = CloudManager.Credential.CreateScoped(
AppengineService.Scope.CloudPlatform);
}
_appEngineService = new AppengineService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = CloudManager.ApplicationName
});
}
public static void AddCloudFirestore() {
IntializeAppEngine();
var body = new Application {
LocationId = "us-east1",
Id = "projects/" + CloudManager.ProjectId
};
var res = _appEngineService.Apps.Create(body).Execute();
}
Error:
Unhandled exception. The service appengine has thrown an exception.
HttpStatusCode is Forbidden.
Google.Apis.Requests.RequestError
The caller does not have permission [403]
Errors [
Message[The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
]
Google.GoogleApiException: The service appengine has thrown an exception. HttpStatusCode is Forbidden. The caller does not have permission
at Google.Apis.Requests.ClientServiceRequest`1.ParseResponse(HttpResponseMessage response)
at Google.Apis.Requests.ClientServiceRequest`1.Execute()
at CloudResourceManager.FirebaseManagement.AddCloudFirestore()
Instead of Appengine, Cloud Firestore REST API can be used as Sarah suggested.
In c# Google.Apis.Firestore.v1 can be used to create cloud firestore.
I'm working with Aws Sdk and I'm trying to implement a login UI using UWP. I followed this online tutorial (which is for WPF) and I tried to make it works for the Universal Windows Platform as well.
The core part of the source code is the following (please note that is 90% similar to the one posted in the tutorial. The "only difference" is that I used
InitiateAuthAsync
instead of
AdminInitiateAuthAsync
<!-- language: lang-cs -->
private readonly AmazonCognitoIdentityProviderClient _client;
private readonly string _clientId = "32fsoifj93fjsiispat";
public MainPage()
{
this.InitializeComponent();
var amazonCognitoIdentityProviderConfig = new AmazonCognitoIdentityProviderConfig();
amazonCognitoIdentityProviderConfig.ServiceURL = "https://cognito-idp.eu-central-1.amazonaws.com/";
_client = new AmazonCognitoIdentityProviderClient(amazonCognitoIdentityProviderConfig);
}
private async Task<bool> CheckPasswordAsync(string userName, string password)
{
try
{
List<HttpHeader> httpHeaders = new List<HttpHeader>();
HttpHeader httpHeader = new HttpHeader
{
HeaderName = "X-Amz-Target",
HeaderValue = "AWSCognitoIdentityProviderService.InitiateAuth"
};
httpHeaders.Add(httpHeader);
httpHeader = new HttpHeader
{
HeaderName = "Content-Type",
HeaderValue = "application/x-amz-json-1.1"
};
httpHeaders.Add(httpHeader);
var authReq = new InitiateAuthRequest()
{
ClientId = _clientId,
AuthFlow = AuthFlowType.USER_PASSWORD_AUTH,
};
authReq.AuthParameters.Add("USERNAME", userName);
authReq.AuthParameters.Add("PASSWORD", password);
var authResp = await _client.InitiateAuthAsync(authReq);
return true;
}
catch (Exception ex)
{
return false;
}
}
Please consider that it is working properly with WPF framework. I'm able to get the TokenId and RefreshToken.
But if I try to copy and paste the same code in UWP I get the exception:
'Unable to get IAM security credentials from EC2 Instance Metadata Service.'
And if I try to investigate with Fiddler I get the following error:
[Fiddler] The connection to '169.254.169.254' failed. Error: NetworkUnreachable (0x2743). System.Net.Sockets.SocketException A socket operation was attempted to an unreachable network 169.254.169.254:80
I really can't understand why it tries to connect to the '169.254.169.254' address. Googling around I found other people experiencing the same issue (for example here). Do you have any idea?
I am trying to read/write emails/folders inside Gmail mailboxes using the Gmail REST API. When adding the following Google auth scopes, emails can be read from Gmail REST API without any problem:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://www.googleapis.com/auth/gmail.readonly,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
Note: The parameter https://www.googleapis.com/auth/gmail.readonly correctly allows one to read from mailboxes.
However, I need to be able to delete emails too. Thus, in line with the documentation at https://developers.google.com/gmail/api/auth/scopes?hl=ja, one simply needs to include https://mail.google.com/ in place of https://www.googleapis.com/auth/gmail.readonly. When adding the following auth scopes:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://mail.google.com/,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
... the error outputted is as follows:
2015-07-27 10:27:59 i.c.s.a.cv [DEBUG] failed get labels for user
com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
Surely, this is incorrect on the part of Google? What am I missing? Is the documentation incorrect? What auth scope needs to be added?
I am interfacing with the Java Google API Client Library. See: https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.20.0/overview-summary
The delete request is as follows:
public void deleteMessages(Queue<String> messages, GoogleUserAdapter user) throws Exception {
Gmail gmail = getService(user);
JsonBatchCallback<Void> voidCallBack = new JsonBatchCallback<Void>() {
#Override
public void onSuccess(Void t, HttpHeaders responseHeaders) throws IOException {
logger.debug("delete success");
}
#Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
logger.debug("failed to delete message:"+e.getMessage());
}
};
while (!messages.isEmpty()) {
if (Thread.currentThread().isInterrupted())
throw new InterruptedException();
BatchRequest batch = gmail.batch();
for (int i = 0; i < MAX_REQUESTS; i++) {
if (messages.isEmpty() || Thread.currentThread().isInterrupted())
break;
gmail.users().messages().delete(user.getId(), messages.poll()).queue(batch, voidCallBack);
}
batch.execute();
}
}
The credential is created as follows:
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {
Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(connection.getServiceAccountId())
.setServiceAccountScopes(
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
"https://apps-apis.google.com/a/feeds/compliance/audit/",
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
.setServiceAccountUser(impersonateAccount)
.setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
.build();
setHttpTimeout(credential);
return credential;
}
The exact error that occurs on delete is:
failed to delete message:Insufficient Permission
Jamie
Access denied is caused by a typo in the constant GmailScopes.MAIL_GOOGLE_COM as defined by the Google Java Client API.
The constant returns "https://mail.google.com" and not "https://mail.google.com/" (as it ought to be). Omitting a backslash at the end of the string will result in access denied.
Thus, in the example above, the following service scopes must be set:
https://apps-apis.google.com/a/feeds/compliance/audit/","https://mail.google.com/",DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY, DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY
(note: the hardcoded value of "https://mail.google.com/")
The following string must be added to Manage API client access page in Google Apps:
https://apps-apis.google.com/a/feeds/compliance/audit/,
https://www.googleapis.com/auth/admin.directory.user.readonly, https://mail.google.com/,
https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly
I hope this helps someone else!
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {
Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(connection.getServiceAccountId())
.setServiceAccountScopes(
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
"https://apps-apis.google.com/a/feeds/compliance/audit/",
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
.setServiceAccountUser(impersonateAccount)
.setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
.build();
setHttpTimeout(credential);
return credential;
}
I am using google app engine's urlfetch sevice to get book description from google play. When I fetch the url
https://play.google.com/store/books
, I can get correct web page html content and parse it in my local developement enviroment. But on production server, Google Play just give me a "Unavailable in your country" page.
This is my test code referenced from GAE document(https://developers.google.com/appengine/docs/java/urlfetch/usingjavanet)
try {
URL url = new URL("https://play.google.com/store/books");
final URLConnection connection = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// connection.setRequestProperty("Accept-Language", "en-US");
String line;
while ((line = reader.readLine()) != null) {
log.warn(line);
}
reader.close();
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
I also try to change request property "Accept-Language" but not work. Do you have any ideas for this ?
Seems to be a simple thing using a WebClient object to retrieve content of a text file in a Silverlight web application.
It works in our intranet setup on a local server, but when deployed on a hosted "hostgator" server, WebClient gets a security exception. Following suggestions from numerous web blogs, I tried crossdomain access policy and crossdomain.xml with no result - no wonder, all in on the same domain.
private void LoadCSVFile(string csvFile)
{
try
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(csvFile, UriKind.Absolute));
}
catch (Exception ex)
{
string errorMessage = String.Format("Ex accessing csv: {0}\n{1}", csvFile,
}
}
//the csvFile is an absolute path: http://myserver.com/myapplication:port/sourcefiles/file.csv
//The sourcefiles is a virtual directory in the same website containing csv files
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(e.Result))
{
mainFileData = new List<string>();
string line;
}
}
catch (Exception ex)
{
string errorMessage = ex.InnerException;
}else
{
"here is the place for the exception!!!!!!! so, e.Error is not null"
}
}
The text of the exception reads: System.SecurityException: Security error at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult) etc.
Spend 2 days gooogling with no result.
Please help.
V
A couple of things to check:
(1) The format for the URL that you list (http://myserver.com/myapplication:port/sourcefiles/file.csv) looks odd. Shouldn't it be http://myserver.com:port/myapplication/sourcefiles/file.csv? Or is that just a typo?
(2) What's the port number that you're accessing? The Silverlight WebClient will only access ports 80 and 443.
(3) Can you get to the file using a direct URL? Sometimes web servers need to be told about a specific file type before they'll allow it to be served up.