github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/services/authorizations/create.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 authorizations
    19  
    20  import (
    21  	"github.com/aacfactory/errors"
    22  	"github.com/aacfactory/fns/context"
    23  	"github.com/aacfactory/fns/runtime"
    24  	"github.com/aacfactory/fns/services"
    25  	"time"
    26  )
    27  
    28  var (
    29  	createFnName = []byte("create")
    30  )
    31  
    32  type CreateParam struct {
    33  	Id         Id         `json:"id" avro:"id"`
    34  	Account    Id         `json:"account" avro:"account"`
    35  	Attributes Attributes `json:"attributes" avro:"attributes"`
    36  }
    37  
    38  type CreateResult struct {
    39  	Token         Token         `json:"token" avro:"token"`
    40  	Authorization Authorization `json:"authorization" avro:"authorization"`
    41  }
    42  
    43  func Create(ctx context.Context, param CreateParam) (token Token, err error) {
    44  	rt := runtime.Load(ctx)
    45  	response, handleErr := rt.Endpoints().Request(
    46  		ctx,
    47  		endpointName, createFnName,
    48  		param,
    49  	)
    50  	if handleErr != nil {
    51  		err = handleErr
    52  		return
    53  	}
    54  	result, resultErr := services.ValueOfResponse[CreateResult](response)
    55  	if resultErr != nil {
    56  		err = errors.Warning("authorizations: scan encode value failed").WithCause(resultErr)
    57  		return
    58  	}
    59  	With(ctx, result.Authorization)
    60  	token = result.Token
    61  	return
    62  }
    63  
    64  type createFn struct {
    65  	encoder   TokenEncoder
    66  	store     TokenStore
    67  	expireTTL time.Duration
    68  }
    69  
    70  func (fn *createFn) Name() string {
    71  	return string(createFnName)
    72  }
    73  
    74  func (fn *createFn) Internal() bool {
    75  	return true
    76  }
    77  
    78  func (fn *createFn) Readonly() bool {
    79  	return false
    80  }
    81  
    82  func (fn *createFn) Handle(r services.Request) (v any, err error) {
    83  	param, paramErr := services.ValueOfParam[CreateParam](r.Param())
    84  	if paramErr != nil {
    85  		err = errors.Warning("authorizations: invalid param")
    86  		return
    87  	}
    88  	if len(param.Id) == 0 || len(param.Account) == 0 {
    89  		err = errors.Warning("authorizations: invalid param")
    90  		return
    91  	}
    92  	authorization := Authorization{
    93  		Id:         param.Id,
    94  		Account:    param.Account,
    95  		Attributes: param.Attributes,
    96  		ExpireAT:   time.Now().Add(fn.expireTTL),
    97  	}
    98  	token, encodeErr := fn.encoder.Encode(r, authorization)
    99  	if encodeErr != nil {
   100  		err = errors.Warning("authorizations: encode authorization failed").WithCause(encodeErr)
   101  		return
   102  	}
   103  	saveErr := fn.store.Save(r, authorization)
   104  	if saveErr != nil {
   105  		err = errors.Warning("authorizations: encode authorization failed").WithCause(saveErr)
   106  		return
   107  	}
   108  	v = CreateResult{
   109  		Token:         token,
   110  		Authorization: authorization,
   111  	}
   112  	return
   113  }