mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-25 09:48:08 -04:00
graph: refactor auth and middlewares
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
@@ -63,6 +63,11 @@ type Reva struct {
|
|||||||
Address string
|
Address string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TokenManager is the config for using the reva token manager
|
||||||
|
type TokenManager struct {
|
||||||
|
JWTSecret string
|
||||||
|
}
|
||||||
|
|
||||||
type Spaces struct {
|
type Spaces struct {
|
||||||
WebDavBase string
|
WebDavBase string
|
||||||
}
|
}
|
||||||
@@ -79,6 +84,7 @@ type Config struct {
|
|||||||
Ldap Ldap
|
Ldap Ldap
|
||||||
OpenIDConnect OpenIDConnect
|
OpenIDConnect OpenIDConnect
|
||||||
Reva Reva
|
Reva Reva
|
||||||
|
TokenManager TokenManager
|
||||||
Spaces Spaces
|
Spaces Spaces
|
||||||
|
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
|||||||
@@ -213,6 +213,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
|||||||
Destination: &cfg.OpenIDConnect.Realm,
|
Destination: &cfg.OpenIDConnect.Realm,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "jwt-secret",
|
||||||
|
Value: flags.OverrideDefaultString(cfg.TokenManager.JWTSecret, "Pive-Fumkiu4"),
|
||||||
|
Usage: "Used to validate the reva access JWT, should equal reva's jwt-secret",
|
||||||
|
EnvVars: []string{"GRAPH_JWT_SECRET", "OCIS_JWT_SECRET"},
|
||||||
|
Destination: &cfg.TokenManager.JWTSecret,
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "reva-gateway-addr",
|
Name: "reva-gateway-addr",
|
||||||
Value: flags.OverrideDefaultString(cfg.Reva.Address, "127.0.0.1:9142"),
|
Value: flags.OverrideDefaultString(cfg.Reva.Address, "127.0.0.1:9142"),
|
||||||
|
|||||||
78
graph/pkg/middleware/auth.go
Normal file
78
graph/pkg/middleware/auth.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/cs3org/reva/pkg/auth/scope"
|
||||||
|
"github.com/cs3org/reva/pkg/token"
|
||||||
|
"github.com/cs3org/reva/pkg/token/manager/jwt"
|
||||||
|
"github.com/cs3org/reva/pkg/user"
|
||||||
|
"github.com/owncloud/ocis/graph/pkg/service/v0/errorcode"
|
||||||
|
"github.com/owncloud/ocis/ocis-pkg/account"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
)
|
||||||
|
|
||||||
|
// authOptions initializes the available default options.
|
||||||
|
func authOptions(opts ...account.Option) account.Options {
|
||||||
|
opt := account.Options{}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&opt)
|
||||||
|
}
|
||||||
|
|
||||||
|
return opt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth provides a middleware to authenticate requestrs using the x-access-token header value
|
||||||
|
// and write it to the context. If there is no x-access-token the middleware prevents access and renders a json document.
|
||||||
|
func Auth(opts ...account.Option) func(http.Handler) http.Handler {
|
||||||
|
opt := authOptions(opts...)
|
||||||
|
tokenManager, err := jwt.New(map[string]interface{}{
|
||||||
|
"secret": opt.JWTSecret,
|
||||||
|
"expires": int64(60),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
opt.Logger.Fatal().Err(err).Msgf("Could not initialize token-manager")
|
||||||
|
}
|
||||||
|
return func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
t := r.Header.Get("x-access-token")
|
||||||
|
if t == "" {
|
||||||
|
errorcode.InvalidAuthenticationToken.Render(w, r, http.StatusUnauthorized, "Access token is empty.")
|
||||||
|
/* msgraph error for GET https://graph.microsoft.com/v1.0/me
|
||||||
|
{
|
||||||
|
"error":
|
||||||
|
{
|
||||||
|
"code":"InvalidAuthenticationToken",
|
||||||
|
"message":"Access token is empty.",
|
||||||
|
"innerError":{
|
||||||
|
"date":"2021-07-09T14:40:51",
|
||||||
|
"request-id":"bb12f7db-b4c4-43a9-ba4b-31676aeed019",
|
||||||
|
"client-request-id":"bb12f7db-b4c4-43a9-ba4b-31676aeed019"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
u, tokenScope, err := tokenManager.DismantleToken(r.Context(), t)
|
||||||
|
if err != nil {
|
||||||
|
errorcode.InvalidAuthenticationToken.Render(w, r, http.StatusUnauthorized, "invalid token")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ok, err := scope.VerifyScope(tokenScope, r); err != nil || !ok {
|
||||||
|
opt.Logger.Error().Err(err).Msg("verifying scope failed")
|
||||||
|
errorcode.InvalidAuthenticationToken.Render(w, r, http.StatusUnauthorized, "verifying scope failed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = token.ContextSetToken(ctx, t)
|
||||||
|
ctx = user.ContextSetUser(ctx, u)
|
||||||
|
ctx = metadata.AppendToOutgoingContext(ctx, token.TokenHeader, t)
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,11 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/asim/go-micro/v3"
|
"github.com/asim/go-micro/v3"
|
||||||
|
graphMiddleware "github.com/owncloud/ocis/graph/pkg/middleware"
|
||||||
svc "github.com/owncloud/ocis/graph/pkg/service/v0"
|
svc "github.com/owncloud/ocis/graph/pkg/service/v0"
|
||||||
"github.com/owncloud/ocis/graph/pkg/version"
|
"github.com/owncloud/ocis/graph/pkg/version"
|
||||||
|
"github.com/owncloud/ocis/ocis-pkg/account"
|
||||||
"github.com/owncloud/ocis/ocis-pkg/middleware"
|
"github.com/owncloud/ocis/ocis-pkg/middleware"
|
||||||
"github.com/owncloud/ocis/ocis-pkg/oidc"
|
|
||||||
"github.com/owncloud/ocis/ocis-pkg/service/http"
|
"github.com/owncloud/ocis/ocis-pkg/service/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,11 +28,6 @@ func Server(opts ...Option) (http.Service, error) {
|
|||||||
svc.Logger(options.Logger),
|
svc.Logger(options.Logger),
|
||||||
svc.Config(options.Config),
|
svc.Config(options.Config),
|
||||||
svc.Middleware(
|
svc.Middleware(
|
||||||
middleware.RealIP,
|
|
||||||
middleware.RequestID,
|
|
||||||
middleware.NoCache,
|
|
||||||
middleware.Cors,
|
|
||||||
middleware.Secure,
|
|
||||||
middleware.Version(
|
middleware.Version(
|
||||||
"graph",
|
"graph",
|
||||||
version.String,
|
version.String,
|
||||||
@@ -39,11 +35,9 @@ func Server(opts ...Option) (http.Service, error) {
|
|||||||
middleware.Logger(
|
middleware.Logger(
|
||||||
options.Logger,
|
options.Logger,
|
||||||
),
|
),
|
||||||
middleware.OpenIDConnect(
|
graphMiddleware.Auth(
|
||||||
oidc.Endpoint(options.Config.OpenIDConnect.Endpoint),
|
account.Logger(options.Logger),
|
||||||
oidc.Realm(options.Config.OpenIDConnect.Realm),
|
account.JWTSecret(options.Config.TokenManager.JWTSecret),
|
||||||
oidc.Insecure(options.Config.OpenIDConnect.Insecure),
|
|
||||||
oidc.Logger(options.Logger),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,42 +8,17 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
|
|
||||||
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||||
"github.com/cs3org/reva/pkg/token"
|
|
||||||
|
|
||||||
msgraph "github.com/owncloud/open-graph-api-go"
|
msgraph "github.com/owncloud/open-graph-api-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getToken(r *http.Request) string {
|
|
||||||
// 1. check Authorization header
|
|
||||||
hdr := r.Header.Get("Authorization")
|
|
||||||
t := strings.TrimPrefix(hdr, "Bearer ")
|
|
||||||
if t != "" {
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
// TODO 2. check form encoded body parameter for POST requests, see https://tools.ietf.org/html/rfc6750#section-2.2
|
|
||||||
|
|
||||||
// 3. check uri query parameter, see https://tools.ietf.org/html/rfc6750#section-2.3
|
|
||||||
tokens, ok := r.URL.Query()["access_token"]
|
|
||||||
if !ok || len(tokens[0]) < 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokens[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDrives implements the Service interface.
|
// GetDrives implements the Service interface.
|
||||||
func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
|
||||||
g.logger.Info().Msg("Calling GetDrives")
|
g.logger.Info().Msg("Calling GetDrives")
|
||||||
if getToken(r) == "" {
|
|
||||||
g.logger.Error().Msg("no access token provided in request")
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
client, err := g.GetClient()
|
client, err := g.GetClient()
|
||||||
@@ -52,9 +27,6 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t := r.Header.Get("x-access-token")
|
|
||||||
ctx = token.ContextSetToken(ctx, t)
|
|
||||||
ctx = metadata.AppendToOutgoingContext(ctx, "x-access-token", t)
|
|
||||||
|
|
||||||
res, err := client.ListStorageSpaces(ctx, &storageprovider.ListStorageSpacesRequest{})
|
res, err := client.ListStorageSpaces(ctx, &storageprovider.ListStorageSpacesRequest{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,11 +62,6 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
|
|||||||
// GetRootDriveChildren implements the Service interface.
|
// GetRootDriveChildren implements the Service interface.
|
||||||
func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
||||||
g.logger.Info().Msg("Calling GetRootDriveChildren")
|
g.logger.Info().Msg("Calling GetRootDriveChildren")
|
||||||
if getToken(r) == "" {
|
|
||||||
g.logger.Error().Msg("no access token provided in request")
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
fn := g.config.WebdavNamespace
|
fn := g.config.WebdavNamespace
|
||||||
@@ -106,12 +73,6 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t := r.Header.Get("x-access-token")
|
|
||||||
ctx = token.ContextSetToken(ctx, t)
|
|
||||||
ctx = metadata.AppendToOutgoingContext(ctx, "x-access-token", t)
|
|
||||||
|
|
||||||
g.logger.Info().Interface("context", ctx).Msg("provides access token")
|
|
||||||
|
|
||||||
ref := &storageprovider.Reference{
|
ref := &storageprovider.Reference{
|
||||||
Path: fn,
|
Path: fn,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ const (
|
|||||||
ActivityLimitReached
|
ActivityLimitReached
|
||||||
// GeneralException defines the error if an unspecified error has occurred.
|
// GeneralException defines the error if an unspecified error has occurred.
|
||||||
GeneralException
|
GeneralException
|
||||||
|
// InvalidAuthenticationToken defines the error if the access token is missing
|
||||||
|
InvalidAuthenticationToken
|
||||||
// InvalidRange defines the error if the specified byte range is invalid or unavailable.
|
// InvalidRange defines the error if the specified byte range is invalid or unavailable.
|
||||||
InvalidRange
|
InvalidRange
|
||||||
// InvalidRequest defines the error if the request is malformed or incorrect.
|
// InvalidRequest defines the error if the request is malformed or incorrect.
|
||||||
@@ -47,6 +49,7 @@ var errorCodes = [...]string{
|
|||||||
"accessDenied",
|
"accessDenied",
|
||||||
"activityLimitReached",
|
"activityLimitReached",
|
||||||
"generalException",
|
"generalException",
|
||||||
|
"InvalidAuthenticationToken",
|
||||||
"invalidRange",
|
"invalidRange",
|
||||||
"invalidRequest",
|
"invalidRequest",
|
||||||
"itemNotFound",
|
"itemNotFound",
|
||||||
@@ -62,9 +65,10 @@ var errorCodes = [...]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render writes an Graph ErrorObject to the response writer
|
// Render writes an Graph ErrorObject to the response writer
|
||||||
func (e ErrorCode) Render(w http.ResponseWriter, r *http.Request, status int) {
|
func (e ErrorCode) Render(w http.ResponseWriter, r *http.Request, status int, msg string) {
|
||||||
resp := &msgraph.ErrorObject{
|
resp := &msgraph.ErrorObject{
|
||||||
Code: e.String(),
|
Code: e.String(),
|
||||||
|
Message: msg,
|
||||||
}
|
}
|
||||||
render.Status(r, status)
|
render.Status(r, status)
|
||||||
render.JSON(w, r, resp)
|
render.JSON(w, r, resp)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func (g Graph) GroupCtx(next http.Handler) http.Handler {
|
|||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
groupID := chi.URLParam(r, "groupID")
|
groupID := chi.URLParam(r, "groupID")
|
||||||
if groupID == "" {
|
if groupID == "" {
|
||||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest)
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "groupID empty")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO make filter configurable
|
// TODO make filter configurable
|
||||||
@@ -28,7 +28,7 @@ func (g Graph) GroupCtx(next http.Handler) http.Handler {
|
|||||||
group, err := g.ldapGetSingleEntry(g.config.Ldap.BaseDNGroups, filter)
|
group, err := g.ldapGetSingleEntry(g.config.Ldap.BaseDNGroups, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Info().Err(err).Msgf("Failed to read group %s", groupID)
|
g.logger.Info().Err(err).Msgf("Failed to read group %s", groupID)
|
||||||
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound)
|
errorcode.ItemNotFound.Render(w, r, http.StatusInternalServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) {
|
|||||||
con, err := g.initLdap()
|
con, err := g.initLdap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Error().Err(err).Msg("Failed to initialize ldap")
|
g.logger.Error().Err(err).Msg("Failed to initialize ldap")
|
||||||
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError)
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ func (g Graph) GetGroups(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixGroup)'")
|
g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixGroup)'")
|
||||||
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError)
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/owncloud/ocis/graph/pkg/service/v0/errorcode"
|
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||||
|
"github.com/cs3org/reva/pkg/user"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
"github.com/go-ldap/ldap/v3"
|
"github.com/go-ldap/ldap/v3"
|
||||||
"github.com/owncloud/ocis/ocis-pkg/oidc"
|
"github.com/owncloud/ocis/graph/pkg/service/v0/errorcode"
|
||||||
msgraph "github.com/yaegashi/msgraph.go/v1.0"
|
msgraph "github.com/yaegashi/msgraph.go/v1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserCtx middleware is used to load an User object from
|
// UserCtx middleware is used to load an User object from
|
||||||
// the URL parameters passed through as the request. In case
|
// the URL parameters passed through as the request. In case
|
||||||
// the User could not be found, we stop here and return a 404.
|
// the User could not be found, we stop here and return a 404.
|
||||||
|
// TODO use cs3 api to look up user
|
||||||
func (g Graph) UserCtx(next http.Handler) http.Handler {
|
func (g Graph) UserCtx(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
var user *ldap.Entry
|
var user *ldap.Entry
|
||||||
@@ -24,7 +25,7 @@ func (g Graph) UserCtx(next http.Handler) http.Handler {
|
|||||||
|
|
||||||
userID := chi.URLParam(r, "userID")
|
userID := chi.URLParam(r, "userID")
|
||||||
if userID == "" {
|
if userID == "" {
|
||||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest)
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO make filter configurable
|
// TODO make filter configurable
|
||||||
@@ -32,7 +33,7 @@ func (g Graph) UserCtx(next http.Handler) http.Handler {
|
|||||||
user, err = g.ldapGetSingleEntry(g.config.Ldap.BaseDNUsers, filter)
|
user, err = g.ldapGetSingleEntry(g.config.Ldap.BaseDNUsers, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Info().Err(err).Msgf("Failed to read user %s", userID)
|
g.logger.Info().Err(err).Msgf("Failed to read user %s", userID)
|
||||||
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound)
|
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,30 +44,48 @@ func (g Graph) UserCtx(next http.Handler) http.Handler {
|
|||||||
|
|
||||||
// GetMe implements the Service interface.
|
// GetMe implements the Service interface.
|
||||||
func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
||||||
claims := oidc.FromContext(r.Context())
|
|
||||||
g.logger.Info().Interface("Claims", claims).Msg("Claims in /me")
|
|
||||||
|
|
||||||
// TODO make filter configurable
|
u, ok := user.ContextGetUser(r.Context())
|
||||||
filter := fmt.Sprintf("(&(objectClass=posixAccount)(cn=%s))", claims.PreferredUsername)
|
if !ok {
|
||||||
user, err := g.ldapGetSingleEntry(g.config.Ldap.BaseDNUsers, filter)
|
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "")
|
||||||
if err != nil {
|
|
||||||
g.logger.Info().Err(err).Msgf("Failed to read user %s", claims.PreferredUsername)
|
|
||||||
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
me := createUserModelFromLDAP(user)
|
g.logger.Info().Interface("user", u).Msg("User in /me")
|
||||||
|
|
||||||
|
me := createUserModelFromCS3(u)
|
||||||
|
|
||||||
render.Status(r, http.StatusOK)
|
render.Status(r, http.StatusOK)
|
||||||
render.JSON(w, r, me)
|
render.JSON(w, r, me)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createUserModelFromCS3(u *userpb.User) *msgraph.User {
|
||||||
|
return &msgraph.User{
|
||||||
|
DisplayName: &u.DisplayName,
|
||||||
|
Mail: &u.Mail,
|
||||||
|
// TODO u.Groups
|
||||||
|
OnPremisesSamAccountName: &u.Username,
|
||||||
|
DirectoryObject: msgraph.DirectoryObject{
|
||||||
|
Entity: msgraph.Entity{
|
||||||
|
ID: &u.Id.OpaqueId,
|
||||||
|
Object: msgraph.Object{
|
||||||
|
AdditionalData: map[string]interface{}{
|
||||||
|
"uidnumber": u.UidNumber,
|
||||||
|
"gidnumber": u.GidNumber,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetUsers implements the Service interface.
|
// GetUsers implements the Service interface.
|
||||||
|
// TODO use cs3 api to look up user
|
||||||
func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
con, err := g.initLdap()
|
con, err := g.initLdap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Error().Err(err).Msg("Failed to initialize ldap")
|
g.logger.Error().Err(err).Msg("Failed to initialize ldap")
|
||||||
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError)
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +94,7 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixAccount)'")
|
g.logger.Error().Err(err).Msg("Failed search ldap with filter: '(objectClass=posixAccount)'")
|
||||||
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError)
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user