FOSSology  4.4.0
Open Source License Compliance by Open Source Software
HomePage.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2016, 2021 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 namespace Fossology\UI\Page;
9 
10 use Firebase\JWT\JWT;
13 use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
14 use League\OAuth2\Client\Provider\GenericProvider;
15 use League\OAuth2\Client\Token\AccessToken;
16 use League\OAuth2\Client\Token\AccessTokenInterface;
17 use Symfony\Component\HttpFoundation\Request;
18 use Symfony\Component\HttpFoundation\Response;
19 
23 class HomePage extends DefaultPlugin
24 {
25  const NAME = "home";
26 
27  function __construct()
28  {
29  parent::__construct(self::NAME, array(
30  self::TITLE => _("Getting Started with FOSSology"),
31  self::REQUIRES_LOGIN => false,
32  self::MENU_LIST => "Home",
33  self::MENU_ORDER => 100
34  ));
35  }
36 
41  protected function handle(Request $request)
42  {
43  global $SysConf;
44 
45  $vars = array('isSecure' => $request->isSecure());
46  $vars['loginProvider'] = "password";
47  if (array_key_exists('AUTHENTICATION', $SysConf) &&
48  array_key_exists('provider', $SysConf['AUTHENTICATION'])) {
49  $vars['loginProvider'] = $SysConf['AUTHENTICATION']['provider'];
50  }
51  if (array_key_exists('User', $_SESSION) && $_SESSION['User'] ==
52  "Default User" && plugin_find_id("auth") >= 0) {
53  if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "off") {
54  $vars['protocol'] = "HTTPS";
55  } else {
56  $vars['protocol'] = preg_replace("@/.*@", "",
57  @$_SERVER['SERVER_PROTOCOL']);
58  }
59 
60  $vars['referrer'] = "?mod=browse";
61  $vars['authUrl'] = "?mod=auth";
62  }
63  $vars['getEmail'] = "";
64  $vars['getOauth'] = false;
65 
66  $email = null;
67  if (! empty(GetParm("code", PARM_TEXT))) {
68  try {
69  $email = $this->getEmailFromOAuth();
70  } catch (IdentityProviderException $e) {
71  $vars['message'] = $e->getMessage();
72  } catch (\UnexpectedValueException $e) {
73  $vars['message'] = $e->getMessage();
74  }
75  }
76  if (! empty(GetParm("error", PARM_TEXT))) {
77  $vars['message'] = GetParm("error_description", PARM_TEXT);
78  }
79 
80  if ($email !== null) {
81  $_SESSION['oauthemail'] = $email;
82  $vars['getOauth'] = true;
83  if (array_key_exists('HTTP_REFERER', $_SESSION)) {
84  $vars['referrer'] = $_SESSION['HTTP_REFERER'];
85  }
86  }
87 
88  if (!empty($SysConf['SYSCONFIG']['OidcAppName'])) {
89  $vars['providerExist'] = $SysConf['SYSCONFIG']['OidcAppName'];
90  } else {
91  $vars['providerExist'] = 0;
92  }
93  return $this->render("home.html.twig", $this->mergeWithDefault($vars));
94  }
95 
105  private function getEmailFromOAuth()
106  {
107  global $SysConf;
108  if (empty(GetParm("state", PARM_TEXT)) ||
109  (isset($_SESSION['oauth2state']) &&
110  GetParm("state", PARM_TEXT) !== $_SESSION['oauth2state'])) {
111  // Check given state against previously stored one to mitigate CSRF attack
112  if (isset($_SESSION['oauth2state'])) {
113  unset($_SESSION['oauth2state']);
114  }
115  throw new \UnexpectedValueException('Invalid state');
116  }
117  $proxy = "";
118  if (array_key_exists('http_proxy', $SysConf['FOSSOLOGY']) &&
119  ! empty($SysConf['FOSSOLOGY']['http_proxy'])) {
120  $proxy = $SysConf['FOSSOLOGY']['http_proxy'];
121  }
122  if (array_key_exists('https_proxy', $SysConf['FOSSOLOGY']) &&
123  ! empty($SysConf['FOSSOLOGY']['https_proxy'])) {
124  $proxy = $SysConf['FOSSOLOGY']['https_proxy'];
125  }
126 
127  $provider = new GenericProvider([
128  "clientId" => $SysConf['SYSCONFIG']['OidcAppId'],
129  "clientSecret" => $SysConf['SYSCONFIG']['OidcSecret'],
130  "redirectUri" => $SysConf['SYSCONFIG']['OidcRedirectURL'],
131  "urlAuthorize" => $SysConf['SYSCONFIG']['OidcAuthorizeURL'],
132  "urlAccessToken" => $SysConf['SYSCONFIG']['OidcAccessTokenURL'],
133  "urlResourceOwnerDetails" => $SysConf['SYSCONFIG']['OidcResourceURL'],
134  "responseResourceOwnerId" => $SysConf['SYSCONFIG']['OidcResourceOwnerId'],
135  "proxy" => $proxy
136  ]);
137  $accessToken = $provider->getAccessToken('authorization_code',
138  ['code' => GetParm("code", PARM_TEXT)]);
139 
140  $this->validateAccessToken($accessToken);
141 
142  return $this->getEmailFromResource($provider, $accessToken);
143  }
144 
153  private function validateAccessToken($accessToken)
154  {
155  global $SysConf;
160  $authHelper = $this->container->get('helper.authHelper');
161  $jwks = $authHelper::loadJwks();
162  $jwtToken = null;
163  if ($SysConf['SYSCONFIG']['OidcTokenType'] === "A") {
164  $jwtToken = $accessToken->getToken();
165  } elseif ($SysConf['SYSCONFIG']['OidcTokenType'] === "I") {
166  $jwtToken = $accessToken->getValues()['id_token'];
167  }
168  if (empty($jwtToken)) {
169  throw new \UnexpectedValueException("Unable to get identity from OIDC token. " .
170  "Please check 'Token to use from provider' field in config.");
171  }
172  try {
173  $jwtTokenDecoded = JWT::decode(
174  $jwtToken,
175  $jwks
176  );
177  } catch (\Exception $e) {
178  throw new \UnexpectedValueException("JWKS: " . $e->getMessage());
179  }
180  if (property_exists($jwtTokenDecoded, 'iss') &&
181  $jwtTokenDecoded->{'iss'} == $SysConf['SYSCONFIG']['OidcIssuer']) {
182  return true;
183  }
184  throw new \UnexpectedValueException("Invalid issuer of token.");
185  }
186 
194  private function getEmailFromResource($provider, $accessToken)
195  {
196  $resourceOwner = $provider->getResourceOwner($accessToken);
197  if (!empty($resourceOwner->getId())) {
198  return $resourceOwner->getId();
199  }
200  return null;
201  }
202 }
203 
204 register_plugin(new HomePage());
render($templateName, $vars=null, $headers=null)
Provides helper methods for REST api.
Definition: AuthHelper.php:38
about page on UI
Definition: HomePage.php:24
getEmailFromResource($provider, $accessToken)
Definition: HomePage.php:194
handle(Request $request)
Definition: HomePage.php:41
const PARM_TEXT
Definition: common-parm.php:20
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:46