Parse subOwner, subName.

This commit is contained in:
Yang Luo 2021-02-28 23:14:48 +08:00
parent ba4185c9b1
commit f3f902af45
3 changed files with 70 additions and 31 deletions

View File

@ -34,10 +34,10 @@ func InitAuthz() {
modelText := `
[request_definition]
r = userId, method, urlPath, objOwner, objName
r = subOwner, subName, method, urlPath, objOwner, objName
[policy_definition]
p = userId, method, urlPath, objOwner
p = subOwner, subName, method, urlPath, objOwner, objName
[role_definition]
g = _, _
@ -46,7 +46,9 @@ g = _, _
e = some(where (p.eft == allow))
[matchers]
m = r.method == "GET" || r.userId == r.objOwner
m = (r.subOwner == p.subOwner || p.subOwner == "*") && (r.subName == p.subName || p.subName == "*") && \
(r.method == p.method || p.method == "*") && (r.urlPath == p.urlPath || p.urlPath == "*") && \
(r.objOwner == p.objOwner || p.objOwner == "*") && (r.objName == p.objName || p.objName == "*")
`
m, err := model.NewModelFromString(modelText)
@ -59,9 +61,17 @@ m = r.method == "GET" || r.userId == r.objOwner
panic(err)
}
if len(Enforcer.GetPolicy()) == 0 {
//if len(Enforcer.GetPolicy()) == 0 {
if true {
ruleText := `
p, 1, 2, 3, 4
p, built-in, *, *, *, *, *
p, *, *, POST, /api/register, *, *
p, *, *, POST, /api/login, *, *
p, *, *, POST, /api/logout, *, *
p, *, *, GET, /api/get-account, *, *
p, *, *, GET, /api/auth/login, *, *
p, *, *, GET, /api/get-application, *, *
p, *, *, GET, /api/get-users, *, *
`
sa := stringadapter.NewAdapter(ruleText)
@ -81,8 +91,8 @@ p, 1, 2, 3, 4
}
}
func IsAllowed(userId string, method string, urlPath string, objOwner string, objName string) bool {
res, err := Enforcer.Enforce(userId, method, urlPath, objOwner, objName)
func IsAllowed(subOwner string, subName string, method string, urlPath string, objOwner string, objName string) bool {
res, err := Enforcer.Enforce(subOwner, subName, method, urlPath, objOwner, objName)
if err != nil {
panic(err)
}

View File

@ -29,24 +29,43 @@ type Object struct {
Name string `json:"name"`
}
func getUserId(ctx *context.Context) string {
username := ctx.Input.Session("username")
userId := strings.TrimLeft(username.(string), "/")
if userId == "" {
userId = "anonymous"
func getUsername(ctx *context.Context) (username string) {
defer func() {
if r := recover(); r != nil {
username = ""
}
}()
// bug in Beego: this call will panic when file session store is empty
// so we catch the panic
username = ctx.Input.Session("username").(string)
return
}
func getSubject(ctx *context.Context) (string, string) {
username := getUsername(ctx)
if username == "" {
return "anonymous", "anonymous"
}
return userId
// username == "built-in/admin"
tokens := strings.Split(username, "/")
owner := tokens[0]
name := tokens[1]
return owner, name
}
func getObject(ctx *context.Context) (string, string) {
method := ctx.Request.Method
if method == http.MethodGet {
// query = "id=built-in/admin"
query := ctx.Request.URL.RawQuery
if query == "" {
// query == "owner=admin"
if query == "" || strings.Contains(query, "=") {
return "", ""
}
// query == "id=built-in/admin"
query = strings.TrimLeft(query, "id=")
tokens := strings.Split(query, "/")
owner := tokens[0]
@ -78,16 +97,16 @@ func denyRequest(ctx *context.Context) {
}
func AuthzFilter(ctx *context.Context) {
userId := getUserId(ctx)
subOwner, subName := getSubject(ctx)
method := ctx.Request.Method
urlPath := ctx.Request.URL.Path
objOwner, objName := getObject(ctx)
isAllowed := authz.IsAllowed(userId, method, urlPath, objOwner, objName)
isAllowed := authz.IsAllowed(subOwner, subName, method, urlPath, objOwner, objName)
fmt.Printf("userId = %s, method = %s, urlPath = %s, obj.Owner = %s, obj.Name = %s, isAllowed = %v\n",
userId, method, urlPath, objOwner, objName, isAllowed)
//if !isAllowed {
// denyRequest(ctx)
//}
fmt.Printf("subOwner = %s, subName = %s, method = %s, urlPath = %s, obj.Owner = %s, obj.Name = %s, isAllowed = %v\n",
subOwner, subName, method, urlPath, objOwner, objName, isAllowed)
if !isAllowed {
denyRequest(ctx)
}
}

View File

@ -67,18 +67,28 @@ class Face extends React.Component {
});
};
renderForm() {
renderForm(application) {
return (
<Form
name="normal_login"
initialValues={{
organization: this.getApplicationObj().organization,
organization: application.organization,
remember: true
}}
onFinish={this.onFinish.bind(this)}
style={{width: "250px"}}
size="large"
>
<Form.Item style={{height: 0, visibility: "hidden"}}
name="organization"
rules={[{ required: true, message: 'Please input your organization!' }]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="organization"
disabled={!application.enablePassword}
/>
</Form.Item>
<Form.Item
name="username"
rules={[{ required: true, message: 'Please input your Username!' }]}
@ -86,7 +96,7 @@ class Face extends React.Component {
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="username"
disabled={!this.getApplicationObj().enablePassword}
disabled={!application.enablePassword}
/>
</Form.Item>
<Form.Item
@ -97,12 +107,12 @@ class Face extends React.Component {
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="password"
disabled={!this.getApplicationObj().enablePassword}
disabled={!application.enablePassword}
/>
</Form.Item>
<Form.Item>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox style={{float: "left"}} disabled={!this.getApplicationObj().enablePassword}>
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
Auto login
</Checkbox>
</Form.Item>
@ -116,7 +126,7 @@ class Face extends React.Component {
type="primary"
htmlType="submit"
style={{width: "100%"}}
disabled={!this.getApplicationObj().enablePassword}
disabled={!application.enablePassword}
>
Login
</Button>
@ -126,9 +136,9 @@ class Face extends React.Component {
</Form.Item>
<Form.Item>
{
this.getApplicationObj().providerObjs.map(provider => {
application.providerObjs.map(provider => {
return (
<a href={Provider.getAuthUrl(this.getApplicationObj(), provider, "signup")}>
<a href={Provider.getAuthUrl(application, provider, "signup")}>
<img width={30} height={30} src={Provider.getAuthLogo(provider)} alt={provider.displayName} style={{margin: "3px"}} />
</a>
);
@ -149,7 +159,7 @@ class Face extends React.Component {
<Row>
<Col span={24} style={{display: "flex", justifyContent: "center"}} >
<div style={{marginTop: "80px", textAlign: "center"}}>
<img width={250} src={application.logo} alt={application.displayName} style={{marginBottom: '50px'}}/>
<img width={250} src={application.logo} alt={application.displayName} style={{marginBottom: '30px'}}/>
{
this.renderForm(application)
}