I've followed the guide error-handling for handling back an error to the users from the setCredentials method. However, even when using the provided example method to throw an error to the user, I still get the generic error on all my reports:
This is the default code I used for setting up the setCredentials function looker-studio auth connector.
function setCredentials(request) {
try {
Logger.log('setCredentials/try');
var creds = request.userPass;
var username = creds.username;
var password = creds.password;
var validCreds = validateCredentials(username, password).validCreds;
if (!validCreds) {
return {
errorCode: 'INVALID_CREDENTIALS'
};
};
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('connector.username', username);
userProperties.setProperty('connector.password', password);
return {
errorCode: 'NONE'
};
} catch(e) {
Logger.log('setCredentials/catch');
DataStudioApp.createCommunityConnector()
.newUserError()
.setDebugText('Error setting credentials. Exception details: ' + e)
.setText('I want to show a custom error message')
.throwException();
}
}
This is the toast message I want to change
I tried to throw an error before returning INVALID_CREDENTIALS so it falls in the catch. However, I don't see changes in the text.
function setCredentials(request) {
try {
Logger.log('setCredentials/try');
var creds = request.userPass;
var username = creds.username;
var password = creds.password;
var validCreds = validateCredentials(username, password).validCreds;
if (!validCreds) {
throw new Error('Only to fall to the catch');
};
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('connector.username', username);
userProperties.setProperty('connector.password', password);
return {
errorCode: 'NONE'
};
} catch(e) {
Logger.log('setCredentials/catch');
throw new Error('This message appears but it doesn't overwritte the default message');
}
}
(I have admin set to true)
If I throw again a new Error in the catch before the DataStudioApp newUserError I can see that 2 error toasts appear. A default one and mine, however this is not the intended result. What I want is to edit the default error message and I don't know if it's possible.
Related
I'm having trouble figuring out why can't I see a prompt to enter API key. I can connect directly without any authentication. Why is the API key ignored?
auth.js file:
function getAuthType() {
return {
type: 'KEY'
};
}
function validateKey(key) {
var url = 'http://myapi.com/endpoint?api_key=' + key;
var options = {
"method": "post",
"contentType":"application/json"
};
var response = JSON.parse(
UrlFetchApp.fetch(url, options)
);
Logger.log(response.data.length > 0)
return response.data.length > 0;
}
function isAuthValid() {
var userProperties = PropertiesService.getUserProperties();
var key = userProperties.getProperty('dscc.key');
return validateKey(key);
}
function resetAuth() {
var userProperties = PropertiesService.getUserProperties();
userProperties.deleteProperty('dscc.key');
}
function setCredentials(request) {
var key = request.key;
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('dscc.key', key);
return {
errorCode: 'NONE'
};
}
function isAdminUser() {
return false;
}
The Logger.log output:
I was using a http url. We've moved our API to https and the problem is solved. Data Studio doesn't show any error messages and skips the auth step. This is very strange.
Edit: A month later, while reviewing the document I noticed that Data Studio is already asking for us an https url.
Each prefix must use https://, not http://. source
I have a login form which have username and password fields in it. I want to authenticate username and password with Oidc Client . This is a method that was used for signing in by default:
async signIn(state) {
await this.ensureUserManagerInitialized();
try {
const silentUser = await this.userManager.signinSilent(this.createArguments());
this.updateState(silentUser);
return this.success(state);
} catch (silentError) {
// User might not be authenticated, fallback to popup authentication
console.log("Silent authentication error: ", silentError);
try {
if (this._popUpDisabled) {
throw new Error('Popup disabled. Change \'AuthorizeService.js:AuthorizeService._popupDisabled\' to false to enable it.')
}
const popUpUser = await this.userManager.signinPopup(this.createArguments());
this.updateState(popUpUser);
return this.success(state);
} catch (popUpError) {
if (popUpError.message === "Popup window closed") {
// The user explicitly cancelled the login action by closing an opened popup.
return this.error("The user closed the window.");
} else if (!this._popUpDisabled) {
console.log("Popup authentication error: ", popUpError);
}
// PopUps might be blocked by the user, fallback to redirect
try {
await this.userManager.signinRedirect(this.createArguments(state));
return this.redirect();
} catch (redirectError) {
console.log("Redirect authentication error: ", redirectError);
return this.error(redirectError);
}
}
}
}
Method was called from Login.js :
async login(returnUrl) {
const state = {returnUrl };
const result = await authService.signIn(state);
switch (result.status) {
case AuthenticationResultStatus.Redirect:
break;
case AuthenticationResultStatus.Success:
await this.navigateToReturnUrl(returnUrl);
break;
case AuthenticationResultStatus.Fail:
this.setState({ message: result.message });
break;
default:
throw new Error(`Invalid status result ${result.status}.`);
}
}
Now i have a custom login form. I will have value of user-entered username and password but I have no idea of authenticating it. How can it be done?
Unfortunately it's not supported by the library yet.
https://github.com/IdentityModel/oidc-client-js/issues/234
I'm trying to build my own connector for the first time. I'm getting the following error:
Sorry, we failed to submit your credentials because there was an error in the connector in processing the credentials.
Here is my code so far:
function getAuthType() {
var cc = DataStudioApp.createCommunityConnector();
return cc.newAuthTypeResponse()
.setAuthType(cc.AuthType.USER_TOKEN)
.setHelpUrl('https://api-doc-help-url/authentication')
.build();
}
function validateCredentials(userName, token) {
var rawResponse = UrlFetchApp.fetch('https://api/v2/stuff/' + userName , {
method: 'GET',
headers: {
'Authorization': userName + ':' + token
},
muteHttpExceptions: true
});
return rawResponse.getResponseCode() === 200;
}
function isAuthValid() {
var userProperties = PropertiesService.getUserProperties();
var userName = userProperties.getProperty('dscc.username');
var token = userProperties.getProperty('dscc.token');
return validateCredentials(userName, token);
}
function setCredentials(request) {
var creds = request.userToken;
var username = creds.username;
var token = creds.token;
var validCreds = checkForValidCreds(username, token);
if (!validCreds) {
return {
errorCode: 'INVALID_CREDENTIALS'
};
}
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('dscc.username', username);
userProperties.setProperty('dscc.token', token);
return {
errorCode: 'NONE'
};
}
I'm not sure how all this work exactly. I know that I need to pass the Authorization in the header with the following value userName:token
When deploying my manifest and clicking the Google Data Studio link I'm redirected to the select connector data studio interface. The error appear when I'm trying to submit Usernam and Token.
checkForValidCreds is not defined inside the function setCredentials. which is causing the error
I have this weird scenario which I do not know what the problem is exactly. While troubleshooting I found out that the subscription is published and subscribed to because it's printed on the console. When I executed this on Firefox console it displayed this error SyntaxError: missing : after property id [Learn More]. I don't know what the syntax error is as the same code works on other files.
If I remove fetch() function from it it displayed 2 obects being published. This means the publish and sbscription is working. What am I to do right?
This is the event function
students(){
let myslug = trimInput(Session.get('ReceivedSlug'));
if (myslug) {
let mySchoolDoc = SchoolDb.findOne({slug: myslug});
if (mySchoolDoc) {
let arrayModuleSchool = StudentSchool.find({schoolId: mySchoolDoc._id});
if (arrayModuleSchool) {
var arrayStudentIds = [];
arrayModuleSchool.forEach(function(studentSchool){
arrayStudentIds.push(studentSchool.studentId);
});
let subReadiness = SchoolStudents.find({ _id: {$in: arrayStudentIds}}).fetch();
if (subReadiness) {
console.log('before readiness --- ' +arrayStudentIds);
console.log('after seting --- ' +subReadiness);
return subReadiness;
}
}
}
}
}
This is the publish function
Meteor.publish('PaginatedStudents', function (skipCount) {
check(skipCount, Number);
user = Meteor.users.findOne({_id:this.userId})
if(user) {
if(user.emails[0].verified) {
return SchoolStudents.find({userId: this.userId}, {limit: 2, skip: skipCount});
} else {
throw new Meteor.Error('Not authorized');
return false;
}
}
});
Tracker to rerun when things changes
Session.setDefault('skip', 0);
Tracker.autorun(function () {
Meteor.subscribe('PaginatedStudents', Session.get('skip'));
});
I have been using parse for a while now and I am quite confused by the issue I am having.
Here is one function that I call first:
$scope.followUser = function(usernameToFollow)
{
console.log('ready to follow user: ' + usernameToFollow);
var user = Parse.User.current();
if (user)
{
var FollowUser = Parse.Object.extend('User');
var query = new Parse.Query(FollowUser);
query.equalTo('username', usernameToFollow);
query.find({
success: function(results)
{
var relationToUserPosts = user.relation('followUser');
$scope.userToAdd = results[0];//This is the user I want to add relational data to
relationToUserPosts.add(results[0]);
user.save();
},
error: function(error)
{
alert('Error: ' + error.code + '' + error.message);
}
});
}
else
{
console.log('Need to login a user');
// show the signup or login page
}
};
Next after I call that function I call this function:
$scope.addToFollowers = function()
{
var currUser = Parse.User.current();
console.log($scope.userToAdd);
var followerUser = $scope.userToAdd.relation('followers');
followerUser.add(currUser);
$scope.userToAdd.save();
};
I know for sure the $scope.userToAdd is the user I want, I know the relation I pull from the object is valid its when I try to save this object with $scope.userToAdd.save() is when I get the bad request, with no further information as to why its a bad request. Thank you in advance.
UPDATE:
The first method call has no errors and no bad requests.
Error message:
Well turns out you cannot save a user object unless your are logged in as that user time to find another solution thank you for the help eth3lbert.