github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/services/permissions/service.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package permissions
    19  
    20  import (
    21  	"fmt"
    22  	"github.com/aacfactory/errors"
    23  	"github.com/aacfactory/fns/services"
    24  )
    25  
    26  var (
    27  	endpointName  = []byte("permissions")
    28  	enforceFnName = []byte("enforce")
    29  )
    30  
    31  type enforceFn struct {
    32  	enforcer Enforcer
    33  }
    34  
    35  func (fn *enforceFn) Name() string {
    36  	return string(enforceFnName)
    37  }
    38  
    39  func (fn *enforceFn) Internal() bool {
    40  	return true
    41  }
    42  
    43  func (fn *enforceFn) Readonly() bool {
    44  	return false
    45  }
    46  
    47  func (fn *enforceFn) Handle(r services.Request) (v interface{}, err error) {
    48  	param, paramErr := services.ValueOfParam[EnforceParam](r.Param())
    49  	if paramErr != nil {
    50  		err = errors.BadRequest("permissions: invalid enforce param").WithCause(paramErr)
    51  		return
    52  	}
    53  	v, err = fn.enforcer.Enforce(r, param)
    54  	if err != nil {
    55  		err = errors.ServiceError("permissions: enforce failed").WithCause(err)
    56  		return
    57  	}
    58  	return
    59  }
    60  
    61  func New(enforcer Enforcer) (v services.Service) {
    62  	if enforcer == nil {
    63  		panic(fmt.Sprintf("%+v", errors.Warning("permissions: service requires enforcer component")))
    64  		return
    65  	}
    66  	v = &service{
    67  		Abstract: services.NewAbstract(string(endpointName), true, enforcer),
    68  	}
    69  	return
    70  }
    71  
    72  // service
    73  // use @permission
    74  type service struct {
    75  	services.Abstract
    76  	enforcer Enforcer
    77  }
    78  
    79  func (svc *service) Construct(options services.Options) (err error) {
    80  	err = svc.Abstract.Construct(options)
    81  	if err != nil {
    82  		return
    83  	}
    84  	if svc.Components() == nil || len(svc.Components()) != 1 {
    85  		err = errors.Warning("permissions: construct failed").WithMeta("endpoint", svc.Name()).WithCause(errors.Warning("permissions: enforcer is required"))
    86  		return
    87  	}
    88  	var enforcer Enforcer
    89  	has := false
    90  	for _, component := range svc.Components() {
    91  		enforcer, has = component.(Enforcer)
    92  		if has {
    93  			break
    94  		}
    95  	}
    96  	if enforcer == nil {
    97  		err = errors.Warning("permissions: service need token encoder component")
    98  		return
    99  	}
   100  	svc.Abstract.AddFunction(&enforceFn{
   101  		enforcer: enforcer,
   102  	})
   103  	return
   104  }