Login page can also enter prompt page.

This commit is contained in:
Yang Luo
2021-06-20 22:17:03 +08:00
parent a43db3e55a
commit b189993547
5 changed files with 101 additions and 52 deletions

View File

@ -34,7 +34,7 @@ func codeToResponse(code *object.Code) *Response {
}
}
func (c *ApiController) HandleLoggedIn(user *object.User, form *RequestForm) *Response {
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) *Response {
userId := user.GetId()
resp := &Response{}
if form.Type == ResponseTypeLogin {
@ -50,6 +50,11 @@ func (c *ApiController) HandleLoggedIn(user *object.User, form *RequestForm) *Re
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state)
resp = codeToResponse(code)
if application.HasPromptPage() {
// The prompt page needs the user to be signed in
c.SetSessionUser(userId)
}
} else {
resp = &Response{Status: "error", Msg: fmt.Sprintf("Unknown response type: %s", form.Type)}
}
@ -174,7 +179,8 @@ func (c *ApiController) Login() {
if msg != "" {
resp = &Response{Status: "error", Msg: msg, Data: ""}
} else {
resp = c.HandleLoggedIn(user, &form)
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
resp = c.HandleLoggedIn(application, user, &form)
}
} else if form.Provider != "" {
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
@ -244,16 +250,9 @@ func (c *ApiController) Login() {
// object.LinkMemberAccount(userId, "avatar", avatar)
//}
resp = c.HandleLoggedIn(user, &form)
resp = c.HandleLoggedIn(application, user, &form)
} else {
// Sign up via OAuth
//if userId := object.GetUserIdByField(application, "email", userInfo.Email); userId != "" {
// resp = c.HandleLoggedIn(userId, &form)
//
// object.LinkUserAccount(userId, provider.Type, userInfo.Id)
//}
if !application.EnableSignUp {
resp = &Response{Status: "error", Msg: fmt.Sprintf("The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support", provider.Type, userInfo.Username, userInfo.DisplayName)}
c.Data["json"] = resp
@ -292,7 +291,7 @@ func (c *ApiController) Login() {
object.LinkUserAccount(user, provider.Type, userInfo.Id)
resp = c.HandleLoggedIn(user, &form)
resp = c.HandleLoggedIn(application, user, &form)
}
//resp = &Response{Status: "ok", Msg: "", Data: res}
} else { // form.Method != "signup"

View File

@ -430,8 +430,8 @@ class App extends Component {
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} />)}/>
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />)}/>
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage {...props} />)}/>
<Route exact path="/signup/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signup"} {...props} />}/>
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signin"} {...props} />}/>
<Route exact path="/signup/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
<Route exact path="/callback" component={AuthCallback}/>
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)}/>
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)}/>

View File

@ -108,6 +108,41 @@ export function hasPromptPage(application) {
return isAffiliationPrompted(application);
}
function isAffiliationAnswered(user, application) {
if (!isAffiliationPrompted(application)) {
return true;
}
if (user === null) {
return false;
}
return user.affiliation !== "";
}
function isProviderItemAnswered(user, application, providerItem) {
if (user === null) {
return false;
}
const provider = providerItem.provider;
const linkedValue = user[provider.type.toLowerCase()];
return linkedValue !== undefined && linkedValue !== "";
}
export function isPromptAnswered(user, application) {
if (!isAffiliationAnswered(user, application)) {
return false;
}
const providerItems = getAllPromptedProviderItems(application);
for (let i = 0; i < providerItems.length; i ++) {
if (!isProviderItemAnswered(user, application, providerItems[i])) {
return false;
}
}
return true;
}
export function parseJson(s) {
if (s === "") {
return null;

View File

@ -92,9 +92,16 @@ class LoginPage extends React.Component {
}
}
onUpdateAccount(account) {
this.props.onUpdateAccount(account);
}
onFinish(values) {
const application = this.getApplicationObj();
const ths = this;
values["type"] = this.state.type;
const oAuthParams = Util.getOAuthGetParameters();
AuthBackend.login(values, oAuthParams)
.then((res) => {
if (res.status === 'ok') {
@ -104,7 +111,32 @@ class LoginPage extends React.Component {
Setting.goToLink("/");
} else if (responseType === "code") {
const code = res.data;
if (Setting.hasPromptPage(application)) {
AuthBackend.getAccount("")
.then((res) => {
let account = null;
if (res.status === "ok") {
account = res.data;
account.organization = res.data2;
this.onUpdateAccount(account);
if (Setting.isPromptAnswered(account, application)) {
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
} else {
Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`);
}
} else {
if (res.msg !== "Please sign in first") {
Setting.showMessage("error", `Failed to sign in: ${res.msg}`);
}
}
});
} else {
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
}
// Util.showMessage("success", `Authorization code: ${res.data}`);
}
} else {
@ -195,9 +227,10 @@ class LoginPage extends React.Component {
name="normal_login"
initialValues={{
organization: application.organization,
application: application.name,
remember: true
}}
onFinish={this.onFinish.bind(this)}
onFinish={(values) => {this.onFinish(values)}}
style={{width: "250px"}}
size="large"
>

View File

@ -126,52 +126,34 @@ class PromptPage extends React.Component {
)
}
isProviderItemAnswered(application, providerItem) {
if (this.state.user === null) {
return false;
}
const provider = providerItem.provider;
const linkedValue = this.state.user[provider.type.toLowerCase()];
return linkedValue !== undefined && linkedValue !== "";
}
isAffiliationAnswered(application) {
if (!Setting.isAffiliationPrompted(application)) {
return true;
}
if (this.state.user === null) {
return false;
}
return this.state.user.affiliation !== "";
}
isAnswered(application) {
if (!this.isAffiliationAnswered(application)) {
return false;
}
const providerItems = Setting.getAllPromptedProviderItems(application);
for (let i = 0; i < providerItems.length; i ++) {
if (!this.isProviderItemAnswered(application, providerItems[i])) {
return false;
}
}
return true;
}
onUpdateAccount(account) {
this.props.onUpdateAccount(account);
}
getRedirectUrl() {
// "/prompt/app-example?redirectUri=http://localhost:2000/callback&code=8eb113b072296818f090&state=app-example"
const params = new URLSearchParams(this.props.location.search);
const redirectUri = params.get("redirectUri");
const code = params.get("code");
const state = params.get("state");
if (redirectUri === null || code === null || state === null) {
return "";
}
return `${redirectUri}?code=${code}&state=${state}`;
}
logout() {
AuthBackend.logout()
.then((res) => {
if (res.status === 'ok') {
this.onUpdateAccount(null);
const redirectUrl = this.getRedirectUrl();
if (redirectUrl !== "") {
Setting.goToLink(redirectUrl);
} else {
Setting.goToLogin(this, this.getApplicationObj());
}
} else {
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
}
@ -245,7 +227,7 @@ class PromptPage extends React.Component {
</Col>
</Row>
<div style={{marginTop: "50px"}}>
<Button disabled={!this.isAnswered(application)} type="primary" size="large" onClick={() => {this.submitUserEdit(true)}}>{i18next.t("signup:Submit and complete")}</Button>
<Button disabled={!Setting.isPromptAnswered(this.state.user, application)} type="primary" size="large" onClick={() => {this.submitUserEdit(true)}}>{i18next.t("signup:Submit and complete")}</Button>
</div>
</div>
</Col>