github.com/resonatecoop/id@v1.1.0-43/oauth/scope.go (about)

     1  package oauth
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/resonatecoop/user-api/model"
    10  	"github.com/uptrace/bun"
    11  )
    12  
    13  var (
    14  	// ErrInvalidScope ...
    15  	ErrInvalidScope = errors.New("Invalid scope")
    16  )
    17  
    18  // GetScope takes a requested scope and, if it's empty, returns the default
    19  // scope, if not empty, it validates the requested scope
    20  func (s *Service) GetScope(requestedScope string) (string, error) {
    21  	// Return the default scope if the requested scope is empty
    22  	if requestedScope == "" {
    23  		return s.GetDefaultScope(), nil
    24  	}
    25  
    26  	// If the requested scope exists in the database, return it
    27  	if s.ScopeExists(requestedScope) {
    28  		return requestedScope, nil
    29  	}
    30  
    31  	// Otherwise return error
    32  	return "", ErrInvalidScope
    33  }
    34  
    35  // GetDefaultScope returns the default scope
    36  func (s *Service) GetDefaultScope() string {
    37  	ctx := context.Background()
    38  	// Fetch default scopes
    39  	var scopes []string
    40  
    41  	rows, err := s.db.NewSelect().
    42  		Model((*model.Scope)(nil)).
    43  		Where("is_default = ?", true).
    44  		Rows(ctx)
    45  
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  	defer rows.Close()
    50  
    51  	for rows.Next() {
    52  		scope := new(model.Scope)
    53  		if err := s.db.ScanRow(ctx, rows, scope); err != nil {
    54  			panic(err)
    55  		}
    56  		scopes = append(scopes, scope.Name)
    57  	}
    58  
    59  	if err := rows.Err(); err != nil {
    60  		panic(err)
    61  	}
    62  
    63  	// s.db.NewSelect().Model(new(model.Scope)).Where("is_default = ?", true).Pluck("scope", &scopes)
    64  
    65  	// Sort the scopes alphabetically
    66  	sort.Strings(scopes)
    67  
    68  	// Return space delimited scope string
    69  	return strings.Join(scopes, " ")
    70  }
    71  
    72  // ScopeExists checks if a scope exists
    73  func (s *Service) ScopeExists(requestedScope string) bool {
    74  	ctx := context.Background()
    75  	// Split the requested scope string
    76  	scopes := strings.Split(requestedScope, " ")
    77  
    78  	var available_scopes []model.Scope
    79  
    80  	// Count how many of requested scopes exist in the database
    81  	count, _ := s.db.NewSelect().
    82  		Model(&available_scopes).
    83  		Where("name IN (?)", bun.In(scopes)).
    84  		ScanAndCount(ctx)
    85  
    86  	// Return true only if all requested scopes found
    87  	return count == len(scopes)
    88  }