Skip to content

Commit

Permalink
Fix auth package
Browse files Browse the repository at this point in the history
  • Loading branch information
levichevdmitry committed Dec 2, 2020
1 parent 4581637 commit 3ca3638
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 0 deletions.
35 changes: 35 additions & 0 deletions auth/BasicAuthManager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package auth

import (
"net/http"

cdata "github.com/pip-services3-go/pip-services3-commons-go/data"
cerr "github.com/pip-services3-go/pip-services3-commons-go/errors"
services "github.com/pip-services3-go/pip-services3-rpc-go/services"
)

type BasicAuthManager struct {
}

func (c *BasicAuthManager) Anybody() func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
return func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
next.ServeHTTP(res, req)
}
}

func (c *BasicAuthManager) Signed() func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
return func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
_, ok := req.Context().Value("user").(cdata.AnyValueMap)
if !ok {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("",
"NOT_SIGNED",
"User must be signed in to perform this operation",
).WithStatus(401),
)
} else {
next.ServeHTTP(res, req)
}
}
}
99 changes: 99 additions & 0 deletions auth/OwnerAuthManager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package auth

import (
"net/http"

"github.com/gorilla/mux"
cdata "github.com/pip-services3-go/pip-services3-commons-go/data"
cerr "github.com/pip-services3-go/pip-services3-commons-go/errors"
services "github.com/pip-services3-go/pip-services3-rpc-go/services"
)

type OwnerAuthManager struct {
}

func (c *OwnerAuthManager) Owner(idParam string) func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
if idParam == "" {
idParam = "user_id"
}
return func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {

_, ok := req.Context().Value("user").(cdata.AnyValueMap)

if !ok {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("",
"NOT_SIGNED",
"User must be signed in to perform this operation",
).WithStatus(401),
)
} else {
userId := req.URL.Query().Get(idParam)
if userId == "" {
userId = mux.Vars(req)[idParam]
}

reqUserId, ok := req.Context().Value("user_id").(string)
if !ok || reqUserId != userId {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError(
"", "FORBIDDEN",
"Only data owner can perform this operation",
).WithStatus(403),
)
} else {
next.ServeHTTP(res, req)
}
}
}
}

func (c *OwnerAuthManager) OwnerOrAdmin(idParam string) func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
if idParam == "" {
idParam = "user_id"
}
return func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {

user, ok := req.Context().Value("user").(cdata.AnyValueMap)

if !ok {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("",
"NOT_SIGNED",
"User must be signed in to perform this operation",
).WithStatus(401),
)
} else {

userId := req.URL.Query().Get(idParam)
if userId == "" {
userId = mux.Vars(req)[idParam]
}
roles := user.GetAsArray("roles")
admin := false
for _, role := range roles.Value() {
r, ok := role.(string)
if ok && r == "admin" {
admin = true
break
}
}

reqUserId, ok := req.Context().Value("user_id").(string)
if !ok || reqUserId != userId && !admin {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("",
"FORBIDDEN",
"Only data owner can perform this operation",
).WithStatus(403),
)
} else {
next.ServeHTTP(res, req)
}
}
}
}
64 changes: 64 additions & 0 deletions auth/RoleAuthManager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package auth

import (
"net/http"
"strings"

cdata "github.com/pip-services3-go/pip-services3-commons-go/data"
cerr "github.com/pip-services3-go/pip-services3-commons-go/errors"
services "github.com/pip-services3-go/pip-services3-rpc-go/services"
)

type RoleAuthManager struct {
}

func (c *RoleAuthManager) UserInRoles(roles []string) func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
return func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {

user, ok := req.Context().Value("user").(cdata.AnyValueMap)
if !ok {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("", "NOT_SIGNED",
"User must be signed in to perform this operation").WithStatus(401))
} else {
authorized := false
userRoles := user.GetAsArray("roles")

if userRoles == nil {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError("", "NOT_SIGNED",
"User must be signed in to perform this operation").WithStatus(401))
return
}

for _, role := range roles {
for _, userRole := range userRoles.Value() {
r, ok := userRole.(string)
if ok && role == r {
authorized = true
}
}
}

if !authorized {
services.HttpResponseSender.SendError(
res, req,
cerr.NewUnauthorizedError(
"", "NOT_IN_ROLE",
"User must be "+strings.Join(roles, " or ")+" to perform this operation").WithDetails("roles", roles).WithStatus(403))
} else {
next.ServeHTTP(res, req)
}
}
}
}

func (c *RoleAuthManager) UserInRole(role string) func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
return c.UserInRoles([]string{role})
}

func (c *RoleAuthManager) Admin() func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
return c.UserInRole("admin")
}

0 comments on commit 3ca3638

Please sign in to comment.