Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/cdash/tests/kwtest/kw_web_tester.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ public function getGuzzleClient($username = 'simpletest@localhost',
$html = "{$response->getBody()}";
$dom = new DOMDocument();
@$dom->loadHTML($html);
$token = $dom->getElementById('csrf-token')
$token = $dom->getElementsByTagName('input')
->item(0)
->getAttribute('value');

$response = $client->request('POST',
Expand Down
2 changes: 1 addition & 1 deletion config/saml2.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'enabled' => env('SAML2_ENABLED', false),

/* What text to display in the SAML2 login button */
'login_text' => env('SAML2_LOGIN_TEXT', 'SAML2'),
'login_text' => env('SAML2_LOGIN_TEXT', 'Sign in with SAML2'),

/* Whether or not to automatically register new users */
'autoregister_new_users' => env('SAML2_AUTO_REGISTER_NEW_USERS', false),
Expand Down
8 changes: 4 additions & 4 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
'redirect' => env('APP_URL') . '/auth/github/callback',
'enable' => env('GITHUB_ENABLE', false),
'oauth' => true,
'display_name' => env('GITHUB_DISPLAY_NAME', 'GitHub'),
'display_name' => env('GITHUB_DISPLAY_NAME', 'Sign in with GitHub'),
],
'gitlab' => [
'client_id' => env('GITLAB_CLIENT_ID'),
Expand All @@ -29,7 +29,7 @@
'instance_uri' => env('GITLAB_DOMAIN'),
'enable' => env('GITLAB_ENABLE', false),
'oauth' => true,
'display_name' => env('GITLAB_DISPLAY_NAME', 'GitLab'),
'display_name' => env('GITLAB_DISPLAY_NAME', 'Sign in with GitLab'),
],

'google' => [
Expand All @@ -39,7 +39,7 @@
'redirect' => env('APP_URL') . '/auth/google/callback',
'enable' => env('GOOGLE_ENABLE', false),
'oauth' => true,
'display_name' => env('GOOGLE_DISPLAY_NAME', 'Google'),
'display_name' => env('GOOGLE_DISPLAY_NAME', 'Sign in with Google'),
],

'pingidentity' => [
Expand All @@ -52,7 +52,7 @@
'user_endpoint' => env('PINGIDENTITY_USER_ENDPOINT', '/idp/userinfo.openid'),
'enable' => env('PINGIDENTITY_ENABLE', false),
'oauth' => true,
'display_name' => env('PINGIDENTITY_DISPLAY_NAME', 'PingIdentity'),
'display_name' => env('PINGIDENTITY_DISPLAY_NAME', 'Sign in with PingIdentity'),
],

'mailgun' => [
Expand Down
10 changes: 5 additions & 5 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ To begin, you will need to
| GITHUB_CLIENT_ID | The Client ID assigned to your GitHub OAuth2 app. | '' |
| GITHUB_CLIENT_SECRET | The Client Secret created for your GitHub OAuth2 app. | '' |
| GITHUB_AUTO_REGISTER_NEW_USERS | Whether to automatically register a new user or provide them the Registration form | false |
| GITHUB_DISPLAY_NAME | The text displayed on the GitHub OAuth2 login button | GitHub |
| GITHUB_DISPLAY_NAME | The text displayed on the GitHub OAuth2 login button | Sign in with GitHub |

###### GitLab

Expand All @@ -82,7 +82,7 @@ First [configure GitLab as an OAuth2 authentication identity provider](https://d
| GITLAB_CLIENT_SECRET | The OAuth 2 Client Secret from the Secret field. | '' |
| GITLAB_DOMAIN | The GitLab server to authenticate against. | https://gitlab.com |
| GITLAB_AUTO_REGISTER_NEW_USERS | Whether to automatically register a new user or provide them the Registration form | false |
| GITLAB_DISPLAY_NAME | The text displayed on the GitLab OAuth2 login button | GitLab |
| GITLAB_DISPLAY_NAME | The text displayed on the GitLab OAuth2 login button | Sign in with GitLab |

###### Google

Expand All @@ -94,7 +94,7 @@ Begin by [creating OAuth2 credentials for your Google project](https://developer
| GOOGLE_CLIENT_ID | The client ID from your Google OAuth2 credentials. | '' |
| GOOGLE_CLIENT_SECRET | The client secret from your Google OAuth2 credentials. | '' |
| GOOGLE_AUTO_REGISTER_NEW_USERS | Whether to automatically register a new user or provide them the Registration form | false |
| GOOGLE_DISPLAY_NAME | The text displayed on the Google OAuth2 login button | Google |
| GOOGLE_DISPLAY_NAME | The text displayed on the Google OAuth2 login button | Sign in with Google |

###### PingIdentity

Expand All @@ -110,7 +110,7 @@ Begin by [creating OAuth2 client in your PingIdentity console](https://docs.ping
| PINGIDENTITY_TOKEN_ENDPOINT | The URL fragment to the endpoint to ask for the Token | '/as/token.oauth2' |
| PINGIDENTITY_USER_ENDPOINT | The URL fragment to the endpoint to ask for the user's information with the token | '/idp/userinfo.openid' |
| PINGIDENTITY_AUTO_REGISTER_NEW_USERS | Whether to automatically register a new user or provide them the Registration form | false |
| PINGIDENTITY_DISPLAY_NAME | The text displayed on the PingIdentity OAuth2 login button | PingIdentity |
| PINGIDENTITY_DISPLAY_NAME | The text displayed on the PingIdentity OAuth2 login button | Sign in with PingIdentity |

## SAML2

Expand All @@ -122,6 +122,6 @@ Relevant `.env` variables for CDash SAML2 authentication:
| Variable | Description | Default |
| -------- |------------ | ------- |
| SAML2_ENABLED | Whether or not to use SAML2 authentication. | false |
| SAML2_LOGIN_TEXT | What text to display in the SAML2 login button. | SAML2 |
| SAML2_LOGIN_TEXT | What text to display in the SAML2 login button. | Sign in with SAML2 |
| SAML2_AUTO_REGISTER_NEW_USERS | Whether or not to automatically register new users upon first login. | false |
| SAML2_PROXY_VARS | Whether or not to trust the X-Forwarded-Proto HTTP header | false |
8 changes: 4 additions & 4 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -18574,19 +18574,19 @@ parameters:
path: app/cdash/tests/kwtest/kw_web_tester.php

-
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:832::__construct() has parameter $response with no type specified.'
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:833::__construct() has parameter $response with no type specified.'
identifier: missingType.parameter
count: 1
path: app/cdash/tests/kwtest/kw_web_tester.php

-
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:832::getSent() has no return type specified.'
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:833::getSent() has no return type specified.'
identifier: missingType.return
count: 1
path: app/cdash/tests/kwtest/kw_web_tester.php

-
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:832::read() has no return type specified.'
rawMessage: 'Method class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:833::read() has no return type specified.'
identifier: missingType.return
count: 1
path: app/cdash/tests/kwtest/kw_web_tester.php
Expand Down Expand Up @@ -18814,7 +18814,7 @@ parameters:
path: app/cdash/tests/kwtest/kw_web_tester.php

-
rawMessage: Property class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:832::$read has no type specified.
rawMessage: Property class@anonymous/app/cdash/tests/kwtest/kw_web_tester.php:833::$read has no type specified.
identifier: missingType.property
count: 1
path: app/cdash/tests/kwtest/kw_web_tester.php
Expand Down
148 changes: 65 additions & 83 deletions resources/views/auth/login.blade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
@php
$oauthCollection = collect(config('oauth2'));
$has_oauth2_login = $oauthCollection->firstWhere('enable', true);

$socialiteCollection = collect(config('services'))->where("oauth","true");
$has_socialite_login = $socialiteCollection->firstWhere('enable', true);
$oauthCollection = collect(config('services'))->where("oauth","true");
$has_oauth_login = $oauthCollection->firstWhere('enable', true);

$has_saml2_login = config('saml2.enabled');
$saml2_login_text = config('saml2.login_text');
Expand All @@ -13,92 +10,77 @@
$title = 'Login';
@endphp

@extends('cdash')
@extends('cdash', [
'vue' => true,
'daisyui' => true,
])

@section('main_content')
@includeIf('local.login')
<div id="message" style="color: green;"></div>
@if ($show_login_form)
<form method="POST" action="login" name="loginform" id="loginform">
<input type="hidden" name="_token" id="csrf-token" value="{{ csrf_token() }}" />
<div class="row table-heading">
<div class="col-1 ml-2 mt-1 mb-1 text-right">
{{ $login_field }}:
</div>
<div class="col-auto mt-1 mb-1">
<input class="textbox" name="email" size="40" value="{{ old('email') }}">
@if ($errors->has('email'))
<div>
<span class="invalid-feedback d-block" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
</div>
@endif
</div>
<div class="tw-flex tw-flex-row tw-w-full tw-justify-center tw-gap-8">
@if(View::exists('local.login'))
<div class="tw-max-w-xl">
@include('local.login')
</div>
<div class="row table-heading">
<div class="col-1 ml-2 mt-1 mb-1 text-right">
Password:
</div>
<div class="col-auto mt-1 mb-1">
<input class="textbox" type="password" name="password" size="20" autocomplete="off">
<input class="textbox" type="checkbox" name="remember" id="remember" {{old('remember') ? 'checked' : ''}}> Remember Me
@if ($errors->has('password'))
<div>
<span class="invalid-feedback d-block" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
</div>
@endif
</div>
</div>
<div class="row table-heading pb-2">
<div class="col-1 ml-2 mt-1 mb-1">
</div>
<div class="col-1 mt-1 mb-1 mr-auto">
<input type="submit" value="Login >>" name="sent" class="textbox">
</div>
<div class="col-auto text-right">
@if (Route::has('password.request'))
<a class="cdash-link" href="recoverPassword.php">Forgot your password?</a>
@endif
</div>
</div>
</form>
@endif <!-- $show_login_form -->

@if ($has_oauth2_login || $has_saml2_login || $has_socialite_login)
<div class="row table-heading border-top pt-2">
<div class="col-auto offset-1">
<p>
Sign in with:
@if ($has_saml2_login)
<form method="POST" action="/saml2/login" name="saml2_login_form" id="saml2_login_form">
<input type="hidden" name="_token" id="csrf-token" value="{{ csrf_token() }}" />
<button type="submit" class="btn btn-primary">
{{ $saml2_login_text }}
</button>
</form>
@endif
@foreach($socialiteCollection as $key => $config)
@if ($config['enable'])
<a class="cdash-link" href="/auth/{{ $key }}/redirect">
<button>
<img class="paddr" src="img/{{ $key }}_signin.png" title="Log in with your {{ $key }} account" style="height:40px"/>
{{ $config['display_name']}}
</button>
</a>
@endif
@endforeach
@foreach($oauthCollection as $key => $config)
@endif
<div class="tw-flex tw-flex-col tw-w-96 tw-gap-2">
@if ($show_login_form)
<form method="POST" action="{{ url('/login') }}" name="loginform" id="loginform">
@csrf
<div class="tw-w-full tw-flex tw-flex-row tw-justify-center">
<img src="{{ asset('img/cdash_logo_full.svg?rev=2023-05-31') }}" height="60" alt="CDash logo" style="height: 60px;">
</div>
<label class="tw-form-control tw-w-full">
<span class="tw-label tw-label-text">
{{ $login_field }}
</span>
<input type="text" name="email" value="{{ old('email') }}" class="tw-input tw-input-bordered tw-w-full" />
@if ($errors->has('email'))
<span class="tw-label-alt tw-text-error">
{{ $errors->first('email') }}
</span>
@endif
</label>
<label class="tw-form-control tw-w-full">
<span class="tw-label">
<span class="tw-label-text">
Password
</span>
<a href="{{ url('recoverPassword.php') }}" class="tw-label-text-alt tw-link tw-link-hover">
Forgot Password?
</a>
</span>
<input type="password" name="password" class="tw-input tw-input-bordered tw-w-full" />
@if ($errors->has('password'))
<span class="tw-label-alt tw-text-error">
{{ $errors->first('password') }}
</span>
@endif
</label>
<button class="tw-btn tw-btn-block tw-mt-2" type="submit">Sign In</button>
</form>
@endif
@if($show_login_form && ($has_saml2_login || $has_oauth_login))
<div class="tw-divider">OR</div>
@endif
@if($has_saml2_login)
<form method="POST" action="{{ url('/saml2/login') }}" name="saml2_login_form" id="saml2_login_form">
@csrf
<button type="submit" class="tw-btn tw-btn-block">
{{ $saml2_login_text }}
</button>
</form>
@endif
@if($has_oauth_login)
@foreach($oauthCollection as $provider => $config)
@if ($config['enable'])
<a class="cdash-link" href="/oauth/{{ $key }}">
<img class="paddr" src="img/{{ $key }}_signin.png" title="Log in with your {{ $key }} account"/>
<a class="tw-btn tw-btn-block" href="{{ url("/auth/$provider/redirect") }}">
<img src="img/{{ $provider }}_signin.png" alt="Log in with your {{ $provider }} account" style="height:40px"/>
{{ $config['display_name']}}
</a>
@endif
@endforeach
</p>
@endif
</div>
</div>
@endif
@endsection
3 changes: 2 additions & 1 deletion tests/Feature/CDashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ public function testOverrideLoginField(): void
URL::forceRootUrl('http://localhost');
Config::set('cdash.login_field', 'User');
$this->get('/login')
->assertSeeText('User:');
->assertSeeText('User')
->assertDontSeeText('Email');
}

public function testViewProjectsRedirectNoPublicProjects(): void
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/LoginAndRegistration.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function testCanViewLoginForm(): void
// Verify that the normal login form is shown by default.
$response = $this->get('/login');
$response->assertOk();
$response->assertSeeText('Email:');
$response->assertSeeText('Email');
}

public function testRegisterUser(): void
Expand Down