Skip to content
This repository has been archived by the owner on Apr 9, 2019. It is now read-only.

Commit

Permalink
Merge pull request #61 from jarias/develop
Browse files Browse the repository at this point in the history
Release 0.1.0-beta.21
  • Loading branch information
jarias authored Aug 20, 2016
2 parents 00e5c9f + 890f30d commit 82b82e2
Show file tree
Hide file tree
Showing 25 changed files with 591 additions and 111 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fmt.Println(account)

See `web/example/example.go`

Features:
# Features

* Cache with a sample local in-memory implementation
* Almost 100% of the Stormpath API implemented
Expand Down
74 changes: 63 additions & 11 deletions account_store_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,61 @@ package stormpath

import "strings"

//AccountStoreMapping represents an Stormpath account store mapping
//ApplicationAccountStoreMapping represents an Stormpath account store mapping
//
//See: http://docs.stormpath.com/rest/product-guide/#account-store-mappings
type AccountStoreMapping struct {
type ApplicationAccountStoreMapping struct {
resource
ListIndex *int `json:"collectionResourceIndex,omitempty"`
IsDefaultAccountStore *bool `json:"isDefaultAccountStore,omitempty"`
IsDefaultGroupStore *bool `json:"isDefaultGroupStore,omitempty"`
IsDefaultAccountStore bool `json:"isDefaultAccountStore"`
IsDefaultGroupStore bool `json:"isDefaultGroupStore"`
Application *Application `json:"application,omitempty"`
AccountStore *resource `json:"accountStore,omitempty"`
}

//AccountStoreMappings represents a pages result of account store mappings
type OrganizationAccountStoreMapping struct {
resource
ListIndex *int `json:"collectionResourceIndex,omitempty"`
IsDefaultAccountStore bool `json:"isDefaultAccountStore"`
IsDefaultGroupStore bool `json:"isDefaultGroupStore"`
Organization *Organization `json:"organization,omitempty"`
AccountStore *resource `json:"accountStore,omitempty"`
}

//ApplicationAccountStoreMappings represents a pages result of account store mappings
//
//See: http://docs.stormpath.com/rest/product-guide/#collectionResource-account-store-mappings
type AccountStoreMappings struct {
type ApplicationAccountStoreMappings struct {
collectionResource
Items []AccountStoreMapping `json:"items,omitempty"`
Items []ApplicationAccountStoreMapping `json:"items,omitempty"`
}

type OrganizationAccountStoreMappings struct {
collectionResource
Items []OrganizationAccountStoreMapping `json:"items,omitempty"`
}

//NewAccountStoreMapping creates a new account store mappings
func NewAccountStoreMapping(applicationHref string, accountStoreHref string) *AccountStoreMapping {
func NewApplicationAccountStoreMapping(applicationHref string, accountStoreHref string) *ApplicationAccountStoreMapping {
app := Application{}
app.Href = applicationHref
return &AccountStoreMapping{
return &ApplicationAccountStoreMapping{
Application: &app,
AccountStore: &resource{Href: accountStoreHref},
}
}

func NewOrganizationAccountStoreMapping(organizationHref string, accountStoreHref string) *OrganizationAccountStoreMapping {
org := Organization{}
org.Href = organizationHref
return &OrganizationAccountStoreMapping{
Organization: &org,
AccountStore: &resource{Href: accountStoreHref},
}
}

//Save saves the given account store mapping
func (mapping *AccountStoreMapping) Save() error {
func (mapping *ApplicationAccountStoreMapping) Save() error {
url := buildRelativeURL("accountStoreMappings")
if mapping.Href != "" {
url = mapping.Href
Expand All @@ -42,6 +65,35 @@ func (mapping *AccountStoreMapping) Save() error {
return client.post(url, mapping, mapping)
}

func (mapping *AccountStoreMapping) IsAccountStoreDirectory() bool {
func (mapping *OrganizationAccountStoreMapping) Save() error {
url := buildRelativeURL("organizationAccountStoreMappings")
if mapping.Href != "" {
url = mapping.Href
}

return client.post(url, mapping, mapping)
}

func (mapping *ApplicationAccountStoreMapping) IsAccountStoreDirectory() bool {
return strings.Contains(mapping.AccountStore.Href, "/directories/")
}

func (mapping *ApplicationAccountStoreMapping) IsAccountStoreGroup() bool {
return strings.Contains(mapping.AccountStore.Href, "/groups/")
}

func (mapping *ApplicationAccountStoreMapping) IsAccountStoreOrganization() bool {
return strings.Contains(mapping.AccountStore.Href, "/organizations/")
}

func (mapping *OrganizationAccountStoreMapping) IsAccountStoreDirectory() bool {
return strings.Contains(mapping.AccountStore.Href, "/directories/")
}

func (mapping *OrganizationAccountStoreMapping) IsAccountStoreGroup() bool {
return strings.Contains(mapping.AccountStore.Href, "/groups/")
}

func (mapping *OrganizationAccountStoreMapping) IsAccountStoreOrganization() bool {
return strings.Contains(mapping.AccountStore.Href, "/organizations/")
}
29 changes: 23 additions & 6 deletions account_store_mapping_criteria.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,42 @@ package stormpath

import "net/url"

type AccountStoreMappingCriteria struct {
type ApplicationAccountStoreMappingCriteria struct {
baseCriteria
}

func MakeAccountStoreMappingCriteria() AccountStoreMappingCriteria {
return AccountStoreMappingCriteria{baseCriteria{filter: url.Values{}}}
type OrganizationAccountStoreMappingCriteria struct {
baseCriteria
}

func MakeApplicationAccountStoreMappingCriteria() ApplicationAccountStoreMappingCriteria {
return ApplicationAccountStoreMappingCriteria{baseCriteria{filter: url.Values{}}}
}

func MakeApplicationAccountStoreMappingsCriteria() ApplicationAccountStoreMappingCriteria {
return ApplicationAccountStoreMappingCriteria{baseCriteria{limit: 25, filter: url.Values{}}}
}

func MakeAccountStoreMappingsCriteria() AccountStoreMappingCriteria {
return AccountStoreMappingCriteria{baseCriteria{limit: 25, filter: url.Values{}}}
func MakeOrganizationAccountStoreMappingCriteria() OrganizationAccountStoreMappingCriteria {
return OrganizationAccountStoreMappingCriteria{baseCriteria{filter: url.Values{}}}
}

func MakeOrganizationAccountStoreMappingsCriteria() OrganizationAccountStoreMappingCriteria {
return OrganizationAccountStoreMappingCriteria{baseCriteria{limit: 25, filter: url.Values{}}}
}

//Expansion related functions

func (c AccountStoreMappingCriteria) WithApplication() AccountStoreMappingCriteria {
func (c ApplicationAccountStoreMappingCriteria) WithApplication() ApplicationAccountStoreMappingCriteria {
c.expandedAttributes = append(c.expandedAttributes, "application")
return c
}

func (c OrganizationAccountStoreMappingCriteria) WithOrganization() OrganizationAccountStoreMappingCriteria {
c.expandedAttributes = append(c.expandedAttributes, "organization")
return c
}

//TODO: Right not this function is disable cause the type of accountStore is resource and thus can't be
//expanded, probably need to change it interface and create a custom serializer depending on the href value
//directory, application or group
Expand Down
12 changes: 6 additions & 6 deletions account_store_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
func TestAccountStoreMappingJsonMarshaling(t *testing.T) {
t.Parallel()

accountStoreMapping := NewAccountStoreMapping("http://appurl", "http://storeUrl")
accountStoreMapping := NewApplicationAccountStoreMapping("http://appurl", "http://storeUrl")

jsonData, _ := json.Marshal(accountStoreMapping)

assert.Equal(t, "{\"application\":{\"href\":\"http://appurl\"},\"accountStore\":{\"href\":\"http://storeUrl\"}}", string(jsonData))
assert.Equal(t, "{\"isDefaultAccountStore\":false,\"isDefaultGroupStore\":false,\"application\":{\"href\":\"http://appurl\"},\"accountStore\":{\"href\":\"http://storeUrl\"}}", string(jsonData))
}

func TestSaveAccountStoreMapping(t *testing.T) {
Expand All @@ -27,7 +27,7 @@ func TestSaveAccountStoreMapping(t *testing.T) {
directory := createTestDirectory()
defer directory.Delete()

asm := NewAccountStoreMapping(application.Href, directory.Href)
asm := NewApplicationAccountStoreMapping(application.Href, directory.Href)
err := asm.Save()

assert.NoError(t, err)
Expand All @@ -40,7 +40,7 @@ func TestSaveAccountStoreMappingApplicationNoExists(t *testing.T) {
directory := createTestDirectory()
defer directory.Delete()

asm := NewAccountStoreMapping(GetClient().ClientConfiguration.BaseURL+"applications/XXX", directory.Href)
asm := NewApplicationAccountStoreMapping(GetClient().ClientConfiguration.BaseURL+"applications/XXX", directory.Href)
err := asm.Save()

assert.Error(t, err)
Expand All @@ -54,7 +54,7 @@ func TestSaveAccountStoreMappingDirectoryNoExists(t *testing.T) {
application := createTestApplication()
defer application.Purge()

asm := NewAccountStoreMapping(application.Href, GetClient().ClientConfiguration.BaseURL+"directories/XXX")
asm := NewApplicationAccountStoreMapping(application.Href, GetClient().ClientConfiguration.BaseURL+"directories/XXX")
err := asm.Save()

assert.Error(t, err)
Expand All @@ -74,7 +74,7 @@ func TestIsAccountStoreDirectory(t *testing.T) {
}

for _, c := range cases {
accountStoreMapping := NewAccountStoreMapping("", c.url)
accountStoreMapping := NewApplicationAccountStoreMapping("", c.url)
assert.Equal(t, accountStoreMapping.IsAccountStoreDirectory(), c.isDirectory)
}
}
39 changes: 22 additions & 17 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ import (
//See: http://docs.stormpath.com/rest/product-guide/#applications
type Application struct {
accountStoreResource
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Status string `json:"status,omitempty"`
Groups *Groups `json:"groups,omitempty"`
Tenant *Tenant `json:"tenant,omitempty"`
PasswordResetTokens *resource `json:"passwordResetTokens,omitempty"`
AccountStoreMappings *AccountStoreMappings `json:"accountStoreMappings,omitempty"`
DefaultAccountStoreMapping *AccountStoreMapping `json:"defaultAccountStoreMapping,omitempty"`
DefaultGroupStoreMapping *AccountStoreMapping `json:"defaultGroupStoreMapping,omitempty"`
OAuthPolicy *OAuthPolicy `json:"oAuthPolicy,omitempty"`
APIKeys *APIKeys `json:"apiKeys,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Status string `json:"status,omitempty"`
Groups *Groups `json:"groups,omitempty"`
Tenant *Tenant `json:"tenant,omitempty"`
PasswordResetTokens *resource `json:"passwordResetTokens,omitempty"`
AccountStoreMappings *ApplicationAccountStoreMappings `json:"accountStoreMappings,omitempty"`
DefaultAccountStoreMapping *ApplicationAccountStoreMapping `json:"defaultAccountStoreMapping,omitempty"`
DefaultGroupStoreMapping *ApplicationAccountStoreMapping `json:"defaultGroupStoreMapping,omitempty"`
OAuthPolicy *OAuthPolicy `json:"oAuthPolicy,omitempty"`
APIKeys *APIKeys `json:"apiKeys,omitempty"`
}

//Applications represents a paged result or applications
Expand Down Expand Up @@ -81,7 +81,7 @@ func (app *Application) Update() error {
//
//See: http://docs.stormpath.com/rest/product-guide/#delete-an-application
func (app *Application) Purge() error {
accountStoreMappings, err := app.GetAccountStoreMappings(MakeAccountStoreMappingCriteria().Offset(0).Limit(25))
accountStoreMappings, err := app.GetAccountStoreMappings(MakeApplicationAccountStoreMappingCriteria().Offset(0).Limit(25))
if err != nil {
return err
}
Expand All @@ -95,8 +95,8 @@ func (app *Application) Purge() error {
//GetAccountStoreMappings returns all the applications account store mappings
//
//See: http://docs.stormpath.com/rest/product-guide/#application-account-store-mappings
func (app *Application) GetAccountStoreMappings(criteria Criteria) (*AccountStoreMappings, error) {
accountStoreMappings := &AccountStoreMappings{}
func (app *Application) GetAccountStoreMappings(criteria Criteria) (*ApplicationAccountStoreMappings, error) {
accountStoreMappings := &ApplicationAccountStoreMappings{}

err := client.get(
buildAbsoluteURL(app.AccountStoreMappings.Href, criteria.ToQueryString()),
Expand All @@ -110,7 +110,7 @@ func (app *Application) GetAccountStoreMappings(criteria Criteria) (*AccountStor
return accountStoreMappings, nil
}

func (app *Application) GetDefaultAccountStoreMapping(criteria Criteria) (*AccountStoreMapping, error) {
func (app *Application) GetDefaultAccountStoreMapping(criteria Criteria) (*ApplicationAccountStoreMapping, error) {
err := client.get(
buildAbsoluteURL(app.DefaultAccountStoreMapping.Href, criteria.ToQueryString()),
app.DefaultAccountStoreMapping,
Expand Down Expand Up @@ -153,12 +153,17 @@ func (app *Application) RegisterSocialAccount(socialAccount *SocialAccount) (*Ac
//AuthenticateAccount authenticates an account against the application
//
//See: http://docs.stormpath.com/rest/product-guide/#authenticate-an-account
func (app *Application) AuthenticateAccount(username string, password string) (*Account, error) {
func (app *Application) AuthenticateAccount(username string, password string, accountStoreHref string) (*Account, error) {
accountRef := &accountRef{Account: &Account{}}

loginAttemptPayload := make(map[string]string)
loginAttemptPayload := make(map[string]interface{})
loginAttemptPayload["type"] = "basic"
loginAttemptPayload["value"] = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
if accountStoreHref != "" {
loginAttemptPayload["accountStore"] = map[string]string{
"href": accountStoreHref,
}
}

err := client.post(buildAbsoluteURL(app.Href, "loginAttempts"), loginAttemptPayload, accountRef)

Expand Down
10 changes: 3 additions & 7 deletions application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func TestUpdateApplication(t *testing.T) {
assert.Equal(t, application.Name, updatedApplication.Name)
}

func TestRegisterAccount(t *testing.T) {
func TestApplicationRegisterAccount(t *testing.T) {
t.Parallel()

application := createTestApplication()
Expand All @@ -131,7 +131,7 @@ func TestAuthenticateAccount(t *testing.T) {

account := createTestAccount(application)

authenticatedAccount, err := application.AuthenticateAccount(account.Email, "1234567z!A89")
authenticatedAccount, err := application.AuthenticateAccount(account.Email, "1234567z!A89", "")

assert.NoError(t, err)
assert.Equal(t, account.Href, authenticatedAccount.Href)
Expand Down Expand Up @@ -326,14 +326,10 @@ func TestGetApplicationDefaultAccountStoreMapping(t *testing.T) {
application := createTestApplication()
defer application.Purge()

directory := createTestDirectory()
defer directory.Delete()

defaultMapping, err := application.GetDefaultAccountStoreMapping(MakeAccountStoreMappingCriteria())
defaultMapping, err := application.GetDefaultAccountStoreMapping(MakeApplicationAccountStoreMappingCriteria())

assert.NoError(t, err)
assert.Equal(t, application.Href, defaultMapping.Application.Href)
assert.NotEmpty(t, directory.Href)
}

func TestGetOAuthTokenStormpathGrantType(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ func TestNonCacheableResources(t *testing.T) {
&Accounts{},
&Groups{},
&Directories{},
&AccountStoreMappings{},
&ApplicationAccountStoreMappings{},
&OrganizationAccountStoreMappings{},
}
for _, resource := range resources {
c, ok := resource.(Cacheable)
Expand All @@ -136,7 +137,8 @@ func TestCacheableResources(t *testing.T) {
&Account{},
&Group{},
&Directory{},
&AccountStoreMapping{},
&ApplicationAccountStoreMapping{},
&OrganizationAccountStoreMapping{},
&Tenant{},
&CustomData{},
}
Expand Down
Loading

0 comments on commit 82b82e2

Please sign in to comment.