Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Join us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.

Reply
paocohe
Frequent Visitor

Establish an oauth connection error

Hello, everyone! 

I'm writing a custom connector, so I want to open a dialog in power bi like this 

paocohe_0-1708977708357.png

after this one 

paocohe_1-1708977740141.png

but when I run the project, i'm only able to see that (the one with the url)

 

That's why I'm trying to understand the way power query works and i'm not sure if i'm implementing something wrong(which I'm pretty sure I am)... my final goal is to make the user write it's own credentials (client id and client secret) and the use them in the authentication process (oauth).

 

My code works without all the "hello..." methods but as I mention before I need to incorporate them to get the data from the dialog and not from the files as it does right now.

 

section GithubSample;

client_id = Text.FromBinary(Extension.Contents("client_id"));
client_secret = Text.FromBinary(Extension.Contents("client_secret"));
redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
authorize_uri = "https://.../authorize?";
token_uri = "https://.../token";
windowWidth = 1200;
windowHeight = 1000;


scope_prefix = "";
scopes = {
"daily"
};

[DataSource.Kind = "GithubSample", Publish = "GithubSample.UI"]
shared GithubSample.Contents = Value.ReplaceType(Github.Contents, type function (url as Uri.Type) as any);
shared GithubSample.HelloWorldType = Value.ReplaceType(HelloWorldImpl, HelloWorldType);

[DataSource.Kind = "GithubSample"]
shared GithubSample.PagedTable = Value.ReplaceType(
Github.PagedTable, type function (url as Uri.Type) as nullable table
);

GithubSample = [
TestConnection = (dataSourcePath) => {"GithubSample.Contents", dataSourcePath},
Authentication = [
OAuth = [
StartLogin = StartLogin,
FinishLogin = FinishLogin,
Refresh=Refresh
//Logout=Logout
]
],
Label = Extension.LoadString("AuthenticationLabel")
];


HelloWorldType = type function (
message as (
type text meta [
Documentation.FieldCaption = "ClientId",
Documentation.FieldDescription = "Add your credential Id",
Documentation.SampleValues = {"d1e6a11a-abca-1111-1111-b11a1aca1bca", "d1e6a11a-abca-1111-1111-b11a1aca1bca"}
]
),
messageTwo as (
type text meta [
Documentation.FieldCaption = "ClientSecret",
Documentation.FieldDescription = "Add your credential secret",
Documentation.SampleValues = {"d1e6a11a-abca-1111-1111-b11a1aca1bca", "d1e6a11a-abca-1111-1111-b11a1aca1bca"}
]
)
) as table meta [
Documentation.Name = "Enter your redentials",
Documentation.LongDescription = "Hello - Long Description",
Documentation.Examples = {
[
Description = "Returns a table with 'Hello world' repeated 2 times",
//Code = "TestHWConnector.Contents(""Hello world"", 2)",
Result = "#table({""Column1""}, {{""Hello world""}, {""Hello world""}})"
],
[
Description = "Another example, new message, new count!",
//Code = "TestHWConnector.Contents(""Goodbye"", 1)",
Result = "#table({""Column1""}, {{""Goodbye""}})"
]
}
];

HelloWorldImpl = (message as text, messageTwo as text) as table =>
let
_count = 1,
listOfMessages = List.Repeat({message},{messageTwo}, _count),
table = Table.FromList(listOfMessages, Splitter.SplitByNothing())
in
table;


GithubSample.UI = [
Beta = true,
ButtonText = {Extension.LoadString("FormulaTitle"), Extension.LoadString("FormulaHelp")},
SourceImage = GithubSample.Icons,
SourceTypeImage = GithubSample.Icons
];

GithubSample.Icons = [
Icon16 = {
Extension.Contents("github16.png"),
Extension.Contents("github20.png"),
Extension.Contents("github24.png"),
Extension.Contents("github32.png")
},
Icon32 = {
Extension.Contents("github32.png"),
Extension.Contents("github40.png"),
Extension.Contents("github48.png"),
Extension.Contents("github64.png")
}
];


Value.IfNull = (a, b) => if a <> null then a else b;

GetScopeString = (scopes as list, optional scopePrefix as text) as text =>
let
prefix = Value.IfNull(scopePrefix, ""),
addPrefix = List.Transform(scopes, each prefix & _),
asText = Text.Combine(addPrefix, " ")
in
asText;

Github.Contents = (url as text) =>
let
excelContent = Web.Contents(url),
workbook = Excel.Workbook(excelContent),
sheetData = workbook{[Item="Sheet1",Kind="Sheet"]}[Data]
in
sheetData;

Github.PagedTable = (url as text) =>
Table.GenerateByPage(
(previous) =>
let
next = if (previous <> null) then Value.Metadata(previous)[Next] else null,
urlToUse = if (next <> null) then next else url,
current = if (previous <> null and next = null) then null else Github.Contents(urlToUse),
link = if (current <> null) then Value.Metadata(current)[Next] else null
in
current meta [Next = link]
);


GetNextLink = (response, optional request) =>
let
link = Value.Metadata(response)[Headers][#"Link"]?,
links = Text.Split(link, ","),
splitLinks = List.Transform(links, each Text.Split(Text.Trim(_), ";")),
next = List.Select(splitLinks, each Text.Trim(_{1}) = "rel=""next"""),
first = List.First(next),
removedBrackets = Text.Range(first{0}, 1, Text.Length(first{0}) - 2)
in
try removedBrackets otherwise null;


StartLogin = (resourceUrl, state, display) =>
let
AuthorizeUrl = authorize_uri
& Uri.BuildQueryString(
[
client_id = client_id,
scope = "param1 param2",
state = state,
redirect_uri = redirect_uri,
response_type = "code"
]
)
in
[
LoginUri = AuthorizeUrl,
CallbackUri = redirect_uri,
WindowHeight = windowHeight,
WindowWidth = windowWidth,
Context = null
];

FinishLogin = (context, callbackUri, state) => let Parts = Uri.Parts(callbackUri)[Query] in TokenMethod(Parts[code]);

TokenMethod = (code) =>
let
Response = Web.Contents(
token_uri,
[
Content = Text.ToBinary(
Uri.BuildQueryString(
[
client_id = client_id,
client_secret = client_secret,
code = code,
grant_type = "authorization_code",
redirect_uri = redirect_uri
]
)
),
Headers = [#"Content-type" = "application/x-www-form-urlencoded", #"Accept" = "application/json"]
]
),
Parts = Json.Document(Response)
in
Parts;


Refresh = (resourceUrl, refresh_token) => TokenMethod("refresh_token", "refresh_token", refresh_token);


Table.GenerateByPage = (getNextPage as function) as table =>
let
listOfPages = List.Generate(
() => getNextPage(null), (lastPage) => lastPage <> null, (lastPage) => getNextPage(lastPage)
),
tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}),
firstRow = tableOfPages{0} ?
in
if (firstRow = null) then
Table.FromRows({})
else
Value.ReplaceType(
Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])),
Value.Type(firstRow[Column1])
);

 

I really apreaciate any suggestions, also, I was recommended to use RLS, but I think this approach wouldn't work since I cannot know the users that will use my connector.

 

Thanks in advance 🙂

3 REPLIES 3
Anonymous
Not applicable

Hi @paocohe 

Based on the sample code you have provided, you are using github connector, please make sure that the redirect URI must match exactly what is registered in the OAuth application, and you can refer to the following link.

Handling authentication for Power Query connectors - Power Query | Microsoft Learn

GitHub tutorial for Power Query - Power Query | Microsoft Learn

 

Best Regards!

Yolo Zhu

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Yes, the connector by itself works but adding the hello methods it's making it fail. And i'm not sure why, that's where i'm looking for an advice

Anonymous
Not applicable

Hi @paocohe 

You can refer to the following link.

Create a custom connector from scratch | Microsoft Learn

 

Best Regards!

Yolo Zhu

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

 

 

 

Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

June 2025 community update carousel

Fabric Community Update - June 2025

Find out what's new and trending in the Fabric community.