Use new providerItem.

This commit is contained in:
Yang Luo 2021-06-14 21:35:19 +08:00
parent 9fe310f2b7
commit 5a852bfd1d
10 changed files with 132 additions and 82 deletions

View File

@ -179,6 +179,7 @@ func (c *ApiController) Login() {
} else if form.Provider != "" {
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
provider := object.GetProvider(fmt.Sprintf("admin/%s", form.Provider))
providerItem := application.GetProviderItem(provider.Name)
idProvider := idp.GetIdProvider(provider.Type, provider.ClientId, provider.ClientSecret, form.RedirectUri)
if idProvider == nil {
@ -231,6 +232,8 @@ func (c *ApiController) Login() {
}
if user != nil {
// Sign in via OAuth
//if object.IsForbidden(userId) {
// c.forbiddenAccountResp(userId)
// return
@ -243,50 +246,53 @@ func (c *ApiController) Login() {
resp = c.HandleLoggedIn(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)
//}
// sign up via OAuth
properties := map[string]string{}
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
if provider.EnableSignUp {
user := &object.User{
Owner: application.Organization,
Name: userInfo.Username,
CreatedTime: util.GetCurrentTime(),
Id: util.GenerateId(),
Type: "normal-user",
DisplayName: userInfo.DisplayName,
Avatar: userInfo.AvatarUrl,
Email: userInfo.Email,
Score: 200,
IsAdmin: false,
IsGlobalAdmin: false,
IsForbidden: false,
Properties: properties,
}
object.AddUser(user)
// sync info from 3rd-party if possible
object.SetUserOAuthProperties(user, provider.Type, userInfo)
object.LinkUserAccount(user, provider.Type, userInfo.Id)
resp = c.HandleLoggedIn(user, &form)
} else if !application.EnableSignUp {
resp = &Response{Status: "error", Msg: fmt.Sprintf("The account for provider: %s and username: %s does not exist and is not allowed to sign up as new account, please contact your IT support", provider.Type, userInfo.Username)}
c.Data["json"] = resp
c.ServeJSON()
return
} else {
resp = &Response{Status: "error", Msg: fmt.Sprintf("The account for provider: %s and username: %s does not exist, please create an account first", provider.Type, userInfo.Username)}
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
c.ServeJSON()
return
}
if !providerItem.CanSignUp {
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 via %s, please use another way to sign up", provider.Type, userInfo.Username, userInfo.DisplayName, provider.Type)}
c.Data["json"] = resp
c.ServeJSON()
return
}
properties := map[string]string{}
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
user := &object.User{
Owner: application.Organization,
Name: userInfo.Username,
CreatedTime: util.GetCurrentTime(),
Id: util.GenerateId(),
Type: "normal-user",
DisplayName: userInfo.DisplayName,
Avatar: userInfo.AvatarUrl,
Email: userInfo.Email,
Score: 200,
IsAdmin: false,
IsGlobalAdmin: false,
IsForbidden: false,
Properties: properties,
}
object.AddUser(user)
// sync info from 3rd-party if possible
object.SetUserOAuthProperties(user, provider.Type, userInfo)
object.LinkUserAccount(user, provider.Type, userInfo.Id)
resp = c.HandleLoggedIn(user, &form)
}
//resp = &Response{Status: "ok", Msg: "", Data: res}
} else { // form.Method != "signup"

View File

@ -24,16 +24,15 @@ type Application struct {
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
DisplayName string `xorm:"varchar(100)" json:"displayName"`
Logo string `xorm:"varchar(100)" json:"logo"`
HomepageUrl string `xorm:"varchar(100)" json:"homepageUrl"`
Description string `xorm:"varchar(100)" json:"description"`
Organization string `xorm:"varchar(100)" json:"organization"`
EnablePassword bool `json:"enablePassword"`
EnableSignUp bool `json:"enableSignUp"`
Providers []ProviderItem `xorm:"varchar(1000)" json:"providers"`
ProviderObjs []*Provider `xorm:"-" json:"providerObjs"`
OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
DisplayName string `xorm:"varchar(100)" json:"displayName"`
Logo string `xorm:"varchar(100)" json:"logo"`
HomepageUrl string `xorm:"varchar(100)" json:"homepageUrl"`
Description string `xorm:"varchar(100)" json:"description"`
Organization string `xorm:"varchar(100)" json:"organization"`
EnablePassword bool `json:"enablePassword"`
EnableSignUp bool `json:"enableSignUp"`
Providers []*ProviderItem `xorm:"varchar(1000)" json:"providers"`
OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
@ -54,8 +53,17 @@ func GetApplications(owner string) []*Application {
return applications
}
func extendApplicationWithProviders(application *Application) {
providers := GetProviders(application.Owner)
func (application *Application) GetProviderItem(providerName string) *ProviderItem {
for _, providerItem := range application.Providers {
if providerItem.Name == providerName {
return providerItem
}
}
return nil
}
func getProviderMap(owner string) map[string]*Provider {
providers := GetProviders(owner)
m := map[string]*Provider{}
for _, provider := range providers {
if provider.Category != "OAuth" {
@ -66,11 +74,14 @@ func extendApplicationWithProviders(application *Application) {
provider.ProviderUrl = ""
m[provider.Name] = provider
}
return m
}
application.ProviderObjs = []*Provider{}
func extendApplicationWithProviders(application *Application) {
m := getProviderMap(application.Owner)
for _, providerItem := range application.Providers {
if provider, ok := m[providerItem.Name]; ok {
application.ProviderObjs = append(application.ProviderObjs, provider)
providerItem.Provider = provider
}
}
}
@ -143,6 +154,10 @@ func UpdateApplication(id string, application *Application) bool {
return false
}
for _, providerItem := range application.Providers {
providerItem.Provider = nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(application)
if err != nil {
panic(err)
@ -154,6 +169,9 @@ func UpdateApplication(id string, application *Application) bool {
func AddApplication(application *Application) bool {
application.ClientId = util.GenerateClientId()
application.ClientSecret = util.GenerateClientSecret()
for _, providerItem := range application.Providers {
providerItem.Provider = nil
}
affected, err := adapter.Engine.Insert(application)
if err != nil {

View File

@ -66,7 +66,7 @@ func initBuiltInApplication() {
Organization: "built-in",
EnablePassword: true,
EnableSignUp: true,
Providers: []ProviderItem{},
Providers: []*ProviderItem{},
RedirectUris: []string{},
ExpireInHours: 168,
}

View File

@ -20,10 +20,12 @@ import (
)
type ProviderItem struct {
Name string `json:"name"`
CanSignUp bool `json:"canSignUp"`
CanSignIn bool `json:"canSignIn"`
CanUnbind bool `json:"canUnbind"`
Name string `json:"name"`
CanSignUp bool `json:"canSignUp"`
CanSignIn bool `json:"canSignIn"`
CanUnbind bool `json:"canUnbind"`
AlertType string `json:"alertType"`
Provider *Provider `json:"provider"`
}
type Provider struct {
@ -36,7 +38,6 @@ type Provider struct {
Type string `xorm:"varchar(100)" json:"type"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
EnableSignUp bool `json:"enableSignUp"`
Host string `xorm:"varchar(100)" json:"host"`
Port int `json:"port"`

View File

@ -162,15 +162,15 @@ class ApplicationListPage extends React.Component {
<List
size="small"
dataSource={providers}
renderItem={(row, i) => {
renderItem={(providerItem, i) => {
return (
<List.Item>
<div style={{display: "inline"}}>
<Tooltip placement="topLeft" title="Edit">
<Button style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={() => Setting.goToLinkSoft(this, `/providers/${row}`)} />
<Button style={{marginRight: "5px"}} icon={<EditOutlined />} size="small" onClick={() => Setting.goToLinkSoft(this, `/providers/${providerItem.name}`)} />
</Tooltip>
<Link to={`/providers/${row}`}>
{row}
<Link to={`/providers/${providerItem.name}`}>
{providerItem.name}
</Link>
</div>
</List.Item>

View File

@ -179,16 +179,6 @@ class ProviderEditPage extends React.Component {
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={2}>
{i18next.t("application:Enable signup")}:
</Col>
<Col span={1} >
<Switch checked={this.state.provider.enableSignUp} onChange={checked => {
this.updateProviderField('enableSignUp', checked);
}} />
</Col>
</Row>
{
this.state.provider.category === "Email" ? (
<React.Fragment>

View File

@ -38,7 +38,7 @@ class ProviderTable extends React.Component {
}
addRow(table) {
let row = {name: "", canSignUp: false, canSignIn: true, canUnbind: true};
let row = {name: "Please select a provider", canSignUp: false, canSignIn: true, canUnbind: true, alertType: "None"};
if (table === undefined) {
table = [];
}
@ -73,9 +73,11 @@ class ProviderTable extends React.Component {
value={text}
onChange={value => {
this.updateField(table, index, 'name', value);
const provider = this.props.providers.filter(provider => provider.name === value)[0];
this.updateField(table, index, 'provider', provider);
}} >
{
this.props.providers.map((provider, index) => <Option key={index} value={provider.name}>{provider.name}</Option>)
this.props.providers.filter(provider => table.filter(providerItem => providerItem.name === provider.name).length === 0).map((provider, index) => <Option key={index} value={provider.name}>{provider.name}</Option>)
}
</Select>
)
@ -125,6 +127,27 @@ class ProviderTable extends React.Component {
)
}
},
{
title: i18next.t("provider:alertType"),
dataIndex: 'alertType',
key: 'alertType',
width: '120px',
render: (text, record, index) => {
return (
<Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
this.updateField(table, index, 'alertType', value);
})}>
{
[
{id: 'None', name: 'None'},
{id: 'Once', name: 'Once'},
{id: 'Always', name: 'Always'},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
)
}
},
{
title: i18next.t("general:Action"),
key: 'action',

View File

@ -38,24 +38,36 @@ function isLocalhost() {
return hostname === "localhost";
}
export function isProviderVisible(provider) {
if (provider.type !== "GitHub") {
export function isProviderVisible(providerItem) {
if (providerItem.provider === undefined || providerItem.provider === null) {
return false;
}
if (providerItem.provider.type !== "GitHub") {
return true;
}
if (isLocalhost()) {
return provider.name.includes("localhost");
return providerItem.provider.name.includes("localhost");
} else {
return !provider.name.includes("localhost");
return !providerItem.provider.name.includes("localhost");
}
}
export function isProviderVisibleForSignUp(provider) {
if (provider.enableSignUp === false) {
export function isProviderVisibleForSignUp(providerItem) {
if (providerItem.canSignUp === false) {
return false;
}
return isProviderVisible(provider);
return isProviderVisible(providerItem);
}
export function isProviderVisibleForSignIn(providerItem) {
if (providerItem.canSignIn === false) {
return false;
}
return isProviderVisible(providerItem);
}
export function parseJson(s) {

View File

@ -344,7 +344,7 @@ class UserEditPage extends React.Component {
<Col span={22} >
<div style={{marginBottom: 20}}>
{
this.state.application?.providerObjs.filter(provider => Setting.isProviderVisible(provider)).map((provider, index) => this.renderIdp(provider))
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem, index) => this.renderIdp(providerItem.provider))
}
</div>
</Col>

View File

@ -224,8 +224,8 @@ class LoginPage extends React.Component {
</Form.Item>
<Form.Item>
{
application.providerObjs.filter(provider => Setting.isProviderVisibleForSignUp(provider)).map(provider => {
return this.renderProviderLogo(provider, application, 30, 5, "small");
application.providers.filter(providerItem => Setting.isProviderVisibleForSignIn(providerItem)).map(providerItem => {
return this.renderProviderLogo(providerItem.provider, application, 30, 5, "small");
})
}
</Form.Item>
@ -245,8 +245,8 @@ class LoginPage extends React.Component {
</div>
<br/>
{
application.providerObjs.filter(provider => Setting.isProviderVisibleForSignUp(provider)).map(provider => {
return this.renderProviderLogo(provider, application, 40, 10, "big");
application.providers.filter(providerItem => Setting.isProviderVisibleForSignIn(providerItem)).map(providerItem => {
return this.renderProviderLogo(providerItem.provider, application, 40, 10, "big");
})
}
{