fix: Various oauth issues
This commit is contained in:
parent
d05ea54f8d
commit
3d763a84df
|
|
@ -1,4 +1,4 @@
|
||||||
// @generated by protoc-gen-es v2.10.0
|
// @generated by protoc-gen-es v2.10.1
|
||||||
// @generated from file olivetin/api/v1/olivetin.proto (package olivetin.api.v1, syntax proto3)
|
// @generated from file olivetin/api/v1/olivetin.proto (package olivetin.api.v1, syntax proto3)
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
|
|
@ -1421,15 +1421,15 @@ export declare type OAuth2Provider = Message<"olivetin.api.v1.OAuth2Provider"> &
|
||||||
*/
|
*/
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string url = 2;
|
|
||||||
*/
|
|
||||||
url: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from field: string icon = 3;
|
* @generated from field: string icon = 3;
|
||||||
*/
|
*/
|
||||||
icon: string;
|
icon: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string key = 4;
|
||||||
|
*/
|
||||||
|
key: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,7 @@
|
||||||
<div v-if="hasOAuth" class="login-oauth2">
|
<div v-if="hasOAuth" class="login-oauth2">
|
||||||
<h3>OAuth Login</h3>
|
<h3>OAuth Login</h3>
|
||||||
<div class="oauth-providers">
|
<div class="oauth-providers">
|
||||||
<button v-for="provider in oauthProviders" :key="provider.name || provider.title" class="oauth-button"
|
<button v-for="provider in oauthProviders" :key="provider.key" class="oauth-button"
|
||||||
@click="loginWithOAuth(provider)">
|
@click="loginWithOAuth(provider)">
|
||||||
<span v-if="provider.icon" class="provider-icon" v-html="provider.icon"></span>
|
<span v-if="provider.icon" class="provider-icon" v-html="provider.icon"></span>
|
||||||
<span class="provider-name">Login with {{ provider.title }}</span>
|
<span class="provider-name">Login with {{ provider.title }}</span>
|
||||||
|
|
@ -106,9 +106,13 @@ async function handleLocalLogin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loginWithOAuth(provider) {
|
function loginWithOAuth(provider) {
|
||||||
const providerName = provider.title.toLowerCase()
|
if (!provider.key) {
|
||||||
|
console.error('OAuth provider missing key:', provider)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
window.location.href = `/oauth/login?provider=${providerName}`
|
const providerKey = encodeURIComponent(provider.key)
|
||||||
|
window.location.href = `/oauth/login?provider=${providerKey}`
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
@ -138,4 +142,12 @@ form {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.provider-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
margin-right: .4em;
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ checkForUpdates: false
|
||||||
authOAuth2RedirectUrl: "http://localhost:1337/oauth2/callback"
|
authOAuth2RedirectUrl: "http://localhost:1337/oauth2/callback"
|
||||||
authOAuth2Providers:
|
authOAuth2Providers:
|
||||||
github:
|
github:
|
||||||
title: "GitHub"
|
name: github
|
||||||
|
title: "Good old GitHub"
|
||||||
clientId: "test-client-id"
|
clientId: "test-client-id"
|
||||||
clientSecret: "test-client-secret"
|
clientSecret: "test-client-secret"
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ authRequireGuestsToLogin: true
|
||||||
# Simple actions for testing
|
# Simple actions for testing
|
||||||
actions:
|
actions:
|
||||||
- title: Ping Google.com
|
- title: Ping Google.com
|
||||||
shell: ping google.com -c 1
|
shell: echo "ping google.com"
|
||||||
icon: ping
|
icon: ping
|
||||||
|
|
||||||
- title: sleep 2 seconds
|
- title: sleep 2 seconds
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ import { By, until, Condition } from 'selenium-webdriver'
|
||||||
import {
|
import {
|
||||||
getRootAndWait,
|
getRootAndWait,
|
||||||
takeScreenshotOnFailure,
|
takeScreenshotOnFailure,
|
||||||
} from '../lib/elements.js'
|
} from '../../lib/elements.js'
|
||||||
|
|
||||||
describe('config: githubOAuth', function () {
|
describe('config: githubOAuth', function () {
|
||||||
this.timeout(30000)
|
this.timeout(30000)
|
||||||
|
|
||||||
before(async function () {
|
before(async function () {
|
||||||
await runner.start('githubOAuth')
|
await runner.start('oauthLoginGithub')
|
||||||
})
|
})
|
||||||
|
|
||||||
after(async () => {
|
after(async () => {
|
||||||
|
|
@ -75,37 +75,25 @@ describe('config: githubOAuth', function () {
|
||||||
await new Promise(resolve => setTimeout(resolve, 3000))
|
await new Promise(resolve => setTimeout(resolve, 3000))
|
||||||
|
|
||||||
// Find GitHub OAuth button
|
// Find GitHub OAuth button
|
||||||
|
// Since the test config only has one provider (GitHub), we can use the first button
|
||||||
const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
|
const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
|
||||||
expect(githubButtons.length).to.be.greaterThan(0)
|
expect(githubButtons.length).to.be.greaterThan(0, 'At least one OAuth button should be present')
|
||||||
|
|
||||||
let githubButton = null
|
const githubButton = githubButtons[0]
|
||||||
for (const button of githubButtons) {
|
const buttonText = await githubButton.getText()
|
||||||
const buttonText = await button.getText()
|
console.log('Button text:', buttonText)
|
||||||
if (buttonText.toLowerCase().includes('github')) {
|
|
||||||
githubButton = button
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(githubButton).to.not.be.null('GitHub OAuth button should be present')
|
// Verify it's the GitHub button (should contain "github" in the text)
|
||||||
|
expect(buttonText.toLowerCase()).to.include('github', 'Button should be GitHub OAuth button')
|
||||||
// Verify button is displayed and enabled
|
|
||||||
const isDisplayed = await githubButton.isDisplayed()
|
|
||||||
expect(isDisplayed).to.be.true('GitHub OAuth button should be displayed')
|
|
||||||
|
|
||||||
const isEnabled = await githubButton.isEnabled()
|
|
||||||
expect(isEnabled).to.be.true('GitHub OAuth button should be enabled')
|
|
||||||
|
|
||||||
// Check for provider icon (if present)
|
// Check for provider icon (if present)
|
||||||
const providerIcons = await githubButton.findElements(By.css('.provider-icon'))
|
const providerIcons = await githubButton.findElements(By.css('.provider-icon'))
|
||||||
// Icon may or may not be present, so we don't assert on it
|
|
||||||
|
|
||||||
// Check for provider name
|
|
||||||
const providerNames = await githubButton.findElements(By.css('.provider-name'))
|
const providerNames = await githubButton.findElements(By.css('.provider-name'))
|
||||||
// Provider name may show "GitHub" (from title) or be undefined (if using name field)
|
// Provider name may show "GitHub" (from title) or be undefined (if using name field)
|
||||||
// Just verify the structure is present
|
// Just verify the structure is present
|
||||||
if (providerNames.length > 0) {
|
if (providerNames.length > 0) {
|
||||||
const providerNameText = await providerNames[0].getText()
|
const providerNameText = await providerNames[0].getText()
|
||||||
|
expect(providerNameText.toLowerCase()).to.include('github', 'Provider name should include "github"')
|
||||||
expect(providerNameText).to.include('Login with', 'Provider name should have "Login with" prefix')
|
expect(providerNameText).to.include('Login with', 'Provider name should have "Login with" prefix')
|
||||||
console.log('Provider name text:', providerNameText)
|
console.log('Provider name text:', providerNameText)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -329,8 +329,8 @@ message AdditionalLink {
|
||||||
|
|
||||||
message OAuth2Provider {
|
message OAuth2Provider {
|
||||||
string title = 1;
|
string title = 1;
|
||||||
string url = 2;
|
|
||||||
string icon = 3;
|
string icon = 3;
|
||||||
|
string key = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetActionBindingRequest {
|
message GetActionBindingRequest {
|
||||||
|
|
|
||||||
|
|
@ -3390,8 +3390,8 @@ func (x *AdditionalLink) GetUrl() string {
|
||||||
type OAuth2Provider struct {
|
type OAuth2Provider struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
||||||
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
|
|
||||||
Icon string `protobuf:"bytes,3,opt,name=icon,proto3" json:"icon,omitempty"`
|
Icon string `protobuf:"bytes,3,opt,name=icon,proto3" json:"icon,omitempty"`
|
||||||
|
Key string `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
@ -3433,16 +3433,16 @@ func (x *OAuth2Provider) GetTitle() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *OAuth2Provider) GetUrl() string {
|
func (x *OAuth2Provider) GetIcon() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Url
|
return x.Icon
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *OAuth2Provider) GetIcon() string {
|
func (x *OAuth2Provider) GetKey() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Icon
|
return x.Key
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
@ -4003,9 +4003,9 @@ const file_olivetin_api_v1_olivetin_proto_rawDesc = "" +
|
||||||
"\x05title\x18\x01 \x01(\tR\x05title\x12\x10\n" +
|
"\x05title\x18\x01 \x01(\tR\x05title\x12\x10\n" +
|
||||||
"\x03url\x18\x02 \x01(\tR\x03url\"L\n" +
|
"\x03url\x18\x02 \x01(\tR\x03url\"L\n" +
|
||||||
"\x0eOAuth2Provider\x12\x14\n" +
|
"\x0eOAuth2Provider\x12\x14\n" +
|
||||||
"\x05title\x18\x01 \x01(\tR\x05title\x12\x10\n" +
|
"\x05title\x18\x01 \x01(\tR\x05title\x12\x12\n" +
|
||||||
"\x03url\x18\x02 \x01(\tR\x03url\x12\x12\n" +
|
"\x04icon\x18\x03 \x01(\tR\x04icon\x12\x10\n" +
|
||||||
"\x04icon\x18\x03 \x01(\tR\x04icon\"8\n" +
|
"\x03key\x18\x04 \x01(\tR\x03key\"8\n" +
|
||||||
"\x17GetActionBindingRequest\x12\x1d\n" +
|
"\x17GetActionBindingRequest\x12\x1d\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"binding_id\x18\x01 \x01(\tR\tbindingId\"K\n" +
|
"binding_id\x18\x01 \x01(\tR\tbindingId\"K\n" +
|
||||||
|
|
|
||||||
|
|
@ -865,11 +865,11 @@ func (api *oliveTinAPI) addCustomDashboards(rootDashboards *[]string, dashboards
|
||||||
func buildPublicOAuth2ProvidersList(cfg *config.Config) []*apiv1.OAuth2Provider {
|
func buildPublicOAuth2ProvidersList(cfg *config.Config) []*apiv1.OAuth2Provider {
|
||||||
var publicProviders []*apiv1.OAuth2Provider
|
var publicProviders []*apiv1.OAuth2Provider
|
||||||
|
|
||||||
for _, provider := range cfg.AuthOAuth2Providers {
|
for providerKey, provider := range cfg.AuthOAuth2Providers {
|
||||||
publicProviders = append(publicProviders, &apiv1.OAuth2Provider{
|
publicProviders = append(publicProviders, &apiv1.OAuth2Provider{
|
||||||
Title: provider.Title,
|
Title: provider.Title,
|
||||||
Url: provider.AuthUrl,
|
|
||||||
Icon: provider.Icon,
|
Icon: provider.Icon,
|
||||||
|
Key: providerKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OAuth2Handler struct {
|
type OAuth2Handler struct {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue