diff --git a/scm-ui/src/containers/App.js b/scm-ui/src/containers/App.js index 1e1387fd70..e788fc84d8 100644 --- a/scm-ui/src/containers/App.js +++ b/scm-ui/src/containers/App.js @@ -1,25 +1,13 @@ // @flow -import React, { Component } from "react"; +import React, {Component} from "react"; import Main from "./Main"; -import { connect } from "react-redux"; -import { translate } from "react-i18next"; -import { withRouter } from "react-router-dom"; -import { - fetchMe, - isAuthenticated, - getMe, - isFetchMePending, - getFetchMeFailure -} from "../modules/auth"; +import {connect} from "react-redux"; +import {translate} from "react-i18next"; +import {withRouter} from "react-router-dom"; +import {fetchMe, getFetchMeFailure, getMe, isAuthenticated, isFetchMePending} from "../modules/auth"; -import { - PrimaryNavigation, - Loading, - ErrorPage, - Footer, - Header -} from "@scm-manager/ui-components"; -import type { Links, Me } from "@scm-manager/ui-types"; +import {ErrorPage, Footer, Header, Loading, PrimaryNavigation} from "@scm-manager/ui-components"; +import type {Links, Me} from "@scm-manager/ui-types"; import { getFetchIndexResourcesFailure, getLinks, @@ -50,23 +38,10 @@ class App extends Component { } render() { - const { - me, - loading, - error, - authenticated, - links, - t - } = this.props; + const {me, loading, error, authenticated, links, t} = this.props; let content; - const navigation = authenticated ? ( - - ) : ( - "" - ); + const navigation = authenticated ? : ""; if (loading) { content = ; @@ -85,7 +60,7 @@ class App extends Component {
{navigation}
{content} -
+ {authenticated &&
}
); } diff --git a/scm-ui/src/containers/Login.js b/scm-ui/src/containers/Login.js index f8246ab88b..b8c5b5ae9c 100644 --- a/scm-ui/src/containers/Login.js +++ b/scm-ui/src/containers/Login.js @@ -2,13 +2,13 @@ import React from "react"; import { Redirect, withRouter } from "react-router-dom"; import { - login, + getLoginFailure, isAuthenticated, isLoginPending, - getLoginFailure + login } from "../modules/auth"; import { connect } from "react-redux"; -import { getLoginLink, getLoginInfoLink } from "../modules/indexResource"; +import { getLoginInfoLink, getLoginLink } from "../modules/indexResource"; import LoginInfo from "../components/LoginInfo"; import classNames from "classnames"; import injectSheet from "react-jss"; @@ -37,7 +37,6 @@ type Props = { }; class Login extends React.Component { - handleLogin = (username: string, password: string): void => { const { link, login } = this.props; login(link, username, password); @@ -45,7 +44,7 @@ class Login extends React.Component { renderRedirect = () => { const { from } = this.props.location.state || { from: { pathname: "/" } }; - return ; + return ; }; render() { @@ -56,7 +55,7 @@ class Login extends React.Component { } return ( -
+
@@ -65,7 +64,7 @@ class Login extends React.Component {
- ); + ); } } diff --git a/scm-ui/src/modules/auth.js b/scm-ui/src/modules/auth.js index fdc3c83c7f..02b7b2396a 100644 --- a/scm-ui/src/modules/auth.js +++ b/scm-ui/src/modules/auth.js @@ -1,15 +1,16 @@ // @flow -import type { Me } from "@scm-manager/ui-types"; +import type {Me} from "@scm-manager/ui-types"; import * as types from "./types"; -import { apiClient, UnauthorizedError } from "@scm-manager/ui-components"; -import { isPending } from "./pending"; -import { getFailure } from "./failure"; +import {apiClient, UnauthorizedError} from "@scm-manager/ui-components"; +import {isPending} from "./pending"; +import {getFailure} from "./failure"; import { callFetchIndexResources, fetchIndexResources, fetchIndexResourcesPending, - fetchIndexResourcesSuccess + fetchIndexResourcesSuccess, + getLoginLink } from "./indexResource"; // Action @@ -44,13 +45,11 @@ export default function reducer( case FETCH_ME_SUCCESS: return { ...state, - me: action.payload, - authenticated: true + me: action.payload }; case FETCH_ME_UNAUTHORIZED: return { - me: {}, - authenticated: false + me: {} }; case LOGOUT_SUCCESS: return initialState; @@ -240,7 +239,7 @@ const stateAuth = (state: Object): Object => { }; export const isAuthenticated = (state: Object) => { - if (stateAuth(state).authenticated) { + if (state.auth.me && !getLoginLink(state)) { return true; } return false; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java index b54c831662..70cdb93f33 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/IndexDtoGenerator.java @@ -6,12 +6,12 @@ import de.otto.edison.hal.Embedded; import de.otto.edison.hal.Link; import de.otto.edison.hal.Links; import org.apache.shiro.SecurityUtils; +import sonia.scm.SCMContext; import sonia.scm.SCMContextProvider; import sonia.scm.config.ConfigurationPermissions; import sonia.scm.config.ScmConfiguration; import sonia.scm.group.GroupPermissions; import sonia.scm.plugin.PluginPermissions; -import sonia.scm.repository.RepositoryRolePermissions; import sonia.scm.security.PermissionPermissions; import sonia.scm.user.UserPermissions; @@ -50,6 +50,11 @@ public class IndexDtoGenerator extends HalAppenderMapper { link("me", resourceLinks.me().self()), link("logout", resourceLinks.authentication().logout()) ); + + if (SecurityUtils.getSubject().getPrincipal().equals(SCMContext.USER_ANONYMOUS)) { + builder.single(link("login", resourceLinks.authentication().jsonLogin())); + } + if (PluginPermissions.read().isPermitted()) { builder.single(link("installedPlugins", resourceLinks.installedPluginCollection().self())); builder.single(link("availablePlugins", resourceLinks.availablePluginCollection().self()));