Przejdź do treści
DedicatedPHP Kontakt

Własność zasobów w SaaS: osoba, organizacja czy obszar roboczy

Określ, kto jest właścicielem każdego zasobu w Twoim SaaS, i nie myl użytkownika, który go utworzył, z osobą lub organizacją uprawnioną do zarządzania nim.

Schemat koncepcyjny zasobów powiązanych z użytkownikami, organizacjami i obszarami roboczymi w SaaS

W SaaS, w którym jedna osoba może pracować w wielu organizacjach lub obszarach roboczych, pytanie „kto utworzył ten zasób?” niekoniecznie odpowiada na pytanie „do kogo on należy?”. Ta różnica wpływa na to, kto może go wyświetlać, modyfikować, przekazywać lub zachować, gdy ktoś opuści zespół. Zbyt późne rozstrzygnięcie tej kwestii często prowadzi do rozproszonych reguł w zapytaniach, kontrolerach i zadaniach działających w tle.

Własność zasobów w SaaS dla wielu użytkowników to decyzja dotycząca domeny: określa, która encja pozostaje w głównej relacji z zasobem i jakie konsekwencje ma ta relacja. Nie jest synonimem uwierzytelniania, członkostwa ani uprawnień. Jawne zamodelowanie tej kwestii pozwala produktowi, danym i kodowi stosować spójną regułę.

Tożsamość, członkostwo i własność to różne relacje

Tożsamość, członkostwo i własność to różne relacje — guía visual de DedicatedPHP

Użytkownik reprezentuje tożsamość, która może się zalogować. Członkostwo oznacza, że ta tożsamość uczestniczy w organizacji lub obszarze roboczym, potencjalnie z określoną rolą lub statusem. Własność wskazuje, która encja odpowiada za zasób zgodnie z regułami produktu. Osoba może należeć do kilku obszarów, a jednocześnie utworzyć dokument należący do jednego z nich.

Warto osobno traktować także autorstwo. Pole created_by może zachowywać informację o tym, kto wykonał początkową czynność, ale nie powinno samo w sobie określać własności. Jeśli osoba, która utworzyła rekord, opuści organizację, zasób nadal może do niej należeć. I odwrotnie, osoba może nabyć zasób utworzony pierwotnie przez kogoś innego.

Warto udokumentować odpowiedzi na trzy pytania: kto jest właścicielem, kto może wykonywać operacje na zasobie i kto wykonał każdą istotną czynność. Jeśli jedno pole lub relacja ma odpowiadać na wszystkie te pytania, model prawdopodobnie miesza pojęcia.

Wybór między własnością osobistą, organizacyjną a współdzieloną

  • Osobista: zasób należy do użytkownika. Ma to sens, gdy jego cykl życia jest związany z tą osobą, a nie z zespołem, na przykład w przypadku prywatnych preferencji. Należy zdecydować, co stanie się po dezaktywacji lub usunięciu konta.
  • Organizacyjna: zasób należy do organizacji lub obszaru roboczego. To odpowiednie rozwiązanie, gdy zasób ma pozostać dostępny dla zespołu mimo zmian w jego składzie. Członkostwo użytkownika umożliwia dostęp, ale nie czyni go indywidualnym właścicielem.
  • Współdzielona: kilka encji może pozostawać w relacji własności lub odpowiedzialności. Stosuj ją tylko wtedy, gdy domena rzeczywiście wymaga współwłasności. Jeśli wymaganie polega na tym, by kilka osób mogło przeglądać lub edytować zasób, zwykle chodzi o dostęp oparty na członkostwie lub uprawnieniach, a nie o wielu właścicieli.

Decyzja powinna wynikać z cyklu życia zasobu i reguł biznesowych, a nie z chęci uproszczenia tabeli. Zastanów się, kto może zachować zasób, zdecydować o jego usunięciu i odpowiadać za niego po zmianie składu zespołu. Rozróżnij też „obszar roboczy” od „organizacji”: jeśli ten pierwszy jest rzeczywistą podjednostką z własnym cyklem życia i granicami, może być odpowiednim właścicielem; jeśli to tylko widok lub kontekst nawigacji, być może nie.

Reprezentowanie domeny bez domyślania się, kto jest właścicielem

W prostym modelu tabela zasobów może zawierać jawne wskazanie właściciela, na przykład owner_type i owner_id, albo osobne odwołania, takie jak user_id i organization_id. Pierwsze rozwiązanie może ułatwić obsługę wielu typów właścicieli, wymaga jednak walidowania odwołań i uwzględnienia ograniczeń integralności referencyjnej relacji polimorficznych. Osobne odwołania wyraźniej pokazują powiązania, ale wymagają uniemożliwienia nieprawidłowych kombinacji.

Inną możliwością jest wspólna encja, na przykład workspace, jeśli domena rzeczywiście reprezentuje w jej ramach zarówno konta osobiste, jak i zespoły. Nie wprowadzaj jej wyłącznie po to, by ukryć różnice: musi mieć określone znaczenie i stabilne reguły. W każdym projekcie ustal ograniczenia, które uniemożliwią powiązanie zasobu jednocześnie z niezgodnymi właścicielami albo z żadnym właścicielem, jeśli własność jest wymagana.

Modeluj członkostwa osobno, na przykład jako relację między użytkownikiem a organizacją, zawierającą status i rolę. Aktywny kontekst interfejsu może wskazywać, w którym miejscu osoba aktualnie pracuje, ale nie jest wystarczającym źródłem prawdy: należy go walidować przy każdej operacji. Właściciela nie należy też wyznaczać jako „osoby, która utworzyła zasób” ani jako „aktualnie wybranej organizacji”.

Stosowanie własności podczas odczytu, zapisu i procesów automatycznych

Zapytania powinny uwzględniać zakres własności i odpowiednią kontrolę dostępu. Nie wystarczy pobrać zasób po identyfikatorze i zaufać, że interfejs ukryje te, które nie pasują. W aplikacji PHP scentralizuj ustalanie kontekstu i reguły autoryzacji w warstwie wielokrotnego użytku, unikając powielania niekompletnych warunków w każdym kontrolerze.

Przy zapisie waliduj dozwolonego właściciela i aktualne członkostwo wykonującego operację. Sprawdź również, czy powiązane zasoby — na przykład folder docelowy — należą do zgodnego zakresu; w przeciwnym razie aktualizacja może utworzyć powiązania między różnymi zakresami. W przypadku operacji administracyjnych wyraźnie oddziel wyjątkową autoryzację od zwykłych reguł oraz rejestruj, kto ją wykonał i dlaczego.

Kolejki, zaplanowane polecenia, webhooki i importy nie zawsze mają interaktywnego użytkownika. Powinny przenosić zwalidowany identyfikator właściciela lub kontekstu zamiast polegać na domyślnej sesji. Proces musi stosować te same reguły zakresu co aplikacja internetowa. Jeśli działa z rozszerzonymi uprawnieniami, ogranicz je i poddaj audytowi.

Traktowanie przeniesienia własności jako operacji domenowej

Zmiana właściciela nie powinna być zwykłą edycją pola. Określ warunki wstępne: kto może rozpocząć przeniesienie, jaka relacja musi łączyć odbiorcę z obszarem oraz co zrobić w przypadku oczekującego zaproszenia lub nieaktywnego konta. Operacja powinna być atomowa, gdy aktualizuje wiele relacji i powiązanych efektów.

Określ również, co stanie się z zależnościami, takimi jak pliki, integracje, rozliczenia czy automatyzacje. Nie zakładaj, że wszystko musi zostać przeniesione razem z zasobem: ta polityka zależy od produktu. Jeśli nie da się wykonać wszystkich zmian w jednej transakcji, zaprojektuj proces, który można bezpiecznie wznowić lub odtworzyć, z jasno określonymi stanami i idempotencją przy ponawianiu prób.

Zachowuj dziennik audytowy obejmujący wykonawcę, poprzedniego właściciela, nowego właściciela, czas i — w stosownych przypadkach — powód. Dzięki temu można odróżnić osobę, która zezwoliła na zmianę, od tej, która wykonała czynność techniczną. Pierwotne autorstwo można zachować bez zmian, nawet jeśli własność ulegnie zmianie.

Testowanie granic ujawniających błędy modelu

Zautomatyzuj testy usług i integracyjne, aby weryfikować zarówno dozwolony, jak i zabroniony dostęp. Przydatna macierz obejmuje osobę należącą do dwóch organizacji, własne i cudze zasoby w obu z nich, zawieszone lub cofnięte członkostwa, przeniesienie do niedozwolonego celu oraz dostęp przy użyciu znanych identyfikatorów. Sprawdzaj odpowiedzi i skutki w danych; ukrycie przycisku nie jest testem autoryzacji.

Testuj również zasoby bez prawidłowego właściciela, zduplikowane relacje i błędy podczas przenoszenia własności. Jeśli schemat wymaga właściciela, ograniczenia bazy danych powinny potwierdzać to założenie, a migracje powinny wykrywać niespójne rekordy historyczne przed dodaniem ograniczeń do bazy danych. W przypadku zadań działających w tle sprawdź, czy kontekst zostaje zachowany i czy ponowienie próby nie powoduje zduplikowania zmian.

Lista kontrolna przed rozbudową SaaS

Lista kontrolna przed rozbudową SaaS — guía visual de DedicatedPHP
  • Czy określono, czy każdy typ zasobu należy do osoby, organizacji czy obszaru roboczego?
  • Czy własność jest odróżniana od autorstwa, członkostwa, roli i aktywnego kontekstu?
  • Czy zapytania odczytu i zapisu walidują właściciela oraz aktualne członkostwo?
  • Czy zadania automatyczne otrzymują jawny zakres i stosują równoważne zabezpieczenia?
  • Czy przeniesienie własności ma określone warunki wstępne i skutki, podlega audytowi oraz ma strategię odzyskiwania?
  • Czy istnieją testy dla użytkowników z wieloma obszarami, dezaktywacji lub usuwania kont, dostępu między zakresami i niespójnych danych?

Jeśli którakolwiek odpowiedź zależy od nieudokumentowanych konwencji, warto je wyjaśnić przed dodaniem kolejnych typów zasobów lub przepływów współpracy. Jawny model nie eliminuje wszystkich złożonych przypadków, ale uwidacznia decyzje i pozwala weryfikować je w schemacie, zapytaniach i testach.

Chcesz zastosować te pomysły w swoim projekcie?Omówmy Twoją platformę PHP.
Zobacz powiązaną usługę